Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-05-23 20:01:32 +04:00
91 changed files with 1903 additions and 1435 deletions
@@ -79,7 +79,7 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
return null;
}
if (parameters.getInvocationCount() <= 1 && JavaCompletionUtil.containsMethodCalls(expression)) {
if (parameters.getInvocationCount() <= 1 && JavaCompletionUtil.mayHaveSideEffects(expression)) {
final CompletionService service = CompletionService.getCompletionService();
if (service.getAdvertisementText() == null && parameters.getInvocationCount() < 2) {
service.setAdvertisementText("Invoke completion once more to see runtime type variants");
@@ -677,18 +677,19 @@ public class JavaCompletionUtil {
return ret;
}
@Nullable
static PsiElement getQualifier(final PsiElement element) {
return element instanceof PsiJavaCodeReferenceElement ? ((PsiJavaCodeReferenceElement)element).getQualifier() : null;
}
public static boolean containsMethodCalls(@Nullable final PsiElement qualifier) {
if (qualifier == null) return false;
if (qualifier instanceof PsiMethodCallExpression || qualifier instanceof PsiNewExpression) return true;
if (qualifier instanceof PsiArrayAccessExpression) {
return containsMethodCalls(((PsiArrayAccessExpression)qualifier).getArrayExpression());
public static boolean mayHaveSideEffects(@Nullable final PsiElement element) {
if (element == null) return false;
if (element instanceof PsiMethodCallExpression || element instanceof PsiNewExpression) return true;
if (element instanceof PsiTypeCastExpression) {
return mayHaveSideEffects(((PsiTypeCastExpression)element).getOperand());
}
return containsMethodCalls(getQualifier(qualifier));
if (element instanceof PsiArrayAccessExpression) {
return mayHaveSideEffects(((PsiArrayAccessExpression)element).getArrayExpression());
}
if (element instanceof PsiJavaCodeReferenceElement) {
return mayHaveSideEffects(((PsiJavaCodeReferenceElement)element).getQualifier());
}
return true;
}
public static void insertClassReference(@NotNull PsiClass psiClass, @NotNull PsiFile file, int offset) {
@@ -274,7 +274,9 @@ public class ReferenceExpressionCompletionContributor {
}
if (itemType == null) return;
final PsiElement qualifier = JavaCompletionUtil.getQualifier(reference.getElement());
final PsiElement element1 = reference.getElement();
final PsiElement qualifier =
element1 instanceof PsiJavaCodeReferenceElement ? ((PsiJavaCodeReferenceElement)element1).getQualifier() : null;
final PsiType expectedType = parameters.getExpectedType();
if (!OBJECT_METHOD_PATTERN.accepts(object) || allowGetClass(object, parameters)) {
if (parameters.getParameters().getInvocationCount() >= 3 || !itemType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
@@ -398,7 +400,7 @@ public class ReferenceExpressionCompletionContributor {
}
final String bracketSpace = getSpace(CodeStyleSettingsManager.getSettings(element.getProject()).SPACE_WITHIN_BRACKETS);
if (object instanceof PsiVariable && !JavaCompletionUtil.containsMethodCalls(qualifier)) {
if (object instanceof PsiVariable && !JavaCompletionUtil.mayHaveSideEffects(qualifier)) {
final PsiVariable variable = (PsiVariable)object;
addToArrayConversion(element, prefix,
"new " + componentType.getCanonicalText() +
@@ -1075,38 +1075,33 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
startElement(expression);
DfaValue dfaValue = myFactory.create(expression);
if (dfaValue != null) {
addInstruction(new PushInstruction(dfaValue, expression));
}
else {
PsiExpression condition = expression.getCondition();
PsiExpression condition = expression.getCondition();
PsiExpression thenExpression = expression.getThenExpression();
PsiExpression elseExpression = expression.getElseExpression();
PsiExpression thenExpression = expression.getThenExpression();
PsiExpression elseExpression = expression.getElseExpression();
final int elseOffset = elseExpression == null ? getEndOffset(expression) - 1 : getStartOffset(elseExpression);
if (thenExpression != null) {
condition.accept(this);
generateBoxingUnboxingInstructionFor(condition, PsiType.BOOLEAN);
PsiType type = expression.getType();
addInstruction(new ConditionalGotoInstruction(elseOffset, true, condition));
thenExpression.accept(this);
generateBoxingUnboxingInstructionFor(thenExpression,type);
final int elseOffset = elseExpression == null ? getEndOffset(expression) - 1 : getStartOffset(elseExpression);
if (thenExpression != null) {
condition.accept(this);
generateBoxingUnboxingInstructionFor(condition, PsiType.BOOLEAN);
PsiType type = expression.getType();
addInstruction(new ConditionalGotoInstruction(elseOffset, true, condition));
thenExpression.accept(this);
generateBoxingUnboxingInstructionFor(thenExpression,type);
addInstruction(new GotoInstruction(getEndOffset(expression)));
addInstruction(new GotoInstruction(getEndOffset(expression)));
if (elseExpression != null) {
elseExpression.accept(this);
generateBoxingUnboxingInstructionFor(elseExpression,type);
}
else {
pushUnknown();
}
if (elseExpression != null) {
elseExpression.accept(this);
generateBoxingUnboxingInstructionFor(elseExpression,type);
}
else {
pushUnknown();
}
}
else {
pushUnknown();
}
finishElement(expression);
}
@@ -125,13 +125,13 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
if (node == null) {
return true;
}
final IElementType type = node.getElementType();
if (type == JavaDocTokenType.DOC_TAG_VALUE_TOKEN) {
if (type == JavaDocElementType.DOC_TAG_VALUE_ELEMENT) {
return PsiTreeUtil.getParentOfType(parent, PsiDocMethodOrFieldRef.class) != null;
}
return type == JavaDocElementType.DOC_COMMENT || type == JavaDocElementType.DOC_TAG
|| type == JavaDocElementType.DOC_INLINE_TAG;
return type == JavaDocElementType.DOC_COMMENT || type == JavaDocElementType.DOC_TAG || type == JavaDocElementType.DOC_INLINE_TAG;
}
private void init(final ASTNode child) {
@@ -1096,9 +1096,8 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (myRole1 == ChildRole.OPERATION_SIGN) {
createSpaceInCode(mySettings.SPACE_AROUND_UNARY_OPERATOR);
}
else if (myChild1.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN
&& myChild2.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN)
{
else if ((myType1 == JavaDocTokenType.DOC_TAG_VALUE_TOKEN || myType1 == JavaDocElementType.DOC_TAG_VALUE_ELEMENT) &&
(myType2 == JavaDocTokenType.DOC_TAG_VALUE_TOKEN || myType2 == JavaDocElementType.DOC_TAG_VALUE_ELEMENT)) {
createSpaceInCode(true);
}
else if (myRole1 == ChildRole.COMMA) {
@@ -1516,7 +1515,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
@Override public void visitDocTag(PsiDocTag tag) {
if (myChild1.getElementType() == JavaDocTokenType.DOC_TAG_NAME && myChild2.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_TOKEN) {
if (myType1 == JavaDocTokenType.DOC_TAG_NAME && myType2 == JavaDocElementType.DOC_TAG_VALUE_ELEMENT) {
myResult = Spacing.createSpacing(1, 1, 0, false, 0);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -22,10 +22,9 @@ import com.intellij.psi.tree.IElementType;
* @author max
*/
public class JavaASTFactory extends CoreJavaASTFactory {
@Override
public CompositeElement createComposite(final IElementType type) {
if (type == DOC_TAG_VALUE_TOKEN) {
if (type == DOC_TAG_VALUE_ELEMENT) {
return new PsiDocTagValueImpl();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -147,7 +147,7 @@ public class JavadocParser {
final PsiBuilder.Marker tagValue = builder.mark();
builder.remapCurrentToken(JavaDocElementType.DOC_REFERENCE_HOLDER);
builder.advanceLexer();
tagValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
tagValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT);
}
else if (!isInline && tagName != null && tagName.equals(PARAM_TAG)) {
parseSimpleTagValue(builder, true);
@@ -187,7 +187,7 @@ public class JavadocParser {
else {
final PsiBuilder.Marker tagValue = builder.mark();
builder.advanceLexer();
tagValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
tagValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT);
}
}
@@ -217,7 +217,7 @@ public class JavadocParser {
}
}
else if (tokenType == JavaDocTokenType.DOC_TAG_VALUE_RPAREN) {
subValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
subValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT);
builder.advanceLexer();
refStart.done(JavaDocElementType.DOC_METHOD_OR_FIELD_REF);
return;
@@ -227,7 +227,7 @@ public class JavadocParser {
}
}
subValue.done(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
subValue.done(JavaDocElementType.DOC_TAG_VALUE_ELEMENT);
}
refStart.done(JavaDocElementType.DOC_METHOD_OR_FIELD_REF);
@@ -238,7 +238,7 @@ public class JavadocParser {
while (TAG_VALUES_SET.contains(getTokenType(builder))) {
builder.advanceLexer();
}
tagValue.done(parameter ? JavaDocElementType.DOC_PARAMETER_REF : JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
tagValue.done(parameter ? JavaDocElementType.DOC_PARAMETER_REF : JavaDocElementType.DOC_TAG_VALUE_ELEMENT);
}
@Nullable
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -99,7 +99,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
i == JavaElementType.THIS_EXPRESSION ||
i == JavaElementType.SUPER_EXPRESSION ||
i == JavaDocElementType.DOC_METHOD_OR_FIELD_REF ||
i == JavaDocTokenType.DOC_TAG_VALUE_TOKEN ||
i == JavaDocElementType.DOC_TAG_VALUE_ELEMENT ||
i == JavaElementType.REFERENCE_PARAMETER_LIST ||
i == JavaElementType.ANNOTATION) {
if (isQualified()) {
@@ -21,6 +21,7 @@ import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.javadoc.PsiDocTagValue;
import org.jetbrains.annotations.NotNull;
@@ -29,7 +30,7 @@ import org.jetbrains.annotations.NotNull;
*/
public class CorePsiDocTagValueImpl extends CompositePsiElement implements PsiDocTagValue {
public CorePsiDocTagValueImpl() {
super(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
super(JavaDocElementType.DOC_TAG_VALUE_ELEMENT);
}
@Override
@@ -47,6 +48,7 @@ public class CorePsiDocTagValueImpl extends CompositePsiElement implements PsiDo
if (child.getElementType() == JavaDocTokenType.DOC_TAG_VALUE_COMMA) {
return ChildRole.COMMA;
}
return super.getChildRole(child);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -18,11 +18,7 @@ package com.intellij.psi.impl.source.javadoc;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.SharedImplUtil;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
@@ -43,9 +39,8 @@ import java.util.Set;
* @author mike
*/
public class PsiDocParamRef extends CompositePsiElement implements PsiDocTagValue {
public PsiDocParamRef() {
super(Constants.DOC_PARAMETER_REF);
super(JavaDocElementType.DOC_PARAMETER_REF);
}
@Override
@@ -16,13 +16,9 @@
package com.intellij.psi.impl.source.javadoc;
import com.intellij.lang.ASTNode;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiReference;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
@@ -37,9 +33,10 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Constants {
private static final TokenSet VALUE_BIT_SET = TokenSet.create(
JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF,
DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER);
private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create(
DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF);
private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create(
DOC_TAG_VALUE_TOKEN, JAVA_CODE_REFERENCE, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER));
public PsiDocTagImpl() {
super(DOC_TAG);
@@ -47,17 +44,17 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con
@Override
public PsiDocComment getContainingComment() {
return (PsiDocComment)SourceTreeToPsiMap.treeElementToPsi(getTreeParent());
return (PsiDocComment)getParent();
}
@Override
public PsiElement getNameElement() {
return findChildByRoleAsPsiElement(ChildRole.DOC_TAG_NAME);
return findPsiChildByType(DOC_TAG_NAME);
}
@Override
public PsiDocTagValue getValueElement() {
return (PsiDocTagValue)findChildByRoleAsPsiElement(ChildRole.DOC_TAG_VALUE);
return (PsiDocTagValue)findPsiChildByType(TAG_VALUE_BIT_SET);
}
@Override
@@ -65,6 +62,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con
return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElement.ARRAY_FACTORY);
}
@NotNull
@Override
public String getName() {
if (getNameElement() == null) return "";
@@ -79,7 +77,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con
@Override
public int getChildRole(ASTNode child) {
assert (child.getTreeParent() == this);
assert child.getTreeParent() == this : child.getTreeParent();
IElementType i = child.getElementType();
if (i == DOC_TAG_NAME) {
return ChildRole.DOC_TAG_NAME;
@@ -90,10 +88,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con
else if (i == DOC_COMMENT_LEADING_ASTERISKS) {
return ChildRole.DOC_COMMENT_ASTERISKS;
}
else if (i == DOC_TAG_VALUE_TOKEN) {
return ChildRole.DOC_TAG_VALUE;
}
else if (i == DOC_METHOD_OR_FIELD_REF || i == DOC_PARAMETER_REF) {
else if (TAG_VALUE_BIT_SET.contains(i)) {
return ChildRole.DOC_TAG_VALUE;
}
else {
@@ -104,7 +99,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con
@Override
@NotNull
public PsiReference[] getReferences() {
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiDocTag.class);
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
}
@Override
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.source.tree.java;
package com.intellij.psi.impl.source.javadoc;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
@@ -36,11 +35,10 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlineDocTag, Constants {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiInlineDocTagImpl");
private static final TokenSet VALUE_BIT_SET = TokenSet.create(
JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_METHOD_OR_FIELD_REF, DOC_COMMENT_DATA, DOC_INLINE_TAG,
DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER);
private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create(
DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF);
private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create(
JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER));
public PsiInlineDocTagImpl() {
super(DOC_INLINE_TAG);
@@ -57,7 +55,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin
@Override
public PsiElement getNameElement() {
return findChildByRoleAsPsiElement(ChildRole.DOC_TAG_NAME);
return findPsiChildByType(DOC_TAG_NAME);
}
@Override
@@ -67,7 +65,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin
@Override
public PsiDocTagValue getValueElement() {
return (PsiDocTagValue)findChildByRoleAsPsiElement(ChildRole.DOC_TAG_VALUE);
return (PsiDocTagValue)findPsiChildByType(TAG_VALUE_BIT_SET);
}
@Override
@@ -79,7 +77,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin
@Override
public int getChildRole(ASTNode child) {
LOG.assertTrue(child.getTreeParent() == this);
assert child.getTreeParent() == this : child.getTreeParent();
IElementType i = child.getElementType();
if (i == DOC_TAG_NAME) {
return ChildRole.DOC_TAG_NAME;
@@ -93,10 +91,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin
else if (i == DOC_INLINE_TAG_END) {
return ChildRole.DOC_INLINE_TAG_END;
}
else if (i == DOC_TAG_VALUE_TOKEN) {
return ChildRole.DOC_TAG_VALUE;
}
else if (i == DOC_METHOD_OR_FIELD_REF) {
else if (TAG_VALUE_BIT_SET.contains(i)) {
return ChildRole.DOC_TAG_VALUE;
}
else {
@@ -124,4 +119,4 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin
PsiImplUtil.setName(getNameElement(), name);
return this;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -49,6 +49,7 @@ public class CoreJavaASTFactory extends ASTFactory implements Constants {
return new PsiJavaTokenImpl(type, text);
}
else if (type instanceof IJavaDocElementType) {
assert type != DOC_TAG_VALUE_ELEMENT;
return new PsiDocTokenImpl(type, text);
}
@@ -57,7 +58,7 @@ public class CoreJavaASTFactory extends ASTFactory implements Constants {
@Override
public CompositeElement createComposite(IElementType type) {
if (type == DOC_TAG_VALUE_TOKEN) {
if (type == DOC_TAG_VALUE_ELEMENT) {
return new CorePsiDocTagValueImpl();
}
return null;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -29,7 +29,7 @@ import com.intellij.psi.impl.source.javadoc.PsiDocCommentImpl;
import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
import com.intellij.psi.impl.source.javadoc.PsiDocTagImpl;
import com.intellij.psi.impl.source.tree.java.PsiInlineDocTagImpl;
import com.intellij.psi.impl.source.javadoc.PsiInlineDocTagImpl;
import com.intellij.psi.tree.*;
import com.intellij.psi.tree.java.IJavaDocElementType;
import com.intellij.util.ReflectionUtil;
@@ -70,6 +70,7 @@ public interface JavaDocElementType {
IElementType DOC_INLINE_TAG = new JavaDocCompositeElementType("DOC_INLINE_TAG", PsiInlineDocTagImpl.class);
IElementType DOC_METHOD_OR_FIELD_REF = new JavaDocCompositeElementType("DOC_METHOD_OR_FIELD_REF", PsiDocMethodOrFieldRef.class);
IElementType DOC_PARAMETER_REF = new JavaDocCompositeElementType("DOC_PARAMETER_REF", PsiDocParamRef.class);
IElementType DOC_TAG_VALUE_ELEMENT = new IJavaDocElementType("DOC_TAG_VALUE_ELEMENT");
ILazyParseableElementType DOC_REFERENCE_HOLDER = new JavaDocLazyElementType("DOC_REFERENCE_HOLDER") {
private final JavaParserUtil.ParserWrapper myParser = new JavaParserUtil.ParserWrapper() {
@@ -135,6 +136,6 @@ public interface JavaDocElementType {
};
TokenSet ALL_JAVADOC_ELEMENTS = TokenSet.create(
DOC_TAG, DOC_INLINE_TAG, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF, DOC_REFERENCE_HOLDER, DOC_TYPE_HOLDER, DOC_COMMENT
);
DOC_TAG, DOC_INLINE_TAG, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF, DOC_TAG_VALUE_ELEMENT,
DOC_REFERENCE_HOLDER, DOC_TYPE_HOLDER, DOC_COMMENT);
}
@@ -0,0 +1,12 @@
class Foo {
public void foo() {
final boolean flag = true;
bar(<warning descr="Condition 'flag' is always 'true'">flag</warning> ? "a" : "b",
<warning descr="Condition 'flag' is always 'true'">flag</warning> ? new String[]{"aa"} : new String[]{"bb"}
);
}
void bar(String b, String[] a) {
}
}
@@ -25,7 +25,7 @@ PsiJavaFile:Exception0.java
PsiDocTag:@throws
PsiDocToken:DOC_TAG_NAME('@throws')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_REFERENCE_HOLDER)
PsiJavaCodeReferenceElement:java.lang.Exception
PsiJavaCodeReferenceElement:java.lang
@@ -15,7 +15,7 @@ PsiJavaFile:InlineTag1.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('somefunc')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:String
PsiJavaCodeReferenceElement:String
@@ -15,7 +15,7 @@ PsiJavaFile:InlineTag2.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('somefunc')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:String
PsiJavaCodeReferenceElement:String
@@ -15,7 +15,7 @@ PsiJavaFile:InlineTag3.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('somefunc')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:String
PsiJavaCodeReferenceElement:String
@@ -30,7 +30,7 @@ PsiJavaFile:LinkPlainTag1.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('equals')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:java.lang.Object
PsiJavaCodeReferenceElement:java.lang.Object
@@ -10,7 +10,7 @@ PsiJavaFile:LinkPlainTag2.java
PsiDocTag:@linkplain
PsiDocToken:DOC_TAG_NAME('@linkplain')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiDocToken:DOC_TAG_VALUE_TOKEN('java.lang.String')
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('equals')
@@ -30,7 +30,7 @@ PsiJavaFile:LinkTag1.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('equals')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:java.lang.Object
PsiJavaCodeReferenceElement:java.lang.Object
@@ -10,7 +10,7 @@ PsiJavaFile:LinkTag2.java
PsiDocTag:@link
PsiDocToken:DOC_TAG_NAME('@link')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiDocToken:DOC_TAG_VALUE_TOKEN('java.lang.String')
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('equals')
@@ -17,7 +17,7 @@ PsiJavaFile:LinkTag3.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('foo')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
<empty list>
PsiDocToken:DOC_TAG_VALUE_RPAREN(')')
PsiDocToken:DOC_INLINE_TAG_END('}')
@@ -16,7 +16,7 @@ PsiJavaFile:LinkTag4.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('foo')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
<empty list>
PsiDocToken:DOC_TAG_VALUE_RPAREN(')')
PsiDocToken:DOC_INLINE_TAG_END('}')
@@ -15,7 +15,7 @@ PsiJavaFile:LinkTag5.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('foo')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
<empty list>
PsiDocToken:DOC_TAG_VALUE_RPAREN(')')
PsiDocToken:DOC_INLINE_TAG_END('}')
@@ -15,7 +15,7 @@ PsiJavaFile:LinkTag6.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('foo')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
<empty list>
PsiDocToken:DOC_TAG_VALUE_RPAREN(')')
PsiDocToken:DOC_INLINE_TAG_END('}')
@@ -29,7 +29,7 @@ PsiJavaFile:SeeTag10.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('equals')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:java.lang.Object
PsiJavaCodeReferenceElement:java.lang.Object
@@ -29,7 +29,7 @@ PsiJavaFile:SeeTag11.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('wait')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
<empty list>
PsiDocToken:DOC_TAG_VALUE_RPAREN(')')
PsiWhiteSpace('\n ')
@@ -14,7 +14,7 @@ PsiJavaFile:SeeTag12.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('wait')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
<empty list>
PsiDocToken:DOC_TAG_VALUE_RPAREN(')')
PsiWhiteSpace('\n ')
@@ -29,7 +29,7 @@ PsiJavaFile:SeeTag14.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('append')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:char[]
PsiTypeElement:char
@@ -29,7 +29,7 @@ PsiJavaFile:SeeTag15.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('append')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:java.lang.Object
PsiJavaCodeReferenceElement:java.lang.Object
@@ -19,7 +19,7 @@ PsiJavaFile:SeeTag16.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('equals')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:int
PsiKeyword:int('int')
@@ -19,7 +19,7 @@ PsiJavaFile:SeeTag3.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('equals')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:Object
PsiJavaCodeReferenceElement:Object
@@ -29,7 +29,7 @@ PsiJavaFile:SeeTag5.java
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('wait')
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_TYPE_HOLDER)
PsiTypeElement:long
PsiKeyword:long('long')
@@ -15,16 +15,16 @@ PsiJavaFile:SeeTag9.java
PsiIdentifier:equals('equals')
PsiReferenceParameterList
<empty list>
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiDocToken:DOC_TAG_VALUE_LPAREN('(')
PsiElement(DOC_REFERENCE_HOLDER)
PsiKeyword:long('long')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiDocToken:DOC_TAG_VALUE_COMMA(',')
PsiWhiteSpace(' ')
PsiElement(DOC_REFERENCE_HOLDER)
PsiKeyword:long('long')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiDocToken:DOC_TAG_VALUE_RPAREN(')')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
@@ -23,7 +23,7 @@ PsiJavaFile:Tag2.java
PsiDocTag:@return
PsiDocToken:DOC_TAG_NAME('@return')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiDocToken:DOC_TAG_VALUE_TOKEN('value')
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('value')
@@ -10,7 +10,7 @@ PsiJavaFile:Tag5.java
PsiDocTag:@ejb:bean
PsiDocToken:DOC_TAG_NAME('@ejb:bean')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_TOKEN)
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiDocToken:DOC_TAG_VALUE_TOKEN('this')
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('is an EJB ')
@@ -62,5 +62,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
public void testIDEA84489() throws Throwable { doTest(); }
public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }
}
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2012 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.psi.formatter.java;
import com.intellij.openapi.application.ApplicationManager;
@@ -529,12 +544,12 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest {
public void testJavaDocLinksWithParameterNames() throws Exception {
// See IDEADEV-8332
doTextTest("/**\n" +
"* @return if ( x1 == x1 ) then retrun {@link #cmp(String y1,int y2)}\n" +
"* @return if ( x1 == x1 ) then return {@link #cmp(String y1,int y2)}\n" +
"* otherwise return {@link #cmp(int x1,int x2)}\n" +
"*/\n" +
"class X {\n" +
"}\n", "/**\n" +
" * @return if ( x1 == x1 ) then retrun {@link #cmp(String y1, int y2)}\n" +
" * @return if ( x1 == x1 ) then return {@link #cmp(String y1, int y2)}\n" +
" * otherwise return {@link #cmp(int x1, int x2)}\n" +
" */\n" +
"class X {\n" +
File diff suppressed because it is too large Load Diff
@@ -334,15 +334,17 @@ public class IdeaProjectLoader {
def componentTag = getComponent(root, "Encoding");
if (componentTag == null) return;
componentTag.file?.each {Node fileNode ->
def url = fileNode."@url";
def charset = fileNode."@charset";
String url = fileNode."@url";
String charset = fileNode."@charset";
if ("PROJECT".equals(url)) {
project.projectCharset = charset;
}
else {
def path = projectMacroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(url));
project.filePathToCharset[path] = charset;
if (!StringUtil.isEmptyOrSpaces(charset)) {
if ("PROJECT".equals(url)) {
project.projectCharset = charset;
}
else {
def path = projectMacroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(url));
project.filePathToCharset[FileUtil.toCanonicalPath(path)] = charset;
}
}
}
}
@@ -632,6 +634,12 @@ public class IdeaProjectLoader {
case "JDK_1_5": return "1.5"
case "JDK_1_6": return "1.6"
case "JDK_1_7": return "1.7"
case "JDK_1_8": return "1.8"
}
final String prefix = "JDK_";
if (imlPropertyText != null && imlPropertyText.startsWith(prefix)) {
return imlPropertyText.substring(prefix.length()).replace('_', '.');
}
return "1.6"
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import org.jetbrains.annotations.NotNull;
@@ -38,7 +39,7 @@ public class PrefixMatchingWeigher extends CompletionWeigher {
final NameUtil.MatchingCaseSensitivity sensitivity =
setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE :
setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL;
final NameUtil.MinusculeMatcher matcher = new NameUtil.MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity);
final MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity);
int max = Integer.MIN_VALUE;
for (String lookupString : item.getAllLookupStrings()) {
@@ -32,6 +32,7 @@ public class IntentionActionWrapper implements IntentionAction {
private IntentionAction myDelegate;
private final String[] myCategories;
private final IntentionActionBean myExtension;
private String myFullFamilyName;
public IntentionActionWrapper(final IntentionActionBean extension, String[] categories) {
myExtension = extension;
@@ -60,13 +61,13 @@ public class IntentionActionWrapper implements IntentionAction {
return getDelegate().startInWriteAction();
}
@NotNull
public String getFullFamilyName(){
if (myCategories != null) {
return StringUtil.join(myCategories, "/") + "/" + getFamilyName();
}
else {
return getFamilyName();
String result = myFullFamilyName;
if (result == null) {
myFullFamilyName = result = myCategories != null ? StringUtil.join(myCategories, "/") + "/" + getFamilyName() : getFamilyName();
}
return result;
}
public synchronized IntentionAction getDelegate() {
@@ -24,6 +24,7 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.ui.*;
import com.intellij.ui.speedSearch.SpeedSearchUtil;
@@ -255,7 +256,7 @@ public class LookupCellRenderer implements ListCellRenderer {
final String prefix = myLookup.itemPattern(item);
if (prefix.length() > 0) {
Iterable<TextRange> ranges = new NameUtil.MinusculeMatcher("*" + prefix, NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(name);
Iterable<TextRange> ranges = new MinusculeMatcher("*" + prefix, NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(name);
if (ranges != null) {
SimpleTextAttributes highlighted =
new SimpleTextAttributes(style, selected ? SELECTED_PREFIX_FOREGROUND_COLOR : PREFIX_FOREGROUND_COLOR);
@@ -46,6 +46,7 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.statistics.StatisticsInfo;
import com.intellij.psi.statistics.StatisticsManager;
@@ -1020,7 +1021,8 @@ public abstract class ChooseByNameBase {
String text = EXTRA_ELEM.equals(modelElement) ? null : myModel.getFullName(modelElement);
if (text != null) {
String shortName = myModel.getElementName(modelElement);
int match = shortName != null && matcher instanceof NameUtil.MinusculeMatcher ? ((NameUtil.MinusculeMatcher)matcher).matchingDegree(shortName) : Integer.MIN_VALUE;
int match = shortName != null && matcher instanceof MinusculeMatcher
? ((MinusculeMatcher)matcher).matchingDegree(shortName) : Integer.MIN_VALUE;
int stats = StatisticsManager.getInstance().getUseCount(new StatisticsInfo(statContext, text));
if (stats > best || stats == best && match > bestMatch) {
best = stats;
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.util.proximity.PsiProximityComparator;
import com.intellij.util.Function;
@@ -147,10 +148,10 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider
if (name == null) return false;
final List<String> suspects = split(name, base);
final List<Pair<String, NameUtil.MinusculeMatcher>> patternsAndMatchers =
ContainerUtil.map2List(split(qualifierPattern, base), new Function<String, Pair<String, NameUtil.MinusculeMatcher>>() {
final List<Pair<String, MinusculeMatcher>> patternsAndMatchers =
ContainerUtil.map2List(split(qualifierPattern, base), new Function<String, Pair<String, MinusculeMatcher>>() {
@Override
public Pair<String, NameUtil.MinusculeMatcher> fun(String s) {
public Pair<String, MinusculeMatcher> fun(String s) {
return Pair.create(getNamePattern(base, s), buildPatternMatcher(getNamePattern(base, s)));
}
});
@@ -159,9 +160,9 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider
try {
patterns:
for (Pair<String, NameUtil.MinusculeMatcher> patternAndMatcher : patternsAndMatchers) {
for (Pair<String, MinusculeMatcher> patternAndMatcher : patternsAndMatchers) {
final String pattern = patternAndMatcher.first;
final NameUtil.MinusculeMatcher matcher = patternAndMatcher.second;
final MinusculeMatcher matcher = patternAndMatcher.second;
if (!pattern.isEmpty()) {
for (int j = matchPosition; j < suspects.size() - 1; j++) {
String suspect = suspects.get(j);
@@ -204,7 +205,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider
pattern = pattern.substring(1);
}
final NameUtil.MinusculeMatcher matcher = buildPatternMatcher(pattern);
final MinusculeMatcher matcher = buildPatternMatcher(pattern);
try {
for (String name : names) {
@@ -221,7 +222,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider
}
}
private static boolean matches(ChooseByNameBase base, String pattern, NameUtil.MinusculeMatcher matcher, String name) {
private static boolean matches(ChooseByNameBase base, String pattern, MinusculeMatcher matcher, String name) {
boolean matches = false;
if (name != null) {
if (base.getModel() instanceof CustomMatcherModel) {
@@ -236,7 +237,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider
return matches;
}
private static NameUtil.MinusculeMatcher buildPatternMatcher(String pattern) {
private static MinusculeMatcher buildPatternMatcher(String pattern) {
return NameUtil.buildMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE);
}
@@ -29,7 +29,55 @@ import java.awt.*;
public class AttributesFlyweight {
private final int myHashCode;
private static final StripedLockConcurrentHashMap<AttributesFlyweight, AttributesFlyweight> entries = new StripedLockConcurrentHashMap<AttributesFlyweight, AttributesFlyweight>();
private static final StripedLockConcurrentHashMap<FlyweightKey, AttributesFlyweight> entries = new StripedLockConcurrentHashMap<FlyweightKey, AttributesFlyweight>();
private static final ThreadLocal<FlyweightKey> ourKey = new ThreadLocal<FlyweightKey>();
private static class FlyweightKey implements Cloneable {
Color foreground;
Color background;
@JdkConstants.FontStyle int fontType;
Color effectColor;
EffectType effectType;
Color errorStripeColor;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof FlyweightKey)) return false;
FlyweightKey key = (FlyweightKey)o;
if (fontType != key.fontType) return false;
if (background != null ? !background.equals(key.background) : key.background != null) return false;
if (effectColor != null ? !effectColor.equals(key.effectColor) : key.effectColor != null) return false;
if (effectType != key.effectType) return false;
if (errorStripeColor != null ? !errorStripeColor.equals(key.errorStripeColor) : key.errorStripeColor != null) return false;
if (foreground != null ? !foreground.equals(key.foreground) : key.foreground != null) return false;
return true;
}
@Override
public int hashCode() {
int result = foreground != null ? foreground.hashCode() : 0;
result = 31 * result + (background != null ? background.hashCode() : 0);
result = 31 * result + fontType;
result = 31 * result + (effectColor != null ? effectColor.hashCode() : 0);
result = 31 * result + (effectType != null ? effectType.hashCode() : 0);
result = 31 * result + (errorStripeColor != null ? errorStripeColor.hashCode() : 0);
return result;
}
@Override
protected FlyweightKey clone() {
try {
return (FlyweightKey)super.clone();
}
catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
@NotNull
public static AttributesFlyweight create(Color foreground,
@@ -38,8 +86,23 @@ public class AttributesFlyweight {
Color effectColor,
EffectType effectType,
Color errorStripeColor) {
AttributesFlyweight key = new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor);
return ConcurrencyUtil.cacheOrGet(entries, key, key);
FlyweightKey key = ourKey.get();
if (key == null) {
ourKey.set(key = new FlyweightKey());
}
key.foreground = foreground;
key.background = background;
key.fontType = fontType;
key.effectColor = effectColor;
key.effectType = effectType;
key.errorStripeColor = errorStripeColor;
AttributesFlyweight flyweight = entries.get(key);
if (flyweight != null) {
return flyweight;
}
return ConcurrencyUtil.cacheOrGet(entries, key.clone(), new AttributesFlyweight(foreground, background, fontType, effectColor, effectType, errorStripeColor));
}
private final Color myForeground;
@@ -716,7 +716,7 @@ public class Messages {
}
/**
* Shows dialog with given message and title, infomation icon {@link #getInformationIcon()} and OK button
* Shows dialog with given message and title, information icon {@link #getInformationIcon()} and OK button
*/
public static void showInfoMessage(Component component, String message, String title) {
if (canShowMacSheetPanel()) {
@@ -728,7 +728,7 @@ public class Messages {
}
/**
* Shows dialog with given message and title, infomation icon {@link #getInformationIcon()} and OK button
* Shows dialog with given message and title, information icon {@link #getInformationIcon()} and OK button
*/
public static void showInfoMessage(Project project, @Nls String message, @Nls String title) {
if (canShowMacSheetPanel()) {
@@ -740,7 +740,7 @@ public class Messages {
}
/**
* Shows dialog with given message and title, infomation icon {@link #getInformationIcon()} and OK button
* Shows dialog with given message and title, information icon {@link #getInformationIcon()} and OK button
*/
public static void showInfoMessage(String message, String title) {
if (canShowMacSheetPanel()) {
@@ -18,7 +18,7 @@ package com.intellij.ui.speedSearch;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.Processor;
@@ -65,12 +65,12 @@ public final class SpeedSearchUtil {
final Matcher matcher,
final Color selectedBg,
final boolean selected) {
if (!(matcher instanceof NameUtil.MinusculeMatcher) || (Registry.is("ide.highlight.match.in.selected.only") && !selected)) {
if (!(matcher instanceof MinusculeMatcher) || (Registry.is("ide.highlight.match.in.selected.only") && !selected)) {
component.append(text, attributes);
return;
}
final Iterable<TextRange> iterable = ((NameUtil.MinusculeMatcher)matcher).matchingFragments(text);
final Iterable<TextRange> iterable = ((MinusculeMatcher)matcher).matchingFragments(text);
if (iterable != null) {
final Color fg = attributes.getFgColor();
final int style = attributes.getStyle();
@@ -93,6 +93,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
private final DefaultActionGroup mySecondaryActions = new DefaultActionGroup();
private boolean myMinimalMode;
private boolean myForceUseMacEnhancements;
public ActionButton getSecondaryActionsButton() {
return mySecondaryActionsButton;
@@ -164,7 +165,11 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
}
private boolean doMacEnhancementsForMainToolbar() {
return (UIUtil.isUnderAquaLookAndFeel() && ActionPlaces.MAIN_TOOLBAR.equals(myPlace));
return (UIUtil.isUnderAquaLookAndFeel() && (ActionPlaces.MAIN_TOOLBAR.equals(myPlace) || myForceUseMacEnhancements));
}
public void setForceUseMacEnhancements(boolean useMacEnhancements) {
myForceUseMacEnhancements = useMacEnhancements;
}
private boolean isInsideNavBar() {
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import org.jetbrains.annotations.Nullable;
@@ -24,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
* @author Konstantin Bulenkov
*/
public class SpeedSearchComparator {
private NameUtil.MinusculeMatcher myMinusculeMatcher;
private MinusculeMatcher myMinusculeMatcher;
private String myRecentSearchText;
private boolean myShouldMatchFromTheBeginning;
private boolean myShouldMatchCamelCase;
@@ -52,7 +53,7 @@ public class SpeedSearchComparator {
if (!myShouldMatchFromTheBeginning && !pattern.startsWith("*")) {
pattern = "*" + pattern;
}
myMinusculeMatcher = new NameUtil.MinusculeMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE);
myMinusculeMatcher = new MinusculeMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE);
}
return myMinusculeMatcher.matchingFragments(text);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -72,7 +72,7 @@ public class FileListeningTest extends IntegrationTestCase {
LocalFileSystem.getInstance().refresh(false);
List<Change> changes = getVcs().getChangeListInTests().getChangesInTests().get(0).getChanges();
assertEquals(4, changes.size());
assertEquals(changes.toString(), 4, changes.size());
List<String> actual = new SmartList<String>();
for (Change each : changes) {
actual.add(((StructuralChange)each).getPath());
@@ -100,7 +100,7 @@ public class FileListeningTest extends IntegrationTestCase {
VirtualFile f = createFile("file.txt");
assertEquals(2, getRevisionsFor(f).size());
f.rename(null, "file2.txt");
f.rename(this, "file2.txt");
assertEquals(3, getRevisionsFor(f).size());
}
@@ -125,7 +125,7 @@ public class FileListeningTest extends IntegrationTestCase {
addFileListenerDuring(l, new RunnableAdapter() {
@Override
public void doRun() throws IOException {
f.rename(null, "new.txt");
f.rename(this, "new.txt");
}
});
@@ -139,7 +139,7 @@ public class FileListeningTest extends IntegrationTestCase {
VirtualFile f = createFile("file.hprof");
assertEquals(before, getRevisionsFor(myRoot).size());
f.rename(null, "file.txt");
f.rename(this, "file.txt");
assertEquals(before + 1, getRevisionsFor(myRoot).size());
assertEquals(2, getRevisionsFor(f).size());
@@ -151,7 +151,7 @@ public class FileListeningTest extends IntegrationTestCase {
VirtualFile f = createFile("file.txt");
assertEquals(before + 1, getRevisionsFor(myRoot).size());
f.rename(null, "file.hprof");
f.rename(this, "file.hprof");
assertEquals(before + 2, getRevisionsFor(myRoot).size());
}
@@ -161,7 +161,7 @@ public class FileListeningTest extends IntegrationTestCase {
VirtualFile f = createFile(FILTERED_DIR_NAME);
assertEquals(before, getRevisionsFor(myRoot).size());
f.rename(null, "not_filtered");
f.rename(this, "not_filtered");
assertEquals(before + 1, getRevisionsFor(myRoot).size());
assertEquals(2, getRevisionsFor(f).size());
@@ -173,7 +173,7 @@ public class FileListeningTest extends IntegrationTestCase {
VirtualFile f = createDirectory("not_filtered");
assertEquals(before + 1, getRevisionsFor(myRoot).size());
f.rename(null, FILTERED_DIR_NAME);
f.rename(this, FILTERED_DIR_NAME);
assertEquals(before + 2, getRevisionsFor(myRoot).size());
}
@@ -188,7 +188,7 @@ public class FileListeningTest extends IntegrationTestCase {
assertEquals(4, getRevisionsFor(f).size());
}
public void testIgnoringROStstusChangeForUnversionedFiles() throws Exception {
public void testIgnoringROStatusChangeForUnversionedFiles() throws Exception {
int before = getRevisionsFor(myRoot).size();
VirtualFile f = createFile("f.hprof");
@@ -202,7 +202,7 @@ public class FileListeningTest extends IntegrationTestCase {
int before = getRevisionsFor(myRoot).size();
f.delete(null);
f.delete(this);
assertEquals(before + 1, getRevisionsFor(myRoot).size());
}
@@ -210,24 +210,26 @@ public class FileListeningTest extends IntegrationTestCase {
int before = getRevisionsFor(myRoot).size();
VirtualFile f = createDirectory(FILTERED_DIR_NAME);
f.delete(null);
f.delete(this);
assertEquals(before, getRevisionsFor(myRoot).size());
}
public void testDeletionDoesNotVersionIgnoredFilesRecursively() throws Exception {
String dir1 = createDirectoryExternally("dir");
String f1 = createFileExternally("dir/f.txt");
createFileExternally("dir/f.txt");
createFileExternally("dir/f.class");
createFileExternally("dir/subdir/f.txt");
String dir2 = createDirectoryExternally("dir/subdir/subdir2");
String f2 = createFileExternally("dir/subdir/subdir2/f.txt");
createDirectoryExternally("dir/subdir/subdir2");
createFileExternally("dir/subdir/subdir2/f.txt");
LocalFileSystem.getInstance().refresh(false);
addExcludedDir(myRoot.getPath() + "/dir/subdir");
addContentRoot(myRoot.getPath() + "/dir/subdir/subdir2");
LocalFileSystem.getInstance().findFileByPath(dir1).delete(this);
final VirtualFile vDir1 = LocalFileSystem.getInstance().findFileByPath(dir1);
assertNotNull(dir1, vDir1);
vDir1.delete(this);
List<Change> changes = getVcs().getChangeListInTests().getChangesInTests().get(0).getChanges();
assertEquals(1, changes.size());
@@ -20,6 +20,7 @@
package com.intellij.psi.util;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.codeStyle.MinusculeMatcher;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.UsefulTestCase;
@@ -312,57 +313,57 @@ public class NameUtilTest extends UsefulTestCase {
}
public void testMinusculeFirstLetter() {
assertTrue(new NameUtil.MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic"));
assertFalse(new NameUtil.MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic"));
assertTrue(new NameUtil.MinusculeMatcher("cL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("class"));
assertTrue(new NameUtil.MinusculeMatcher("CL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("Class"));
assertFalse(new NameUtil.MinusculeMatcher("abc", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("_abc"));
assertTrue(new MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic"));
assertFalse(new MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("WebLogic"));
assertTrue(new MinusculeMatcher("cL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("class"));
assertTrue(new MinusculeMatcher("CL", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("Class"));
assertFalse(new MinusculeMatcher("abc", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matches("_abc"));
}
public void testMinusculeAllImportant() {
assertTrue(new NameUtil.MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertFalse(new NameUtil.MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic"));
assertFalse(new NameUtil.MinusculeMatcher("FOO", NameUtil.MatchingCaseSensitivity.ALL).matches("foo"));
assertFalse(new NameUtil.MinusculeMatcher("foo", NameUtil.MatchingCaseSensitivity.ALL).matches("fOO"));
assertFalse(new NameUtil.MinusculeMatcher("Wl", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertTrue(new NameUtil.MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertFalse(new NameUtil.MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("Weblogic"));
assertFalse(new NameUtil.MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic"));
assertFalse(new NameUtil.MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertFalse(new NameUtil.MinusculeMatcher("Str", NameUtil.MatchingCaseSensitivity.ALL).matches("SomeThingRidiculous"));
assertTrue(new MinusculeMatcher("WebLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertFalse(new MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic"));
assertFalse(new MinusculeMatcher("FOO", NameUtil.MatchingCaseSensitivity.ALL).matches("foo"));
assertFalse(new MinusculeMatcher("foo", NameUtil.MatchingCaseSensitivity.ALL).matches("fOO"));
assertFalse(new MinusculeMatcher("Wl", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertTrue(new MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertFalse(new MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("Weblogic"));
assertFalse(new MinusculeMatcher("WL", NameUtil.MatchingCaseSensitivity.ALL).matches("weblogic"));
assertFalse(new MinusculeMatcher("webLogic", NameUtil.MatchingCaseSensitivity.ALL).matches("WebLogic"));
assertFalse(new MinusculeMatcher("Str", NameUtil.MatchingCaseSensitivity.ALL).matches("SomeThingRidiculous"));
}
public void testMatchingFragments() {
@NonNls String sample = "NoClassDefFoundException";
// 0 2 7 10 15 21
assertOrderedEquals(new NameUtil.MinusculeMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
assertOrderedEquals(new MinusculeMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 1), TextRange.from(2, 2), TextRange.from(7, 1), TextRange.from(10, 3), TextRange.from(21, 3));
sample = "doGet(HttpServletRequest, HttpServletResponse):void";
// 0 22
assertOrderedEquals(new NameUtil.MinusculeMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
assertOrderedEquals(new MinusculeMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 1), TextRange.from(22, 2));
assertOrderedEquals(new NameUtil.MinusculeMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
assertOrderedEquals(new MinusculeMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 4), TextRange.from(22, 2));
sample = "_test";
assertOrderedEquals(new NameUtil.MinusculeMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
assertOrderedEquals(new MinusculeMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 1));
assertOrderedEquals(new NameUtil.MinusculeMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
assertOrderedEquals(new MinusculeMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 2));
}
public void testMatchingFragmentsSorted() {
@NonNls String sample = "SWUPGRADEHDLRFSPR7TEST";
// 0 9 12
assertOrderedEquals(new NameUtil.MinusculeMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
assertOrderedEquals(new MinusculeMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 3), TextRange.from(9, 1), TextRange.from(12, 1));
}
public void testPreferCapsMatching() {
String sample = "getCurrentUser";
// 0 4 10
assertOrderedEquals(new NameUtil.MinusculeMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
assertOrderedEquals(new MinusculeMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 4), TextRange.from(10, 1));
}
@@ -390,7 +391,7 @@ public class NameUtilTest extends UsefulTestCase {
}
public void testMeaningfulMatchingDegree() {
assertTrue(new NameUtil.MinusculeMatcher(" EUC-", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matchingDegree("x-EUC-TW") > Integer.MIN_VALUE);
assertTrue(new MinusculeMatcher(" EUC-", NameUtil.MatchingCaseSensitivity.FIRST_LETTER).matchingDegree("x-EUC-TW") > Integer.MIN_VALUE);
}
private static void assertPreference(@NonNls String pattern,
@@ -403,7 +404,7 @@ public class NameUtilTest extends UsefulTestCase {
@NonNls String less,
@NonNls String more,
NameUtil.MatchingCaseSensitivity sensitivity) {
NameUtil.MinusculeMatcher matcher = new NameUtil.MinusculeMatcher(pattern, sensitivity);
MinusculeMatcher matcher = new MinusculeMatcher(pattern, sensitivity);
int iLess = matcher.matchingDegree(less);
int iMore = matcher.matchingDegree(more);
assertTrue(iLess + ">=" + iMore + "; " + less + ">=" + more, iLess < iMore);
@@ -411,24 +412,24 @@ public class NameUtilTest extends UsefulTestCase {
public void testPerformance() {
@NonNls final String longName = "ThisIsAQuiteLongNameWithParentheses().Dots.-Minuses-_UNDERSCORES_digits239:colons:/slashes\\AndOfCourseManyLetters";
final List<NameUtil.MinusculeMatcher> matching = new ArrayList<NameUtil.MinusculeMatcher>();
final List<NameUtil.MinusculeMatcher> nonMatching = new ArrayList<NameUtil.MinusculeMatcher>();
final List<MinusculeMatcher> matching = new ArrayList<MinusculeMatcher>();
final List<MinusculeMatcher> nonMatching = new ArrayList<MinusculeMatcher>();
for (String s : CollectionFactory.ar("*", "*i", "*a", "*u", "T", "ti", longName, longName.substring(0, 20))) {
matching.add(new NameUtil.MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE));
matching.add(new MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE));
}
for (String s : CollectionFactory.ar("A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "ta")) {
nonMatching.add(new NameUtil.MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE));
nonMatching.add(new MinusculeMatcher(s, NameUtil.MatchingCaseSensitivity.NONE));
}
PlatformTestUtil.startPerformanceTest("Matcher is slow", 1200, new ThrowableRunnable() {
PlatformTestUtil.startPerformanceTest("Matcher is slow", 1700, new ThrowableRunnable() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
for (NameUtil.MinusculeMatcher matcher : matching) {
for (MinusculeMatcher matcher : matching) {
assertTrue(matcher.matches(longName));
}
for (NameUtil.MinusculeMatcher matcher : nonMatching) {
for (MinusculeMatcher matcher : nonMatching) {
assertFalse(matcher.matches(longName));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -36,6 +36,7 @@ public abstract class HighlightTestInfo implements Disposable {
Disposer.register(parentDisposable, this);
myPlace = parentDisposable.toString();
}
public HighlightTestInfo checkWarnings() { checkWarnings = true; return this; }
public HighlightTestInfo checkWeakWarnings() { checkWeakWarnings = true; return this; }
public HighlightTestInfo checkInfos() { checkInfos = true; return this; }
@@ -43,10 +44,14 @@ public abstract class HighlightTestInfo implements Disposable {
public HighlightTestInfo projectRoot(@NonNls @NotNull String root) { projectRoot = root; return this; }
public HighlightTestInfo test() throws Exception {
doTest();
tested = true;
Disposer.dispose(this);
return this;
try {
doTest();
return this;
}
finally {
tested = true;
Disposer.dispose(this);
}
}
@Override
@@ -0,0 +1,296 @@
/*
* Copyright 2000-2012 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.psi.codeStyle;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.FList;
import com.intellij.util.text.CharArrayCharSequence;
import com.intellij.util.text.Matcher;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
/**
* @author peter
*/
public class MinusculeMatcher implements Matcher {
private final char[] myPattern;
private final NameUtil.MatchingCaseSensitivity myOptions;
public MinusculeMatcher(String pattern, NameUtil.MatchingCaseSensitivity options) {
myOptions = options;
myPattern = StringUtil.trimEnd(pattern, "* ").replaceAll(":", "\\*:").toCharArray();
}
@Nullable
private FList<TextRange> matchName(String name, int patternIndex, int nameIndex) {
if (patternIndex == myPattern.length) {
return FList.emptyList();
}
if ('*' == myPattern[patternIndex]) {
return skipChars(name, patternIndex, nameIndex, true);
}
if (nameIndex == name.length()) {
return null;
}
if ('.' == myPattern[patternIndex] && name.charAt(nameIndex) != '.') {
return skipChars(name, patternIndex, nameIndex, false);
}
if (' ' == myPattern[patternIndex] && patternIndex != myPattern.length - 1) {
return skipWords(name, patternIndex, nameIndex);
}
if ((patternIndex == 0 || patternIndex == 1 && myPattern[0] == ' ' && nameIndex == 0) &&
myOptions != NameUtil.MatchingCaseSensitivity.NONE && name.charAt(nameIndex) != myPattern[patternIndex]) {
return null;
}
if (NameUtil.isWordSeparator(name.charAt(nameIndex))) {
return skipSeparators(name, patternIndex, nameIndex);
}
if (StringUtil.toLowerCase(name.charAt(nameIndex)) != StringUtil.toLowerCase(myPattern[patternIndex])) {
if (Character.isDigit(name.charAt(nameIndex)) && nameIndex > 0 || (name.charAt(nameIndex) == '.' && name.indexOf('.', nameIndex + 1) > 0)) {
return matchName(name, patternIndex, nameIndex + 1);
}
return null;
}
if (myOptions == NameUtil.MatchingCaseSensitivity.ALL && name.charAt(nameIndex) != myPattern[patternIndex]) {
return null;
}
int nextStart = NameUtil.nextWord(name, nameIndex);
int lastUpper = NameUtil.isWordStart(myPattern[patternIndex]) ? 0 : -1;
int i = 1;
while (true) {
if (patternIndex + i == myPattern.length || i + nameIndex == nextStart) {
break;
}
char p = myPattern[patternIndex + i];
char w = name.charAt(i + nameIndex);
if (lastUpper == i - 1 && NameUtil.isWordStart(p) && myOptions != NameUtil.MatchingCaseSensitivity.ALL) {
if (p == w) {
lastUpper = i;
}
p = StringUtil.toLowerCase(p);
}
if (myOptions != NameUtil.MatchingCaseSensitivity.ALL) {
w = StringUtil.toLowerCase(w);
}
if (w != p) {
break;
}
i++;
}
if (isFinalSpaceMatch(name, patternIndex, nameIndex, nextStart, i)) {
return FList.<TextRange>emptyList().prepend(TextRange.from(nameIndex, i));
}
return matchAfterFragment(name, patternIndex, nameIndex, nextStart, lastUpper, i);
}
private boolean isFinalSpaceMatch(String name, int patternIndex, int nameIndex, int nextStart, int i) {
return nextStart == name.length() &&
patternIndex + i == myPattern.length - 1 &&
' ' == myPattern[patternIndex + i] &&
(i == 1 && NameUtil.isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length());
}
@Nullable
private FList<TextRange> matchAfterFragment(String name, int patternIndex, int nameIndex, int nextStart, int lastUpper, int matchLen) {
boolean star = patternIndex + matchLen < myPattern.length && myPattern[patternIndex + matchLen] == '*';
if (lastUpper >= 0) {
FList<TextRange> ranges = matchName(name, patternIndex + lastUpper + 1, star && matchLen == lastUpper ? nameIndex + lastUpper : nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, lastUpper + 1);
}
}
int trial = matchLen;
while (trial > 0) {
FList<TextRange> ranges = matchName(name, patternIndex + trial, nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, trial);
}
trial--;
}
FList<TextRange> ranges = matchName(name, patternIndex + matchLen, nameIndex + matchLen);
if (ranges != null) {
return prependRange(ranges, nameIndex, matchLen);
}
return null;
}
private static FList<TextRange> prependRange(FList<TextRange> ranges, int from, int length) {
TextRange head = ranges.getHead();
if (head != null && head.getStartOffset() == from + length) {
return ranges.getTail().prepend(new TextRange(from, head.getEndOffset()));
}
return ranges.prepend(TextRange.from(from, length));
}
@Nullable
private FList<TextRange> skipSeparators(String name, int patternIndex, int nameIndex) {
int nextStart = NameUtil.nextWord(name, nameIndex);
assert nextStart - nameIndex == 1 : "'" + name + "'" + nameIndex + " " + nextStart;
char p = myPattern[patternIndex];
if (NameUtil.isWordSeparator(p)) {
if (myOptions != NameUtil.MatchingCaseSensitivity.NONE &&
nameIndex == 0 && name.length() > 1 && patternIndex + 1 < myPattern.length &&
NameUtil.isWordSeparator(name.charAt(1)) && !NameUtil.isWordSeparator(myPattern[patternIndex + 1])) {
return null;
}
final FList<TextRange> ranges = matchName(name, patternIndex + 1, nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, 1);
}
return null;
}
return matchName(name, patternIndex, nextStart);
}
@Nullable
private FList<TextRange> skipChars(String name, int patternIndex, int nameIndex, boolean maySkipNextChar) {
while ('*' == myPattern[patternIndex]) {
patternIndex++;
if (patternIndex == myPattern.length) {
return FList.emptyList();
}
}
String nextChar = String.valueOf(myPattern[patternIndex]);
boolean upper = Character.isUpperCase(myPattern[patternIndex]);
int fromIndex = nameIndex;
while (true) {
int next = StringUtil.indexOfIgnoreCase(name, nextChar, fromIndex);
if (next < 0) {
break;
}
if (upper && next > 0 && !Character.isUpperCase(name.charAt(next))) {
fromIndex = next + 1;
continue;
}
FList<TextRange> ranges = matchName(name, patternIndex, next);
if (ranges != null) {
return ranges;
}
if (!maySkipNextChar) {
return null;
}
fromIndex = next + 1;
}
return null;
}
@Nullable
private FList<TextRange> skipWords(String name, int patternIndex, int nameIndex) {
while (' ' == myPattern[patternIndex]) {
patternIndex++;
if (patternIndex == myPattern.length) {
return null;
}
}
if (nameIndex == 0 || NameUtil.isWordStart(name, nameIndex)) {
FList<TextRange> ranges = matchName(name, patternIndex, nameIndex);
if (ranges != null) {
return ranges;
}
}
boolean separatorInPattern = NameUtil.isWordSeparator(myPattern[patternIndex]);
int fromIndex = nameIndex;
while (fromIndex < name.length()) {
int next = separatorInPattern ? name.indexOf(myPattern[patternIndex], fromIndex) : NameUtil.nextWord(name, fromIndex);
if (next < 0) {
break;
}
FList<TextRange> ranges = matchName(name, patternIndex, next);
if (ranges != null) {
return ranges;
}
fromIndex = next;
if (separatorInPattern) {
fromIndex++;
}
}
return null;
}
public int matchingDegree(String name) {
Iterable<TextRange> iterable = matchingFragments(name);
if (iterable == null) return Integer.MIN_VALUE;
int fragmentCount = 0;
int matchingCase = 0;
CharArrayCharSequence seq = new CharArrayCharSequence(myPattern);
int p = -1;
TextRange first = null;
for (TextRange range : iterable) {
if (first == null) {
first = range;
}
for (int i = range.getStartOffset(); i < range.getEndOffset(); i++) {
char c = name.charAt(i);
p = StringUtil.indexOf(seq, c, p + 1, myPattern.length, false);
if (p < 0) {
break;
}
matchingCase += c == myPattern[p] ? 1 : 0;
}
fragmentCount++;
}
int commonStart = 0;
while (commonStart < name.length() && commonStart < myPattern.length && name.charAt(commonStart) == myPattern[commonStart]) {
commonStart++;
}
boolean prefixMatching = first != null && first.getStartOffset() == 0;
boolean middleWordStart = first != null && first.getStartOffset() > 0 && NameUtil.isWordStart(name, first.getStartOffset());
return -fragmentCount + matchingCase * 10 + commonStart + (prefixMatching ? 2 : middleWordStart ? 1 : 0) * 100;
}
@Override
public boolean matches(String name) {
return matchingFragments(name) != null;
}
@Nullable
public Iterable<TextRange> matchingFragments(String name) {
if (name.isEmpty()) {
return myPattern.length == 0 ? Collections.<TextRange>emptyList() : null;
}
return matchName(name, 0, 0);
}
}
@@ -15,20 +15,15 @@
*/
package com.intellij.psi.codeStyle;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FList;
import com.intellij.util.text.CharArrayCharSequence;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class NameUtil {
@@ -331,24 +326,24 @@ public class NameUtil {
return suggestion;
}
private static boolean isWordStart(String text, int i) {
static boolean isWordStart(String text, int i) {
if (isWordStart(text.charAt(i))) {
return true;
}
if (!Character.isLetterOrDigit(text.charAt(i))) {
return false;
}
if (i > 0 && (MinusculeMatcher.isWordSeparator(text.charAt(i - 1)) || text.charAt(i - 1) == '.')) {
if (i > 0 && (isWordSeparator(text.charAt(i - 1)) || text.charAt(i - 1) == '.')) {
return true;
}
return false;
}
private static boolean isWordStart(char p) {
static boolean isWordStart(char p) {
return Character.isUpperCase(p) || Character.isDigit(p);
}
private static int nextWord(String text, int start) {
static int nextWord(String text, int start) {
if (!Character.isLetterOrDigit(text.charAt(start))) {
return start + 1;
}
@@ -378,6 +373,10 @@ public class NameUtil {
}
}
static boolean isWordSeparator(char c) {
return Character.isWhitespace(c) || c == '_' || c == '-' || c == ':';
}
/**
* @deprecated use com.intellij.util.text.Matcher
*/
@@ -409,276 +408,4 @@ public class NameUtil {
public enum MatchingCaseSensitivity {
NONE, FIRST_LETTER, ALL
}
public static class MinusculeMatcher implements com.intellij.util.text.Matcher {
private final char[] myPattern;
private final MatchingCaseSensitivity myOptions;
public MinusculeMatcher(String pattern, MatchingCaseSensitivity options) {
myOptions = options;
myPattern = StringUtil.trimEnd(pattern, "* ").replaceAll(":", "\\*:").toCharArray();
}
@Nullable
private FList<TextRange> matchName(String name, int patternIndex, int nameIndex) {
if (patternIndex == myPattern.length) {
return FList.emptyList();
}
if ('*' == myPattern[patternIndex]) {
return skipChars(name, patternIndex, nameIndex, true);
}
if (nameIndex == name.length()) {
return null;
}
if ('.' == myPattern[patternIndex] && name.charAt(nameIndex) != '.') {
return skipChars(name, patternIndex, nameIndex, false);
}
if (' ' == myPattern[patternIndex] && patternIndex != myPattern.length - 1) {
return skipWords(name, patternIndex, nameIndex);
}
if ((patternIndex == 0 || patternIndex == 1 && myPattern[0] == ' ' && nameIndex == 0) &&
myOptions != MatchingCaseSensitivity.NONE && name.charAt(nameIndex) != myPattern[patternIndex]) {
return null;
}
if (isWordSeparator(name.charAt(nameIndex))) {
return skipSeparators(name, patternIndex, nameIndex);
}
if (StringUtil.toLowerCase(name.charAt(nameIndex)) != StringUtil.toLowerCase(myPattern[patternIndex])) {
if (Character.isDigit(name.charAt(nameIndex)) && nameIndex > 0 || (name.charAt(nameIndex) == '.' && name.indexOf('.', nameIndex + 1) > 0)) {
return matchName(name, patternIndex, nameIndex + 1);
}
return null;
}
if (myOptions == MatchingCaseSensitivity.ALL && name.charAt(nameIndex) != myPattern[patternIndex]) {
return null;
}
int nextStart = NameUtil.nextWord(name, nameIndex);
int lastUpper = isWordStart(myPattern[patternIndex]) ? 0 : -1;
int i = 1;
while (true) {
if (patternIndex + i == myPattern.length || i + nameIndex == nextStart) {
break;
}
char p = myPattern[patternIndex + i];
char w = name.charAt(i + nameIndex);
if (lastUpper == i - 1 && isWordStart(p) && myOptions != MatchingCaseSensitivity.ALL) {
if (p == w) {
lastUpper = i;
}
p = StringUtil.toLowerCase(p);
}
if (myOptions != MatchingCaseSensitivity.ALL) {
w = StringUtil.toLowerCase(w);
}
if (w != p) {
break;
}
i++;
}
if (isFinalSpaceMatch(name, patternIndex, nameIndex, nextStart, i)) {
return FList.<TextRange>emptyList().prepend(TextRange.from(nameIndex, i));
}
return matchAfterFragment(name, patternIndex, nameIndex, nextStart, lastUpper, i);
}
private boolean isFinalSpaceMatch(String name, int patternIndex, int nameIndex, int nextStart, int i) {
return nextStart == name.length() &&
patternIndex + i == myPattern.length - 1 &&
' ' == myPattern[patternIndex + i] &&
(i == 1 && isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length());
}
@Nullable
private FList<TextRange> matchAfterFragment(String name, int patternIndex, int nameIndex, int nextStart, int lastUpper, int matchLen) {
boolean star = patternIndex + matchLen < myPattern.length && myPattern[patternIndex + matchLen] == '*';
if (lastUpper >= 0) {
FList<TextRange> ranges = matchName(name, patternIndex + lastUpper + 1, star && matchLen == lastUpper ? nameIndex + lastUpper : nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, lastUpper + 1);
}
}
int trial = matchLen;
while (trial > 0) {
FList<TextRange> ranges = matchName(name, patternIndex + trial, nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, trial);
}
trial--;
}
FList<TextRange> ranges = matchName(name, patternIndex + matchLen, nameIndex + matchLen);
if (ranges != null) {
return prependRange(ranges, nameIndex, matchLen);
}
return null;
}
private static FList<TextRange> prependRange(FList<TextRange> ranges, int from, int length) {
TextRange head = ranges.getHead();
if (head != null && head.getStartOffset() == from + length) {
return ranges.getTail().prepend(new TextRange(from, head.getEndOffset()));
}
return ranges.prepend(TextRange.from(from, length));
}
private static boolean isWordSeparator(char c) {
return Character.isWhitespace(c) || c == '_' || c == '-' || c == ':';
}
@Nullable
private FList<TextRange> skipSeparators(String name, int patternIndex, int nameIndex) {
int nextStart = NameUtil.nextWord(name, nameIndex);
assert nextStart - nameIndex == 1 : "'" + name + "'" + nameIndex + " " + nextStart;
char p = myPattern[patternIndex];
if (isWordSeparator(p)) {
if (myOptions != MatchingCaseSensitivity.NONE &&
nameIndex == 0 && name.length() > 1 && patternIndex + 1 < myPattern.length &&
isWordSeparator(name.charAt(1)) && !isWordSeparator(myPattern[patternIndex + 1])) {
return null;
}
final FList<TextRange> ranges = matchName(name, patternIndex + 1, nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, 1);
}
return null;
}
return matchName(name, patternIndex, nextStart);
}
@Nullable
private FList<TextRange> skipChars(String name, int patternIndex, int nameIndex, boolean maySkipNextChar) {
while ('*' == myPattern[patternIndex]) {
patternIndex++;
if (patternIndex == myPattern.length) {
return FList.emptyList();
}
}
String nextChar = String.valueOf(myPattern[patternIndex]);
boolean upper = Character.isUpperCase(myPattern[patternIndex]);
int fromIndex = nameIndex;
while (true) {
int next = StringUtil.indexOfIgnoreCase(name, nextChar, fromIndex);
if (next < 0) {
break;
}
if (upper && next > 0 && !Character.isUpperCase(name.charAt(next))) {
fromIndex = next + 1;
continue;
}
FList<TextRange> ranges = matchName(name, patternIndex, next);
if (ranges != null) {
return ranges;
}
if (!maySkipNextChar) {
return null;
}
fromIndex = next + 1;
}
return null;
}
@Nullable
private FList<TextRange> skipWords(String name, int patternIndex, int nameIndex) {
while (' ' == myPattern[patternIndex]) {
patternIndex++;
if (patternIndex == myPattern.length) {
return null;
}
}
if (nameIndex == 0 || isWordStart(name, nameIndex)) {
FList<TextRange> ranges = matchName(name, patternIndex, nameIndex);
if (ranges != null) {
return ranges;
}
}
boolean separatorInPattern = isWordSeparator(myPattern[patternIndex]);
int fromIndex = nameIndex;
while (fromIndex < name.length()) {
int next = separatorInPattern ? name.indexOf(myPattern[patternIndex], fromIndex) : nextWord(name, fromIndex);
if (next < 0) {
break;
}
FList<TextRange> ranges = matchName(name, patternIndex, next);
if (ranges != null) {
return ranges;
}
fromIndex = next;
if (separatorInPattern) {
fromIndex++;
}
}
return null;
}
public int matchingDegree(String name) {
Iterable<TextRange> iterable = matchingFragments(name);
if (iterable == null) return Integer.MIN_VALUE;
int fragmentCount = 0;
int matchingCase = 0;
CharArrayCharSequence seq = new CharArrayCharSequence(myPattern);
int p = -1;
TextRange first = null;
for (TextRange range : iterable) {
if (first == null) {
first = range;
}
for (int i = range.getStartOffset(); i < range.getEndOffset(); i++) {
char c = name.charAt(i);
p = StringUtil.indexOf(seq, c, p + 1, myPattern.length, false);
if (p < 0) {
break;
}
matchingCase += c == myPattern[p] ? 1 : 0;
}
fragmentCount++;
}
int commonStart = 0;
while (commonStart < name.length() && commonStart < myPattern.length && name.charAt(commonStart) == myPattern[commonStart]) {
commonStart++;
}
boolean prefixMatching = first != null && first.getStartOffset() == 0;
boolean middleWordStart = first != null && first.getStartOffset() > 0 && isWordStart(name, first.getStartOffset());
return -fragmentCount + matchingCase * 10 + commonStart + (prefixMatching ? 2 : middleWordStart ? 1 : 0) * 100;
}
@Override
public boolean matches(String name) {
return matchingFragments(name) != null;
}
@Nullable
public Iterable<TextRange> matchingFragments(String name) {
if (name.isEmpty()) {
return myPattern.length == 0 ? Collections.<TextRange>emptyList() : null;
}
return matchName(name, 0, 0);
}
}
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -1023,7 +1024,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
new Task.Backgroundable(project, VcsBundle.message("show.diff.progress.title")) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
LocalHistoryAction action = file != null ? startLocalHistoryAction(revision) : LocalHistoryAction.NULL;
final LocalHistoryAction action = file != null ? startLocalHistoryAction(revision) : LocalHistoryAction.NULL;
final byte[] revisionContent;
try {
revisionContent = VcsHistoryUtil.loadRevisionContent(revision);
@@ -1049,39 +1050,37 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
return;
}
try {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override public void run() {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
public void run() {
if (file != null && !file.isWritable()) {
if (ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(file).hasReadonlyFiles()) {
return;
}
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
try {
new WriteCommandAction.Simple(project) {
@Override
protected void run() throws Throwable {
if (file != null &&
!file.isWritable() &&
ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(file).hasReadonlyFiles()) {
return;
}
try {
write(revisionContent);
} catch (IOException e) {
Messages.showMessageDialog(VcsBundle.message("message.text.cannot.save.content", e.getLocalizedMessage()),
VcsBundle.message( "message.title.get.revision.content"), Messages.getErrorIcon());
}
}
}, createGetActionTitle(revision), null);
try {
write(revisionContent);
}
catch (IOException e) {
Messages.showMessageDialog(VcsBundle.message("message.text.cannot.save.content", e.getLocalizedMessage()),
VcsBundle.message("message.title.get.revision.content"), Messages.getErrorIcon());
}
}
});
}.execute();
if (file != null) {
VcsDirtyScopeManager.getInstance(project).fileDirty(file);
}
}
finally {
action.finish();
}
});
if (file != null) {
VcsDirtyScopeManager.getInstance(project).fileDirty(file);
}
}
finally {
action.finish();
}
});
}
}.queue();
}
@@ -49,7 +49,6 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.OptionsDialog;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NonNls;
@@ -581,19 +580,14 @@ public abstract class AbstractCommonUpdateAction extends AbstractVcsAction {
updateInfoTree.setBefore(myBefore);
updateInfoTree.setAfter(myAfter);
// todo make temporal listener of changes reload
if (updateInfoTree != null) {
updateInfoTree.setCanGroupByChangeList(canGroupByChangelist(myVcsToVirtualFiles.keySet()));
final MessageBusConnection messageBusConnection = myProject.getMessageBus().connect();
messageBusConnection.subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesAdapter() {
public void incomingChangesUpdated(final List<CommittedChangeList> receivedChanges) {
if (receivedChanges != null) {
updateInfoTree.setChangeLists(receivedChanges);
messageBusConnection.disconnect();
}
updateInfoTree.setCanGroupByChangeList(canGroupByChangelist(myVcsToVirtualFiles.keySet()));
myProject.getMessageBus().connect(updateInfoTree).subscribe(CommittedChangesCache.COMMITTED_TOPIC, new CommittedChangesAdapter() {
public void incomingChangesUpdated(final List<CommittedChangeList> receivedChanges) {
if (receivedChanges != null) {
updateInfoTree.setChangeLists(receivedChanges);
}
});
}
}
});
}
public void onCancel() {
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ipp.opassign.assignment;
class ByteOpassign {
void foo(byte b) {
b<caret> += 1;
}
}
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ipp.opassign.assignment;
class ByteOpassign {
void foo(byte b) {
b = (byte) (b + 1);
}
}
@@ -1,8 +0,0 @@
package com.siyeh.ipp.opassign.assignment;
class ByteOpassign {
void foo(byte b) {
b<caret> += 1;
}
}
@@ -1,8 +0,0 @@
package com.siyeh.ipp.opassign.assignment;
class ByteOpassign {
void foo(byte b) {
b = (byte) (b + 1);
}
}
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ipp.opassign.assignment;
class DoubleOpassign {
void foo(double d) {
d <caret>+= 0.5;
}
}
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ipp.opassign.assignment;
class DoubleOpassign {
void foo(double d) {
d = d + 0.5;
}
}
@@ -1,8 +0,0 @@
package com.siyeh.ipp.opassign.assignment;
class DoubleOpassign {
void foo(double d) {
d <caret>+= 0.5;
}
}
@@ -1,8 +0,0 @@
package com.siyeh.ipp.opassign.assignment;
class DoubleOpassign {
void foo(double d) {
d = d + 0.5;
}
}
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ipp.opassign.assignment;
class StringOpassign {
void foo(String s) {
s = s + 1.0;
}
}
@@ -1,8 +0,0 @@
package com.siyeh.ipp.opassign.assignment;
class StringOpassign {
void foo(String s) {
s = s + 1.0;
}
}
@@ -17,6 +17,7 @@ package com.intellij.android.designer.model;
import com.intellij.android.designer.propertyTable.FragmentProperty;
import com.intellij.android.designer.propertyTable.IdProperty;
import com.intellij.android.designer.propertyTable.JavadocParser;
import com.intellij.android.designer.propertyTable.editors.ChooseClassDialog;
import com.intellij.android.designer.propertyTable.editors.ResourceEditor;
import com.intellij.designer.model.RadComponent;
@@ -45,15 +46,17 @@ public class RadFragment extends RadViewComponent implements IConfigurableCompon
setValue(fragment);
}
}
}, "Supply the name of the fragment class to instantiate.");
}, JavadocParser.build("name", "Supply the name of the fragment class to instantiate."));
private static final Property TAG_PROPERTY = new FragmentProperty("tag", new TextEditor(),
"Use <code>device-admin</code> as the root tag of the XML resource that\n" +
"describes a\n" +
" {@link android.app.admin.DeviceAdminReceiver}, which is\n" +
" referenced from its\n" +
" {@link android.app.admin.DeviceAdminReceiver#DEVICE_ADMIN_META_DATA}\n" +
" meta-data entry. Described here are the attributes that can be\n" +
" included in that tag.");
JavadocParser.build(
"tag",
"Use <code>device-admin</code> as the root tag of the XML resource that\n" +
"describes a\n" +
" {@link android.app.admin.DeviceAdminReceiver}, which is\n" +
" referenced from its\n" +
" {@link android.app.admin.DeviceAdminReceiver#DEVICE_ADMIN_META_DATA}\n" +
" meta-data entry. Described here are the attributes that can be\n" +
" included in that tag."));
private static final String NAME_KEY = "fragment.name";
@Override
@@ -25,6 +25,7 @@ import com.intellij.designer.propertyTable.renderers.LabelPropertyRenderer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.android.designer.propertyTable.JavadocParser;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,6 +36,8 @@ public class CenterProperty extends Property<RadViewComponent> {
private static final String[] COMBO_ITEMS = {"horizontal", "vertical", "both"};
private static final String[] ATTR_ITEMS =
{"android:layout_centerHorizontal", "android:layout_centerVertical", "android:layout_centerInParent"};
private static final String JAVA_DOC =
JavadocParser.build("layout:centerInParent", "Set centers this child horizontally or vertically within its parent.");
private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null);
private final PropertyEditor myEditor = new StringsComboEditor(COMBO_ITEMS);
@@ -116,6 +119,6 @@ public class CenterProperty extends Property<RadViewComponent> {
@Override
public String getJavadocText() {
return "Set centers this child horizontally or vertically within its parent.";
return JAVA_DOC;
}
}
@@ -22,6 +22,7 @@ import com.intellij.android.designer.designSurface.layout.relative.RelativeDecor
import com.intellij.android.designer.model.PropertyParser;
import com.intellij.android.designer.model.RadViewLayoutWithData;
import com.intellij.android.designer.model.layout.actions.AllGravityAction;
import com.intellij.android.designer.propertyTable.JavadocParser;
import com.intellij.designer.componentTree.TreeEditOperation;
import com.intellij.designer.designSurface.*;
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
@@ -54,7 +55,9 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD
@Override
public void configureProperties(List<Property> properties) {
CompoundProperty alignComponent =
new CompoundProperty("layout:alignComponent", "Positions the edges of this view to the edges of the another view.");
new CompoundProperty("layout:alignComponent",
JavadocParser
.build("layout:alignComponent", "Positions the edges of this view to the edges of the another view."));
PropertyParser.moveProperties(properties, alignComponent,
"layout:alignTop", "top:top",
"layout:below", "top:bottom",
@@ -68,7 +71,8 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD
properties.add(alignComponent);
CompoundProperty alignParent =
new CompoundProperty("layout:alignParent", "Positions the edges of this view to the edges of the parent.");
new CompoundProperty("layout:alignParent",
JavadocParser.build("layout:alignParent", "Positions the edges of this view to the edges of the parent."));
PropertyParser.moveProperties(properties, alignParent,
"layout:alignParentTop", "top",
"layout:alignParentLeft", "left",
@@ -41,6 +41,7 @@ public class AttributeProperty extends Property<RadViewComponent> {
protected final AttributeDefinition myDefinition;
private final PropertyRenderer myRenderer;
private final PropertyEditor myEditor;
private String myJavadocText;
public AttributeProperty(@NotNull String name, @NotNull AttributeDefinition definition) {
this(null, name, definition);
@@ -137,6 +138,12 @@ public class AttributeProperty extends Property<RadViewComponent> {
@Override
public String getJavadocText() {
return myDefinition.getDocValue();
if (myJavadocText == null) {
String javadocText = myDefinition.getDocValue();
if (javadocText != null) {
myJavadocText = JavadocParser.build(getName(), javadocText);
}
}
return myJavadocText;
}
}
@@ -37,6 +37,7 @@ import java.util.List;
* @author Alexander Lobas
*/
public class CustomViewProperty extends Property<RadCustomViewComponent> {
private static final String JAVA_DOC = JavadocParser.build("view:class", "The fully qualified name of the class.");
private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null);
private final PropertyEditor myEditor = new ResourceEditor(null, Collections.<AttributeFormat>emptySet(), null) {
@Override
@@ -122,6 +123,6 @@ public class CustomViewProperty extends Property<RadCustomViewComponent> {
@Override
public String getJavadocText() {
return "The fully qualified name of the class.";
return JAVA_DOC;
}
}
@@ -40,6 +40,7 @@ public class FlagProperty extends Property<RadViewComponent> implements IPropert
private final PropertyRenderer myRenderer = new LabelPropertyRenderer(null);
protected final AttributeDefinition myDefinition;
protected final List<Property<RadViewComponent>> myOptions = new ArrayList<Property<RadViewComponent>>();
private String myJavadocText;
public FlagProperty(@NotNull String name, @NotNull AttributeDefinition definition) {
super(null, name);
@@ -163,7 +164,13 @@ public class FlagProperty extends Property<RadViewComponent> implements IPropert
@Override
public String getJavadocText() {
return myDefinition.getDocValue();
if (myJavadocText == null) {
String javadocText = myDefinition.getDocValue();
if (javadocText != null) {
myJavadocText = JavadocParser.build(getName(), javadocText);
}
}
return myJavadocText;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -41,6 +41,7 @@ public class IncludeLayoutProperty extends Property<RadViewComponent> {
public static ResourceType[] TYPES = new ResourceType[]{ResourceType.LAYOUT};
private static final Set<AttributeFormat> FORMATS = EnumSet.of(AttributeFormat.Reference);
public static final Property INSTANCE = new IncludeLayoutProperty();
private static final String JAVA_DOC = JavadocParser.build(NAME, "Reference to the layout file you wish to include.");
private final PropertyRenderer myRenderer = new ResourceRenderer(FORMATS);
private final PropertyEditor myEditor = new ResourceEditor(TYPES, FORMATS, null);
@@ -91,6 +92,6 @@ public class IncludeLayoutProperty extends Property<RadViewComponent> {
@Override
public String getJavadocText() {
return "Reference to the layout file you wish to include.";
return JAVA_DOC;
}
}
@@ -0,0 +1,86 @@
/*
* Copyright 2000-2012 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.android.designer.propertyTable;
import com.intellij.codeInsight.documentation.DocumentationManager;
import org.jetbrains.annotations.NotNull;
/**
* @author Alexander Lobas
*/
public class JavadocParser {
private static final String[] TAGS = {"{see ", "{@see ", "{@link "};
@NotNull
public static String build(@NotNull String title, @NotNull String javadoc) {
StringBuilder buffer = new StringBuilder();
buffer.append("<html><head><style type=\"text/css\">p {margin: 5px 0;}</style></head><body>");
buffer.append("<p><b>").append(title).append("</b> - ");
for (String tag : TAGS) {
javadoc = convertLink(javadoc, tag);
}
javadoc = javadoc.replaceAll("<code>", "<i>");
javadoc = javadoc.replaceAll("</code>", "</i>");
buffer.append(javadoc);
return buffer.append("</body></html>").toString();
}
private static String convertLink(String javadoc, String tag) {
StringBuilder buffer = new StringBuilder();
int length = javadoc.length();
int start = 0;
while (true) {
int index = javadoc.indexOf(tag, start);
if (index == -1) {
buffer.append(javadoc.substring(start, length));
break;
}
else {
buffer.append(javadoc.substring(start, index));
int linkStart = index + tag.length();
int end = javadoc.indexOf('}', linkStart);
String linkValue = javadoc.substring(linkStart, end).trim();
String href;
String text;
int spaceIndex = linkValue.indexOf(' ');
if (spaceIndex != -1) {
href = linkValue.substring(0, spaceIndex);
text = linkValue.substring(spaceIndex + 1);
}
else {
href = text = linkValue;
}
text = text.replace('#', '.');
DocumentationManager.createHyperlink(buffer, href, text, true);
start = end + 1;
}
}
return buffer.toString();
}
}
@@ -92,7 +92,7 @@ class AndroidFacet extends Facet {
}
if (lookInContentRoot) {
module.contentRoots.each {String contentRoot ->
for (String contentRoot in module.contentRoots) {
def absPath = FileUtil.toSystemIndependentName(contentRoot + relativePath)
def f = new File(absPath)
@@ -584,6 +584,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
if (!FileUtil.moveDirWithContent(tmpOutputDir, aptOutputDirectory)) {
context.processMessage(new CompilerMessage(ANDROID_APT_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle
.message("android.jps.errors.cannot.move.content", tmpOutputDir.getPath(), aptOutputDirectory.getPath())));
success = false;
continue;
}
markDirtyRecursively(aptOutputDirectory, context, ANDROID_APT_COMPILER);
@@ -27,7 +27,6 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jdom.Element;
@@ -97,15 +96,10 @@ public class AndroidFacetConfiguration implements FacetConfiguration {
}
public void init(@NotNull Module module, @NotNull String baseDirectoryPath) {
String moduleDirPath = AndroidRootUtil.getModuleDirPath(module);
if (moduleDirPath == null) {
final String s = AndroidRootUtil.getPathRelativeToModuleDir(module, baseDirectoryPath);
if (s == null || s.length() == 0) {
return;
}
if (moduleDirPath.equals(baseDirectoryPath)) {
return;
}
String s = FileUtil.getRelativePath(moduleDirPath, baseDirectoryPath, '/');
GEN_FOLDER_RELATIVE_PATH_APT = '/' + s + GEN_FOLDER_RELATIVE_PATH_APT;
GEN_FOLDER_RELATIVE_PATH_AIDL = '/' + s + GEN_FOLDER_RELATIVE_PATH_AIDL;
@@ -514,4 +514,16 @@ public class AndroidRootUtil {
String moduleDirPath = getModuleDirPath(facet.getModule());
return moduleDirPath != null ? FileUtil.toSystemDependentName(moduleDirPath + path) : null;
}
@Nullable
public static String getPathRelativeToModuleDir(@NotNull Module module, @NotNull String path) {
String moduleDirPath = getModuleDirPath(module);
if (moduleDirPath == null) {
return null;
}
if (moduleDirPath.equals(path)) {
return "";
}
return FileUtil.getRelativePath(moduleDirPath, path, '/');
}
}
@@ -389,9 +389,13 @@ public abstract class AndroidFacetImporterBase extends FacetImporter<AndroidFace
final AndroidFacet facet = AndroidUtils.addAndroidFacet(apklibModuleModel, vApklibDir, true);
final AndroidFacetConfiguration configuration = facet.getConfiguration();
configuration.RES_FOLDER_RELATIVE_PATH = '/' + AndroidMavenUtil.APK_LIB_ARTIFACT_RES_DIR;
configuration.LIBS_FOLDER_RELATIVE_PATH = '/' + AndroidMavenUtil.APK_LIB_ARTIFACT_NATIVE_LIBS_DIR;
configuration.MANIFEST_FILE_RELATIVE_PATH = '/' + AndroidMavenUtil.APK_LIB_ARTIFACT_MANIFEST_FILE;
String s = AndroidRootUtil.getPathRelativeToModuleDir(apklibModule, vApklibDir.getPath());
if (s != null) {
s = s.length() > 0 ? '/' + s + '/' : "/";
configuration.RES_FOLDER_RELATIVE_PATH = s + AndroidMavenUtil.APK_LIB_ARTIFACT_RES_DIR;
configuration.LIBS_FOLDER_RELATIVE_PATH = s + AndroidMavenUtil.APK_LIB_ARTIFACT_NATIVE_LIBS_DIR;
configuration.MANIFEST_FILE_RELATIVE_PATH = s + AndroidMavenUtil.APK_LIB_ARTIFACT_MANIFEST_FILE;
}
importSdkAndDependenciesForApklibArtifact(project, rootModelAdapter, apklibModuleModel, modelsProvider, mavenTree, artifact,
mavenProject2ModuleName);
@@ -26,6 +26,10 @@ import org.jetbrains.idea.devkit.dom.IdeaPlugin;
public abstract class IdeaPluginImpl implements IdeaPlugin {
public String getPluginId() {
final XmlTag tag = getXmlTag();
if (tag == null) {
return null;
}
final XmlTag idTag = tag.findFirstSubTag("id");
if (idTag != null) {
return idTag.getValue().getTrimmedText();
@@ -298,6 +298,9 @@ public class GitUtil {
* @return git root for the file
* @throws IllegalArgumentException if the file is not under git
* @throws VcsException if the file is not under git
*
* @deprecated because uses the java.io.File.
* @use GitRepositoryManager#getRepositoryForFile().
*/
public static VirtualFile getGitRoot(final FilePath filePath) throws VcsException {
VirtualFile root = getGitRootOrNull(filePath);
@@ -312,7 +315,11 @@ public class GitUtil {
*
* @param filePath a file path
* @return git root for the file or null if the file is not under git
*
* @deprecated because uses the java.io.File.
* @use GitRepositoryManager#getRepositoryForFile().
*/
@Deprecated
@Nullable
public static VirtualFile getGitRootOrNull(final FilePath filePath) {
return getGitRootOrNull(filePath.getIOFile());
@@ -322,6 +329,11 @@ public class GitUtil {
return file != null && file.exists() && file.isDirectory() && new File(file, DOT_GIT).exists();
}
/**
* @deprecated because uses the java.io.File.
* @use GitRepositoryManager#getRepositoryForFile().
*/
@Deprecated
@Nullable
public static VirtualFile getGitRootOrNull(final File file) {
File root = file;
@@ -337,6 +349,9 @@ public class GitUtil {
* @param file the file to check
* @return git root for the file
* @throws VcsException if the file is not under git
*
* @deprecated because uses the java.io.File.
* @use GitRepositoryManager#getRepositoryForFile().
*/
public static VirtualFile getGitRoot(@NotNull final VirtualFile file) throws VcsException {
final VirtualFile root = gitRootOrNull(file);
@@ -353,6 +368,9 @@ public class GitUtil {
*
* @param file the file to check
* @return git root for the file or null if the file is not not under Git
*
* @deprecated because uses the java.io.File.
* @use GitRepositoryManager#getRepositoryForFile().
*/
@Nullable
public static VirtualFile gitRootOrNull(final VirtualFile file) {
@@ -376,6 +394,9 @@ public class GitUtil {
* @param project the project
* @param vcs the git Vcs
* @return the list of the roots
*
* @deprecated because uses the java.io.File.
* @use GitRepositoryManager#getRepositoryForFile().
*/
@NotNull
public static List<VirtualFile> getGitRoots(Project project, GitVcs vcs) throws VcsException {
@@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsRoot;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import git4idea.GitUtil;
@@ -97,9 +98,13 @@ public class GitRepositoryManagerImpl extends AbstractProjectComponent implement
@Override
@Nullable
public GitRepository getRepositoryForFile(@NotNull VirtualFile file) {
final VirtualFile vcsRoot = myVcsManager.getVcsRootFor(file);
final VcsRoot vcsRoot = myVcsManager.getVcsRootObjectFor(file);
if (vcsRoot == null) { return null; }
return getRepositoryForRoot(vcsRoot);
if (!myVcs.equals(vcsRoot.vcs)) {
LOG.info(String.format("getRepositoryForFile returned non-Git (%s) root for file %s", vcsRoot.vcs.getDisplayName(), file));
return null;
}
return getRepositoryForRoot(vcsRoot.path);
}
@Override
@@ -62,6 +62,11 @@ public class GitChangeProvider implements ChangeProvider {
final ChangelistBuilder builder,
final ProgressIndicator progress,
final ChangeListManagerGate addGate) throws VcsException {
final GitVcs vcs = GitVcs.getInstance(myProject);
if (vcs == null) {
// already disposed or not yet initialized => ignoring
return;
}
final Collection<VirtualFile> affected = dirtyScope.getAffectedContentRootsWithCheck();
if (dirtyScope.getAffectedContentRoots().size() != affected.size()) {
@@ -78,8 +83,10 @@ public class GitChangeProvider implements ChangeProvider {
myFileDocumentManager, myVcsManager);
for (VirtualFile root : roots) {
GitChangesCollector collector = isNewGitChangeProviderAvailable()
? GitNewChangesCollector.collect(myProject, myGit, myChangeListManager, dirtyScope, root)
: GitOldChangesCollector.collect(myProject, myChangeListManager, dirtyScope, root);
? GitNewChangesCollector.collect(myProject, myGit, myChangeListManager, myVcsManager,
vcs, dirtyScope, root)
: GitOldChangesCollector.collect(myProject, myChangeListManager, myVcsManager,
vcs, dirtyScope, root);
holder.changed(collector.getChanges());
for (Change file : collector.getChanges()) {
builder.processChange(file, GitVcs.getKey());
@@ -90,11 +97,10 @@ public class GitChangeProvider implements ChangeProvider {
}
holder.feedBuilder(builder);
}
} catch (VcsException e) {// most probably the error happened because git is not configured
final GitVcs vcs = GitVcs.getInstance(myProject);
if (vcs != null) {
vcs.getExecutableValidator().showNotificationOrThrow(e);
}
}
catch (VcsException e) {
// most probably the error happened because git is not configured
vcs.getExecutableValidator().showNotificationOrThrow(e);
}
}
@@ -17,13 +17,12 @@ package git4idea.status;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.VcsDirtyScope;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.GitUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -37,18 +36,21 @@ import java.util.*;
* @author Kirill Likhodedov
*/
abstract class GitChangesCollector {
protected final Project myProject;
protected final VirtualFile myVcsRoot;
private final ChangeListManager myChangeListManager;
private final VcsDirtyScope myDirtyScope;
@NotNull protected final Project myProject;
@NotNull protected final VirtualFile myVcsRoot;
@NotNull private final VcsDirtyScope myDirtyScope;
@NotNull private final ChangeListManager myChangeListManager;
@NotNull private final ProjectLevelVcsManager myVcsManager;
@NotNull private AbstractVcs myVcs;
GitChangesCollector(@NotNull Project project,
@NotNull ChangeListManager changeListManager,
@NotNull VcsDirtyScope dirtyScope,
@NotNull VirtualFile vcsRoot) {
GitChangesCollector(@NotNull Project project, @NotNull ChangeListManager changeListManager, @NotNull ProjectLevelVcsManager vcsManager,
@NotNull AbstractVcs vcs, @NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) {
myProject = project;
myChangeListManager = changeListManager;
myVcsManager = vcsManager;
myVcs = vcs;
myDirtyScope = dirtyScope;
myVcsRoot = vcsRoot;
}
@@ -80,27 +82,24 @@ abstract class GitChangesCollector {
}
if (includeChanges) {
try {
for (Change c : myChangeListManager.getChangesIn(myVcsRoot)) {
switch (c.getType()) {
case NEW:
case DELETED:
case MOVED:
if (c.getAfterRevision() != null) {
addToPaths(c.getAfterRevision().getFile(), allPaths);
}
if (c.getBeforeRevision() != null) {
addToPaths(c.getBeforeRevision().getFile(), allPaths);
}
case MODIFICATION:
default:
// do nothing
}
for (Change c : myChangeListManager.getChangesIn(myVcsRoot)) {
switch (c.getType()) {
case NEW:
case DELETED:
case MOVED:
ContentRevision afterRevision = c.getAfterRevision();
if (afterRevision != null) {
addToPaths(afterRevision.getFile(), allPaths);
}
ContentRevision beforeRevision = c.getBeforeRevision();
if (beforeRevision != null) {
addToPaths(beforeRevision.getFile(), allPaths);
}
case MODIFICATION:
default:
// do nothing
}
}
catch (Exception t) {
// ignore exceptions
}
}
removeCommonParents(allPaths);
@@ -114,9 +113,9 @@ abstract class GitChangesCollector {
}
protected void addToPaths(FilePath pathToAdd, List<String> paths) {
File file = pathToAdd.getIOFile();
if (myVcsRoot.equals(GitUtil.getGitRootOrNull(file))) {
paths.add(file.getPath());
VcsRoot fileRoot = myVcsManager.getVcsRootObjectFor(pathToAdd);
if (fileRoot != null && fileRoot.vcs != null && fileRoot.vcs.equals(myVcs) && myVcsRoot.equals(fileRoot.path)) {
paths.add(pathToAdd.getPath());
}
}
@@ -18,9 +18,7 @@ package git4idea.status;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ContentRevision;
@@ -70,8 +68,9 @@ class GitNewChangesCollector extends GitChangesCollector {
*/
@NotNull
static GitNewChangesCollector collect(@NotNull Project project, @NotNull Git git, @NotNull ChangeListManager changeListManager,
@NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs,
@NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) throws VcsException {
return new GitNewChangesCollector(project, git, changeListManager, dirtyScope, vcsRoot);
return new GitNewChangesCollector(project, git, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot);
}
@Override
@@ -87,9 +86,10 @@ class GitNewChangesCollector extends GitChangesCollector {
}
private GitNewChangesCollector(@NotNull Project project, @NotNull Git git, @NotNull ChangeListManager changeListManager,
@NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs,
@NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) throws VcsException
{
super(project, changeListManager, dirtyScope, vcsRoot);
super(project, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot);
myGit = git;
myRepository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(vcsRoot);
@@ -16,9 +16,7 @@
package git4idea.status;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ContentRevision;
@@ -104,11 +102,10 @@ class GitOldChangesCollector extends GitChangesCollector {
* This may be lengthy.
*/
@NotNull
static GitOldChangesCollector collect(@NotNull Project project,
@NotNull ChangeListManager changeListManager,
@NotNull VcsDirtyScope dirtyScope,
@NotNull VirtualFile vcsRoot) throws VcsException {
return new GitOldChangesCollector(project, changeListManager, dirtyScope, vcsRoot);
static GitOldChangesCollector collect(@NotNull Project project, @NotNull ChangeListManager changeListManager,
@NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs,
@NotNull VcsDirtyScope dirtyScope, @NotNull VirtualFile vcsRoot) throws VcsException {
return new GitOldChangesCollector(project, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot);
}
@NotNull
@@ -123,11 +120,10 @@ class GitOldChangesCollector extends GitChangesCollector {
return myChanges;
}
private GitOldChangesCollector(@NotNull Project project,
@NotNull ChangeListManager changeListManager,
@NotNull VcsDirtyScope dirtyScope,
private GitOldChangesCollector(@NotNull Project project, @NotNull ChangeListManager changeListManager,
@NotNull ProjectLevelVcsManager vcsManager, @NotNull AbstractVcs vcs, @NotNull VcsDirtyScope dirtyScope,
@NotNull VirtualFile vcsRoot) throws VcsException {
super(project, changeListManager, dirtyScope, vcsRoot);
super(project, changeListManager, vcsManager, vcs, dirtyScope, vcsRoot);
updateIndex();
collectUnmergedAndUnversioned();
collectDiffChanges();
@@ -28,11 +28,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.popup.NotLookupOrSearchCondition;
import java.awt.*;
@@ -85,13 +87,22 @@ public class ShowJavadoc extends AnAction implements IPropertyTableAction {
callback.doWhenProcessed(new Runnable() {
public void run() {
final JBPopup hint =
JBPopup hint =
JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
.setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
.setProject(project)
.setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
.setResizable(true)
.setMovable(true)
.setRequestFocus(true)
.setTitle(DesignerBundle.message("designer.properties.javadoc.title", property.getName()))
.setCancelCallback(new Computable<Boolean>() {
@Override
public Boolean compute() {
Disposer.dispose(component);
return Boolean.TRUE;
}
})
.createPopup();
component.setHint(hint);
Disposer.register(hint, component);
@@ -8,7 +8,7 @@ command.set.property.value=Set Property Value
designer.properties.title=Properties
designer.properties.show.expert=Show expert properties
designer.properties.show.javadoc=Show Documentation
designer.properties.javadoc.title=Documentation for {0} property
designer.properties.javadoc.title=<html><body>Documentation for <b>{0}</b> property</body></html>
designer.properties.restore_default=Restore default value
designer.properties.column1=Property
designer.properties.column2=Value