mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
+7
-4
@@ -125,10 +125,13 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro
|
||||
if (psiVariable == null || !psiVariable.isValid()) return null;
|
||||
final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
|
||||
PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (expression instanceof PsiReferenceExpression && (((PsiReferenceExpression)expression).resolve() == psiVariable ||
|
||||
Comparing.strEqual(psiVariable.getName(),
|
||||
((PsiReferenceExpression)expression).getReferenceName()))) {
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable));
|
||||
if (expression instanceof PsiReferenceExpression) {
|
||||
final String referenceName = ((PsiReferenceExpression)expression).getReferenceName();
|
||||
if (((PsiReferenceExpression)expression).resolve() == psiVariable ||
|
||||
Comparing.strEqual(psiVariable.getName(), referenceName) ||
|
||||
Comparing.strEqual(exprText, referenceName)) {
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable));
|
||||
}
|
||||
}
|
||||
if (expression == null) {
|
||||
expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiExpression.class);
|
||||
|
||||
+2
@@ -287,6 +287,8 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (oItem == null) return itemWrapper == null;
|
||||
if (itemWrapper == null) return false;
|
||||
if (oItem.getDirectory() != itemWrapper.getDirectory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
import static com.intellij.lang.PsiBuilderUtil.nextTokenType;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.*;
|
||||
|
||||
|
||||
public class DeclarationParser {
|
||||
private final ExpressionParser myExpressionParser;
|
||||
private final StatementParser myStatementParser;
|
||||
@@ -417,7 +416,7 @@ public class DeclarationParser {
|
||||
}
|
||||
|
||||
private PsiBuilder.Marker parseMethodFromLeftParenth(final PsiBuilder builder, final PsiBuilder.Marker declaration,
|
||||
final boolean anno, final boolean constructor) {
|
||||
final boolean anno, final boolean constructor) {
|
||||
parseParameterList(builder);
|
||||
|
||||
eatBrackets(builder, constructor, "expected.semicolon");
|
||||
@@ -435,12 +434,14 @@ public class DeclarationParser {
|
||||
|
||||
myReferenceParser.parseReferenceList(builder, JavaTokenType.THROWS_KEYWORD, JavaElementType.THROWS_LIST, JavaTokenType.COMMA);
|
||||
|
||||
if (anno && expect(builder, JavaTokenType.DEFAULT_KEYWORD)) {
|
||||
final boolean hasDefault = expect(builder, JavaTokenType.DEFAULT_KEYWORD);
|
||||
if (hasDefault && anno) {
|
||||
parseAnnotationValue(builder);
|
||||
}
|
||||
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE) {
|
||||
final boolean hasError = tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE;
|
||||
if (hasError) {
|
||||
final PsiBuilder.Marker error = builder.mark();
|
||||
// heuristic: going to next line obviously means method signature is over, starting new method (actually, another one completion hack)
|
||||
final CharSequence text = builder.getOriginalText();
|
||||
@@ -456,10 +457,11 @@ public class DeclarationParser {
|
||||
error.error(JavaErrorMessages.message("expected.lbrace.or.semicolon"));
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.SEMICOLON)) {
|
||||
if (builder.getTokenType() == JavaTokenType.LBRACE) {
|
||||
myStatementParser.parseCodeBlock(builder);
|
||||
}
|
||||
if (hasDefault && !anno && !hasError && builder.getTokenType() != JavaTokenType.LBRACE) {
|
||||
error(builder, JavaErrorMessages.message("expected.lbrace"));
|
||||
}
|
||||
if (!expect(builder, JavaTokenType.SEMICOLON) && builder.getTokenType() == JavaTokenType.LBRACE) {
|
||||
myStatementParser.parseCodeBlock(builder);
|
||||
}
|
||||
|
||||
done(declaration, anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD);
|
||||
|
||||
+2
-7
@@ -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,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.lang.ASTNode;
|
||||
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
@@ -31,8 +30,6 @@ public class AnnotationMethodElement extends MethodElement {
|
||||
public ASTNode findChildByRole(int role) {
|
||||
if (role == ChildRole.ANNOTATION_DEFAULT_VALUE) {
|
||||
return findChildByType(ANNOTATION_MEMBER_VALUE_BIT_SET);
|
||||
} else if (role == ChildRole.DEFAULT_KEYWORD) {
|
||||
return findChildByType(DEFAULT_KEYWORD);
|
||||
}
|
||||
|
||||
return super.findChildByRole(role);
|
||||
@@ -40,9 +37,7 @@ public class AnnotationMethodElement extends MethodElement {
|
||||
|
||||
@Override
|
||||
public int getChildRole(ASTNode child) {
|
||||
if (child.getElementType() == DEFAULT_KEYWORD) {
|
||||
return ChildRole.DEFAULT_KEYWORD;
|
||||
} else if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) {
|
||||
if (ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) {
|
||||
return ChildRole.ANNOTATION_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -112,6 +112,9 @@ public class MethodElement extends CompositeElement implements Constants {
|
||||
|
||||
case ChildRole.CLOSING_SEMICOLON:
|
||||
return TreeUtil.findChildBackward(this, SEMICOLON);
|
||||
|
||||
case ChildRole.DEFAULT_KEYWORD:
|
||||
return findChildByType(DEFAULT_KEYWORD);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,11 +125,6 @@ public class MethodElement extends CompositeElement implements Constants {
|
||||
if (i == JavaDocElementType.DOC_COMMENT) {
|
||||
return getChildRole(child, ChildRole.DOC_COMMENT);
|
||||
}
|
||||
else if (i == C_STYLE_COMMENT || i == END_OF_LINE_COMMENT) {
|
||||
{
|
||||
return ChildRoleBase.NONE;
|
||||
}
|
||||
}
|
||||
else if (i == MODIFIER_LIST) {
|
||||
return ChildRole.MODIFIER_LIST;
|
||||
}
|
||||
@@ -151,6 +149,9 @@ public class MethodElement extends CompositeElement implements Constants {
|
||||
else if (i == SEMICOLON) {
|
||||
return getChildRole(child, ChildRole.CLOSING_SEMICOLON);
|
||||
}
|
||||
else if (i == DEFAULT_KEYWORD) {
|
||||
return ChildRole.DEFAULT_KEYWORD;
|
||||
}
|
||||
else {
|
||||
return ChildRoleBase.NONE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
PsiJavaFile:Extension.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:default('default')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiReturnStatement
|
||||
PsiKeyword:return('return')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiLiteralExpression:42
|
||||
PsiJavaToken:INTEGER_LITERAL('42')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,25 @@
|
||||
PsiJavaFile:Unclosed6.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiAnnotationMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:default('default')
|
||||
PsiErrorElement:Value expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,37 @@
|
||||
PsiJavaFile:Unclosed7.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiAnnotationMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:default('default')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiArrayInitializerMemberValue:{
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiErrorElement:Value expected
|
||||
<empty list>
|
||||
PsiErrorElement:'}' expected
|
||||
<empty list>
|
||||
PsiErrorElement:'{' or ';' expected
|
||||
<empty list>
|
||||
PsiErrorElement:Unexpected token
|
||||
PsiKeyword:return('return')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:INTEGER_LITERAL('42')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unparsed tokens
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,23 @@
|
||||
PsiJavaFile:Unclosed8.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:default('default')
|
||||
PsiErrorElement:'{' or ';' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,25 @@
|
||||
PsiJavaFile:Unclosed9.java
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethod:f
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeParameterList
|
||||
<empty list>
|
||||
PsiTypeElement:void
|
||||
PsiKeyword:void('void')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:f('f')
|
||||
PsiParameterList:()
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiReferenceList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:default('default')
|
||||
PsiErrorElement:'{' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:SEMICOLON(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
@@ -0,0 +1,13 @@
|
||||
public class ATest {
|
||||
public static final String FOO = "foo";
|
||||
public static final String FOO1 = "foo1";
|
||||
|
||||
String m_interval = "";
|
||||
void foo() {
|
||||
if (FOO.equals(<caret>m_interval.substring(1))) {
|
||||
System.out.println(FOO);
|
||||
} else if (FOO1.equals(m_interval.substring(1))) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
public class ATest {
|
||||
public static final String FOO = "foo";
|
||||
public static final String FOO1 = "foo1";
|
||||
|
||||
String m_interval = "";
|
||||
void foo(String m_interval1) {
|
||||
if (FOO.equals(m_interval1.substring(1))) {
|
||||
System.out.println(FOO);
|
||||
} else if (FOO1.equals(m_interval1.substring(1))) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.
|
||||
@@ -20,7 +20,6 @@ import com.intellij.lang.java.parser.JavaParsers;
|
||||
import com.intellij.lang.java.parser.JavaParsingTestCase;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
|
||||
|
||||
public class DeclarationParserTest extends JavaParsingTestCase {
|
||||
public DeclarationParserTest() {
|
||||
super("parser-partial/declarations");
|
||||
@@ -82,11 +81,16 @@ public class DeclarationParserTest extends JavaParsingTestCase {
|
||||
public void testMethodNormal1() { doParserTest("{ void f(); }", false, false); }
|
||||
public void testSemicolons() { doParserTest("{ void f() {}; void g() {}; }", false, false); }
|
||||
public void testUnclosed0() { doParserTest("{ void f() }", false, false); }
|
||||
public void testExtension() { doParserTest("{ int f() default { return 42; } }", false, false); }
|
||||
public void testUnclosed1() { doParserTest("{ void f( }", false, false); }
|
||||
public void testUnclosed2() { doParserTest("{ void f()\n void g(); }", false, false); }
|
||||
public void testUnclosed3() { doParserTest("{ void f(int a }", false, false); }
|
||||
public void testUnclosed4() { doParserTest("{ void f(int a,, }", false, false); }
|
||||
public void testUnclosed5() { doParserTest("{ void f(int a,); }", false, false); }
|
||||
public void testUnclosed6() { doParserTest("{ void f() default ; }", true, false); }
|
||||
public void testUnclosed7() { doParserTest("{ void f() default {return 42;} }", true, false); }
|
||||
public void testUnclosed8() { doParserTest("{ void f() default }", false, false); }
|
||||
public void testUnclosed9() { doParserTest("{ void f() default ; }", false, false); }
|
||||
public void testConstructorBrackets() { doParserTest("{ A() [] { } }", false, false); }
|
||||
public void testVarArgBrackets() { doParserTest("{ void foo(int... x[]); }", false, false); }
|
||||
|
||||
|
||||
@@ -50,6 +50,15 @@ public class InplaceIntroduceParameterTest extends AbstractJavaInplaceIntroduceT
|
||||
});
|
||||
}
|
||||
|
||||
public void testReplaceAll2() throws Exception {
|
||||
doTest(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) {
|
||||
inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testReplaceAllMethodCalls() throws Exception {
|
||||
doTest(new Pass<AbstractInplaceIntroducer>() {
|
||||
@Override
|
||||
|
||||
@@ -63,7 +63,8 @@ public final class LoadTextUtil {
|
||||
char c = bufferArray != null ? bufferArray[src]:buffer.charAt(src);
|
||||
switch (c) {
|
||||
case '\r':
|
||||
buffer.put(dst++, '\n');
|
||||
if(bufferArray != null) bufferArray[dst++] = '\n';
|
||||
else buffer.put(dst++, '\n');
|
||||
crCount++;
|
||||
break;
|
||||
case '\n':
|
||||
@@ -72,12 +73,14 @@ public final class LoadTextUtil {
|
||||
crlfCount++;
|
||||
}
|
||||
else {
|
||||
buffer.put(dst++, '\n');
|
||||
if(bufferArray != null) bufferArray[dst++] = '\n';
|
||||
else buffer.put(dst++, '\n');
|
||||
lfCount++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
buffer.put(dst++, c);
|
||||
if(bufferArray != null) bufferArray[dst++] = c;
|
||||
else buffer.put(dst++, c);
|
||||
break;
|
||||
}
|
||||
prev = c;
|
||||
|
||||
+2
-2
@@ -229,9 +229,9 @@ public class SingleInspectionProfilePanel extends JPanel {
|
||||
List<ScopeToolState> tools = profile.getDefaultStates();
|
||||
for (ScopeToolState state : tools) {
|
||||
final ArrayList<Descriptor> descriptors = new ArrayList<Descriptor>();
|
||||
/* if (state.getLevel() == HighlightDisplayLevel.NON_SWITCHABLE_ERROR) {
|
||||
if (state.getLevel() == HighlightDisplayLevel.NON_SWITCHABLE_ERROR) {
|
||||
continue;
|
||||
}*/
|
||||
}
|
||||
myDescriptors.put(new Descriptor(state, profile), descriptors);
|
||||
final List<ScopeToolState> nonDefaultTools = profile.getNonDefaultTools(state.getTool().getShortName());
|
||||
if (nonDefaultTools != null) {
|
||||
|
||||
+59
-62
@@ -19,6 +19,7 @@ package com.intellij.util.indexing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -28,11 +29,11 @@ import java.util.List;
|
||||
* Date: Dec 20, 2007
|
||||
*/
|
||||
class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>{
|
||||
private final ValueContainerImpl<Value> myAdded;
|
||||
private final ValueContainerImpl<Value> myRemoved;
|
||||
private final TIntHashSet myInvalidated;
|
||||
// there is no volatile as we modify under write lock and read under read lock
|
||||
private ValueContainerImpl<Value> myAdded;
|
||||
private TIntHashSet myInvalidated;
|
||||
private volatile ValueContainerImpl<Value> myMerged;
|
||||
private final Initializer<Value> myInitializer;
|
||||
private volatile ValueContainerImpl<Value> myMerged = null;
|
||||
|
||||
public interface Initializer<T> extends Computable<ValueContainer<T>> {
|
||||
Object getLock();
|
||||
@@ -40,51 +41,48 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
|
||||
|
||||
public ChangeTrackingValueContainer(Initializer<Value> initializer) {
|
||||
myInitializer = initializer;
|
||||
myAdded = new ValueContainerImpl<Value>();
|
||||
myRemoved = new ValueContainerImpl<Value>();
|
||||
myInvalidated = new TIntHashSet(1);
|
||||
}
|
||||
|
||||
//public void log(String op, int id, final Value value) {
|
||||
// System.out.print("@" + mcount + ": ");
|
||||
// System.out.print(op);
|
||||
// System.out.print("(" + id + ")");
|
||||
// System.out.print(" value=" + value + " ");
|
||||
// System.out.print("+[" + myAdded.dumpInputIdMapping() + "], ");
|
||||
// System.out.print("-[" + myRemoved.dumpInputIdMapping() + "], ");
|
||||
// System.out.println("*[" + (myMerged != null ? myMerged.dumpInputIdMapping() : "null") + "] ");
|
||||
//}
|
||||
|
||||
@Override
|
||||
public void addValue(int inputId, Value value) {
|
||||
if (myMerged != null) {
|
||||
myMerged.addValue(inputId, value);
|
||||
ValueContainerImpl<Value> merged = myMerged;
|
||||
if (merged != null) {
|
||||
merged.addValue(inputId, value);
|
||||
}
|
||||
if (!myRemoved.removeValue(inputId, value)) {
|
||||
myAdded.addValue(inputId, value);
|
||||
ValueContainerImpl<Value> added = myAdded;
|
||||
if (added == null) {
|
||||
myAdded = added = new ValueContainerImpl<Value>();
|
||||
}
|
||||
added.addValue(inputId, value); // will flush the changes & caller should ensure exclusiveness to avoid intermediate visibility issues
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAssociatedValue(int inputId) {
|
||||
if (myMerged != null) {
|
||||
myMerged.removeAssociatedValue(inputId);
|
||||
ValueContainerImpl<Value> merged = myMerged;
|
||||
if (merged != null) {
|
||||
merged.removeAssociatedValue(inputId);
|
||||
}
|
||||
myAdded.removeAssociatedValue(inputId);
|
||||
myRemoved.removeAssociatedValue(inputId);
|
||||
myInvalidated.add(inputId);
|
||||
|
||||
ValueContainerImpl<Value> added = myAdded;
|
||||
if (added != null) added.removeAssociatedValue(inputId);
|
||||
|
||||
TIntHashSet invalidated = myInvalidated;
|
||||
if (invalidated == null) {
|
||||
invalidated = new TIntHashSet(1);
|
||||
}
|
||||
invalidated.add(inputId);
|
||||
myInvalidated = invalidated; // volatile write
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeValue(int inputId, Value value) {
|
||||
if (myMerged != null) {
|
||||
myMerged.removeValue(inputId, value);
|
||||
}
|
||||
if (!myAdded.removeValue(inputId, value)) {
|
||||
if (!myInvalidated.contains(inputId)) {
|
||||
myRemoved.addValue(inputId, value);
|
||||
}
|
||||
ValueContainerImpl<Value> merged = myMerged;
|
||||
if (merged != null) {
|
||||
merged.removeValue(inputId, value);
|
||||
}
|
||||
ValueContainerImpl<Value> added = myAdded;
|
||||
if (added != null) added.removeValue(inputId, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -143,28 +141,29 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
|
||||
} else {
|
||||
newMerged = ((ChangeTrackingValueContainer<Value>)fromDisk).getMergedData().copy();
|
||||
}
|
||||
myInvalidated.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int inputId) {
|
||||
newMerged.removeAssociatedValue(inputId);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
myRemoved.forEach(new ContainerAction<Value>() {
|
||||
@Override
|
||||
public boolean perform(final int id, final Value value) {
|
||||
newMerged.removeValue(id, value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
myAdded.forEach(new ContainerAction<Value>() {
|
||||
@Override
|
||||
public boolean perform(final int id, final Value value) {
|
||||
newMerged.removeAssociatedValue(id); // enforcing "one-value-per-file for particular key" invariant
|
||||
newMerged.addValue(id, value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
TIntHashSet invalidated = myInvalidated;
|
||||
if (invalidated != null) {
|
||||
invalidated.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int inputId) {
|
||||
newMerged.removeAssociatedValue(inputId);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ValueContainerImpl<Value> added = myAdded;
|
||||
if (added != null) {
|
||||
added.forEach(new ContainerAction<Value>() {
|
||||
@Override
|
||||
public boolean perform(final int id, final Value value) {
|
||||
newMerged.removeAssociatedValue(id); // enforcing "one-value-per-file for particular key" invariant
|
||||
newMerged.addValue(id, value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
setNeedsCompacting(fromDisk.needsCompacting());
|
||||
|
||||
myMerged = newMerged;
|
||||
@@ -173,18 +172,16 @@ class ChangeTrackingValueContainer<Value> extends UpdatableValueContainer<Value>
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return myAdded.size() > 0 || myRemoved.size() > 0 || !myInvalidated.isEmpty() || needsCompacting();
|
||||
return (myAdded != null && myAdded.size() > 0) ||
|
||||
(myInvalidated != null && !myInvalidated.isEmpty()) ||
|
||||
needsCompacting();
|
||||
}
|
||||
|
||||
public ValueContainer<Value> getAddedDelta() {
|
||||
public @Nullable ValueContainer<Value> getAddedDelta() {
|
||||
return myAdded;
|
||||
}
|
||||
|
||||
public ValueContainer<Value> getRemovedDelta() {
|
||||
return myRemoved;
|
||||
}
|
||||
|
||||
public TIntHashSet getInvalidated() {
|
||||
public @Nullable TIntHashSet getInvalidated() {
|
||||
return myInvalidated;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ public interface IndexStorage<Key, Value> extends Flushable {
|
||||
|
||||
void addValue(Key key, int inputId, Value value) throws StorageException;
|
||||
|
||||
void removeValue(Key key, int inputId, Value value) throws StorageException;
|
||||
|
||||
void removeAllValues(Key key, int inputId) throws StorageException;
|
||||
|
||||
void clear() throws StorageException;
|
||||
|
||||
@@ -237,17 +237,6 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeValue(final Key key, final int inputId, final Value value) throws StorageException {
|
||||
try {
|
||||
myMap.markDirty();
|
||||
read(key).removeValue(inputId, value);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new StorageException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllValues(Key key, int inputId) throws StorageException {
|
||||
try {
|
||||
|
||||
@@ -144,19 +144,6 @@ public class MemoryIndexStorage<Key, Value> implements IndexStorage<Key, Value>
|
||||
myBackendStorage.addValue(key, inputId, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeValue(final Key key, final int inputId, final Value value) throws StorageException {
|
||||
if (myBufferingEnabled.get()) {
|
||||
getMemValueContainer(key).removeValue(inputId, value);
|
||||
return;
|
||||
}
|
||||
final ChangeTrackingValueContainer<Value> valueContainer = myMap.get(key);
|
||||
if (valueContainer != null) {
|
||||
valueContainer.dropMergedData();
|
||||
}
|
||||
myBackendStorage.removeValue(key, inputId, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllValues(Key key, int inputId) throws StorageException {
|
||||
if (myBufferingEnabled.get()) {
|
||||
|
||||
@@ -33,27 +33,37 @@ import java.util.*;
|
||||
class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implements Cloneable{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.ValueContainerImpl");
|
||||
private final static Object myNullValue = new Object();
|
||||
private THashMap<Value, Object> myInputIdMapping;
|
||||
|
||||
public ValueContainerImpl() {
|
||||
// per statistic most maps (80%) has one value
|
||||
myInputIdMapping = new THashMap<Value, Object>(1);
|
||||
}
|
||||
// there is no volatile as we modify under write lock and read under read lock
|
||||
// Most often (80%) we store 0 or one mapping, then we store them in two fields: myInputIdMapping, myInputIdMappingValue
|
||||
// when there are several value mapped, myInputIdMapping is THashMap<Value, Data>, myInputIdMappingValue = null
|
||||
private Object myInputIdMapping;
|
||||
private Object myInputIdMappingValue;
|
||||
|
||||
@Override
|
||||
public void addValue(int inputId, Value value) {
|
||||
value = maskNull(value);
|
||||
final Object input = myInputIdMapping.get(value);
|
||||
final Object input = getInput(value);
|
||||
|
||||
if (input == null) {
|
||||
//idSet = new TIntHashSet(3, 0.98f);
|
||||
myInputIdMapping.put(value, inputId);
|
||||
if (myInputIdMapping != null) {
|
||||
if (!(myInputIdMapping instanceof THashMap)) {
|
||||
Object oldMapping = myInputIdMapping;
|
||||
myInputIdMapping = new THashMap<Value, Object>(2);
|
||||
((THashMap<Value, Object>)myInputIdMapping).put((Value)oldMapping, myInputIdMappingValue);
|
||||
myInputIdMappingValue = null;
|
||||
}
|
||||
((THashMap<Value, Object>)myInputIdMapping).put(value, inputId);
|
||||
} else {
|
||||
myInputIdMapping = value != null ? value:(Value)myNullValue;
|
||||
myInputIdMappingValue = inputId;
|
||||
}
|
||||
}
|
||||
else {
|
||||
final TIntHashSet idSet;
|
||||
if (input instanceof Integer) {
|
||||
idSet = new IdSet(3, 0.98f);
|
||||
idSet.add(((Integer)input).intValue());
|
||||
myInputIdMapping.put(value, idSet);
|
||||
if (!(myInputIdMapping instanceof THashMap)) myInputIdMappingValue = idSet;
|
||||
else ((THashMap<Value, Object>)myInputIdMapping).put(value, idSet);
|
||||
}
|
||||
else {
|
||||
idSet = (TIntHashSet)input;
|
||||
@@ -64,21 +74,19 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return myInputIdMapping.size();
|
||||
return myInputIdMapping != null ? myInputIdMapping instanceof THashMap ? ((THashMap)myInputIdMapping).size(): 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAssociatedValue(int inputId) {
|
||||
if (myInputIdMapping.isEmpty()) return;
|
||||
if (myInputIdMapping == null) return;
|
||||
List<Value> toRemove = null;
|
||||
for (final Iterator<Value> valueIterator = getValueIterator(); valueIterator.hasNext();) {
|
||||
final Value value = valueIterator.next();
|
||||
if (isAssociated(value, inputId)) {
|
||||
if (toRemove == null) toRemove = new SmartList<Value>(value);
|
||||
else {
|
||||
LOG.error("Expected only one value per-inputId");
|
||||
toRemove.add(value);
|
||||
}
|
||||
if (toRemove == null) toRemove = new SmartList<Value>();
|
||||
else LOG.error("Expected only one value per-inputId");
|
||||
toRemove.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,12 +99,11 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
|
||||
@Override
|
||||
public boolean removeValue(int inputId, Value value) {
|
||||
if (myInputIdMapping.isEmpty()) return false; // skipping hash code for value
|
||||
value = maskNull(value);
|
||||
final Object input = myInputIdMapping.get(value);
|
||||
final Object input = getInput(value);
|
||||
if (input == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input instanceof TIntHashSet) {
|
||||
final TIntHashSet idSet = (TIntHashSet)input;
|
||||
final boolean reallyRemoved = idSet.remove(inputId);
|
||||
@@ -112,57 +119,87 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
return false;
|
||||
}
|
||||
}
|
||||
myInputIdMapping.remove(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
private Value maskNull(Value value) {
|
||||
if (value == null) {
|
||||
return (Value)myNullValue;
|
||||
if (!(myInputIdMapping instanceof THashMap)) {
|
||||
myInputIdMapping = null;
|
||||
myInputIdMappingValue = null;
|
||||
} else {
|
||||
THashMap<Value, Object> mapping = (THashMap<Value, Object>)myInputIdMapping;
|
||||
mapping.remove(value);
|
||||
if (mapping.size() == 1) {
|
||||
myInputIdMapping = mapping.keySet().iterator().next();
|
||||
myInputIdMappingValue = mapping.get((Value)myInputIdMapping);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Value> getValueIterator() {
|
||||
if (myInputIdMapping.isEmpty()) {
|
||||
if (myInputIdMapping != null) {
|
||||
if (!(myInputIdMapping instanceof THashMap)) {
|
||||
return new Iterator<Value>() {
|
||||
private Value value = (Value)myInputIdMapping;
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value next() {
|
||||
Value next = value;
|
||||
if (next == myNullValue) next = null;
|
||||
value = null;
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return new Iterator<Value>() {
|
||||
final Iterator<Value> iterator = ((THashMap<Value, Object>)myInputIdMapping).keySet().iterator();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value next() {
|
||||
Value next = iterator.next();
|
||||
if (next == myNullValue) next = null;
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return EmptyIterator.getInstance();
|
||||
}
|
||||
|
||||
return new Iterator<Value>() {
|
||||
final Iterator<Value> iterator = myInputIdMapping.keySet().iterator();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value next() {
|
||||
Value next = iterator.next();
|
||||
if (next == myNullValue) next = null;
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Value> toValueList() {
|
||||
if (myInputIdMapping.isEmpty()) {
|
||||
if (myInputIdMapping == null) {
|
||||
return Collections.emptyList();
|
||||
} else if (myInputIdMapping instanceof THashMap) {
|
||||
return new ArrayList<Value>(((THashMap<Value, Object>)myInputIdMapping).keySet());
|
||||
} else {
|
||||
return new SmartList<Value>((Value)myInputIdMapping);
|
||||
}
|
||||
return new ArrayList<Value>(myInputIdMapping.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssociated(Value value, final int inputId) {
|
||||
value = maskNull(value);
|
||||
final Object input = myInputIdMapping.get(value);
|
||||
final Object input = getInput(value);
|
||||
if (input instanceof TIntHashSet) {
|
||||
return ((TIntHashSet)input).contains(inputId);
|
||||
}
|
||||
@@ -174,7 +211,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
|
||||
@Override
|
||||
public IntPredicate getValueAssociationPredicate(Value value) {
|
||||
final Object input = myInputIdMapping.get(value);
|
||||
final Object input = getInput(value);
|
||||
if (input == null) return EMPTY_PREDICATE;
|
||||
if (input instanceof Integer) {
|
||||
return new IntPredicate() {
|
||||
@@ -196,8 +233,7 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
|
||||
@Override
|
||||
public IntIterator getInputIdsIterator(Value value) {
|
||||
value = maskNull(value);
|
||||
final Object input = myInputIdMapping.get(value);
|
||||
final Object input = getInput(value);
|
||||
final IntIterator it;
|
||||
if (input instanceof TIntHashSet) {
|
||||
it = new IntSetIterator((TIntHashSet)input);
|
||||
@@ -211,11 +247,30 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
return it;
|
||||
}
|
||||
|
||||
private Object getInput(Value value) {
|
||||
if (myInputIdMapping == null) return null;
|
||||
|
||||
value = value != null ? value:(Value)myNullValue;
|
||||
|
||||
if (myInputIdMapping == value || // myNullValue is Object
|
||||
myInputIdMapping.equals(value)
|
||||
) {
|
||||
return myInputIdMappingValue;
|
||||
}
|
||||
|
||||
if (!(myInputIdMapping instanceof THashMap)) return null;
|
||||
return ((THashMap<Value, Object>)myInputIdMapping).get(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueContainerImpl<Value> clone() {
|
||||
try {
|
||||
final ValueContainerImpl clone = (ValueContainerImpl)super.clone();
|
||||
clone.myInputIdMapping = mapCopy(myInputIdMapping);
|
||||
if (myInputIdMapping instanceof THashMap) {
|
||||
clone.myInputIdMapping = mapCopy((THashMap<Value, Object>)myInputIdMapping);
|
||||
} else if (myInputIdMappingValue instanceof TIntHashSet) {
|
||||
clone.myInputIdMappingValue = ((TIntHashSet)myInputIdMappingValue).clone();
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
catch (CloneNotSupportedException e) {
|
||||
@@ -241,18 +296,30 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
};
|
||||
|
||||
public ValueContainerImpl<Value> copy() {
|
||||
final ValueContainerImpl<Value> container = new ValueContainerImpl<Value>();
|
||||
myInputIdMapping.forEachEntry(new TObjectObjectProcedure<Value, Object>() {
|
||||
@Override
|
||||
public boolean execute(Value key, Object val) {
|
||||
if (val instanceof TIntHashSet) {
|
||||
container.myInputIdMapping.put(key, ((TIntHashSet)val).clone());
|
||||
} else {
|
||||
container.myInputIdMapping.put(key, val);
|
||||
ValueContainerImpl<Value> container = new ValueContainerImpl<Value>();
|
||||
|
||||
if (myInputIdMapping instanceof THashMap) {
|
||||
final THashMap<Value, Object> mapping = (THashMap<Value, Object>)myInputIdMapping;
|
||||
final THashMap<Value, Object> newMapping = new THashMap<Value, Object>(mapping.size());
|
||||
container.myInputIdMapping = newMapping;
|
||||
|
||||
mapping.forEachEntry(new TObjectObjectProcedure<Value, Object>() {
|
||||
@Override
|
||||
public boolean execute(Value key, Object val) {
|
||||
if (val instanceof TIntHashSet) {
|
||||
newMapping.put(key, ((TIntHashSet)val).clone());
|
||||
}
|
||||
else {
|
||||
newMapping.put(key, val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
container.myInputIdMapping = myInputIdMapping;
|
||||
container.myInputIdMappingValue = myInputIdMappingValue instanceof TIntHashSet ?
|
||||
((TIntHashSet)myInputIdMappingValue).clone():myInputIdMappingValue;
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
@@ -271,12 +338,9 @@ class ValueContainerImpl<Value> extends UpdatableValueContainer<Value> implement
|
||||
|
||||
@Override
|
||||
public int next() {
|
||||
try {
|
||||
return myValue;
|
||||
}
|
||||
finally {
|
||||
myValueRead = true;
|
||||
}
|
||||
int next = myValue;
|
||||
myValueRead = true;
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,18 +38,14 @@ class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContaine
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
final DataOutputStream _out = new DataOutputStream(bytes);
|
||||
final TIntHashSet set = valueContainer.getInvalidated();
|
||||
if (set.size() > 0) {
|
||||
if (set != null && set.size() > 0) {
|
||||
for (int inputId : set.toArray()) {
|
||||
ValueContainerExternalizer.saveInvalidateCommand(_out, inputId);
|
||||
}
|
||||
}
|
||||
final ValueContainer<Value> toRemove = valueContainer.getRemovedDelta();
|
||||
if (toRemove.size() > 0) {
|
||||
myValueContainerExternalizer.saveAsRemoved(_out, toRemove);
|
||||
}
|
||||
|
||||
final ValueContainer<Value> toAppend = valueContainer.getAddedDelta();
|
||||
if (toAppend.size() > 0) {
|
||||
if (toAppend != null && toAppend.size() > 0) {
|
||||
myValueContainerExternalizer.save(_out, toAppend);
|
||||
}
|
||||
|
||||
@@ -76,18 +72,14 @@ class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContaine
|
||||
|
||||
@Override
|
||||
public void save(final DataOutput out, @NotNull final ValueContainer<T> container) throws IOException {
|
||||
saveImpl(out, container, false);
|
||||
}
|
||||
|
||||
public void saveAsRemoved(final DataOutput out, @NotNull final ValueContainer<T> container) throws IOException {
|
||||
saveImpl(out, container, true);
|
||||
saveImpl(out, container);
|
||||
}
|
||||
|
||||
public static void saveInvalidateCommand(final DataOutput out, int inputId) throws IOException {
|
||||
DataInputOutputUtil.writeSINT(out, -inputId);
|
||||
}
|
||||
|
||||
private void saveImpl(final DataOutput out, @NotNull final ValueContainer<T> container, final boolean asRemovedData) throws IOException {
|
||||
private void saveImpl(final DataOutput out, @NotNull final ValueContainer<T> container) throws IOException {
|
||||
DataInputOutputUtil.writeSINT(out, container.size());
|
||||
for (final Iterator<T> valueIterator = container.getValueIterator(); valueIterator.hasNext();) {
|
||||
final T value = valueIterator.next();
|
||||
@@ -98,7 +90,7 @@ class ValueContainerMap<Key, Value> extends PersistentHashMap<Key, ValueContaine
|
||||
DataInputOutputUtil.writeSINT(out, ids.size());
|
||||
while (ids.hasNext()) {
|
||||
final int id = ids.next();
|
||||
DataInputOutputUtil.writeSINT(out, asRemovedData ? -id : id);
|
||||
DataInputOutputUtil.writeSINT(out, id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.util.ImageLoader;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -44,11 +45,12 @@ public class HighlightDisplayLevel {
|
||||
public static final HighlightDisplayLevel INFO = new HighlightDisplayLevel(HighlightSeverity.INFO, DO_NOT_SHOW.getIcon());
|
||||
public static final HighlightDisplayLevel WEAK_WARNING = new HighlightDisplayLevel(HighlightSeverity.WEAK_WARNING, DO_NOT_SHOW.getIcon());
|
||||
|
||||
public static final HighlightDisplayLevel NON_SWITCHABLE_ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR, createIconByMask(CodeInsightColors.ERRORS_ATTRIBUTES));
|
||||
public static final HighlightDisplayLevel NON_SWITCHABLE_ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR);
|
||||
|
||||
private Icon myIcon;
|
||||
private final HighlightSeverity mySeverity;
|
||||
|
||||
@Nullable
|
||||
public static HighlightDisplayLevel find(String name) {
|
||||
for (Map.Entry<HighlightSeverity, HighlightDisplayLevel> entry : ourMap.entrySet()) {
|
||||
HighlightSeverity severity = entry.getKey();
|
||||
@@ -70,6 +72,11 @@ public class HighlightDisplayLevel {
|
||||
ourMap.put(mySeverity, this);
|
||||
}
|
||||
|
||||
public HighlightDisplayLevel(HighlightSeverity severity) {
|
||||
mySeverity = severity;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return mySeverity.toString();
|
||||
}
|
||||
|
||||
@@ -190,6 +190,8 @@ public class DualView extends JPanel {
|
||||
if (myCurrentView instanceof JBTable) {
|
||||
((JBTable)myCurrentView).setStriped(true);
|
||||
}
|
||||
final int row = myCurrentView.getSelectedRow();
|
||||
myCurrentView.scrollRectToVisible(myCurrentView.getCellRect(row, 0, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +306,7 @@ public class DualView extends JPanel {
|
||||
SelectionProvider visibleTable = (SelectionProvider)getVisibleTable();
|
||||
Collection selection = visibleTable.getSelection();
|
||||
for (Iterator each = selection.iterator(); each.hasNext();) {
|
||||
result.add((Object)each.next());
|
||||
result.add(each.next());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -579,8 +579,6 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
|
||||
});
|
||||
|
||||
myDualView.requestFocus();
|
||||
myDualView.setSelectionInterval(0, 0);
|
||||
|
||||
|
||||
myDualView.addListSelectionListener(new ListSelectionListener() {
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
|
||||
+3
@@ -43,10 +43,13 @@ public class RelativeLayoutOperation extends AbstractEditOperation {
|
||||
private SnapPointFeedbackHost mySnapFeedback;
|
||||
private TextFeedback myHorizontalTextFeedback;
|
||||
private TextFeedback myVerticalTextFeedback;
|
||||
|
||||
private Rectangle myContainerBounds;
|
||||
private Rectangle myBounds;
|
||||
|
||||
private List<SnapPoint> myHorizontalPoints;
|
||||
private List<SnapPoint> myVerticalPoints;
|
||||
|
||||
private SnapPoint myHorizontalPoint;
|
||||
private SnapPoint myVerticalPoint;
|
||||
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.designSurface.layout.actions;
|
||||
|
||||
import com.intellij.android.designer.designSurface.layout.relative.SnapPoint;
|
||||
import com.intellij.android.designer.designSurface.layout.relative.SnapPointFeedbackHost;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.designer.designSurface.EditOperation;
|
||||
import com.intellij.designer.designSurface.OperationContext;
|
||||
import com.intellij.designer.designSurface.feedbacks.RectangleFeedback;
|
||||
import com.intellij.designer.designSurface.feedbacks.TextFeedback;
|
||||
import com.intellij.designer.designSurface.selection.DirectionResizePoint;
|
||||
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.designer.utils.Position;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class RelativeLayoutResizeOperation implements EditOperation {
|
||||
public static final String TYPE = "relative_resize";
|
||||
|
||||
private final OperationContext myContext;
|
||||
private RadViewComponent myComponent;
|
||||
|
||||
private RectangleFeedback myFeedback;
|
||||
private SnapPointFeedbackHost mySnapFeedback;
|
||||
private TextFeedback myHorizontalTextFeedback;
|
||||
private TextFeedback myVerticalTextFeedback;
|
||||
|
||||
private Rectangle myContainerBounds;
|
||||
private Rectangle myBounds;
|
||||
|
||||
private List<SnapPoint> myHorizontalPoints;
|
||||
private List<SnapPoint> myVerticalPoints;
|
||||
|
||||
private SnapPoint myHorizontalPoint;
|
||||
private SnapPoint myVerticalPoint;
|
||||
|
||||
public RelativeLayoutResizeOperation(OperationContext context) {
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponent(RadComponent component) {
|
||||
myComponent = (RadViewComponent)component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponents(List<RadComponent> components) {
|
||||
}
|
||||
|
||||
private void createFeedback() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFeedback() {
|
||||
createFeedback();
|
||||
// TODO: Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eraseFeedback() {
|
||||
// TODO: Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
// TODO: Auto-generated method stub
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ResizePoint
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void points(ResizeSelectionDecorator decorator) {
|
||||
decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.NORTH_WEST, TYPE,
|
||||
"Change layout:width x layout:height, top x left alignment"));
|
||||
decorator
|
||||
.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.NORTH, TYPE, "Change layout:height, top alignment"));
|
||||
decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.NORTH_EAST, TYPE,
|
||||
"Change layout:width x layout:height, top x right alignment"));
|
||||
decorator
|
||||
.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.EAST, TYPE, "Change layout:width, right alignment"));
|
||||
decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.SOUTH_EAST, TYPE,
|
||||
"Change layout:width x layout:height, bottom x right alignment"));
|
||||
decorator.addPoint(
|
||||
new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.SOUTH, TYPE, "Change layout:height, bottom alignment"));
|
||||
decorator.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.SOUTH_WEST, TYPE,
|
||||
"Change layout:width x layout:height, bottom x left alignment"));
|
||||
decorator
|
||||
.addPoint(new DirectionResizePoint(ResizeOperation.blue, Color.black, Position.WEST, TYPE, "Change layout:width, left alignment"));
|
||||
}
|
||||
}
|
||||
+21
-15
@@ -41,7 +41,7 @@ import java.util.List;
|
||||
public class ResizeOperation implements EditOperation {
|
||||
public static final String TYPE = "resize_children";
|
||||
|
||||
private final static Color blue = new Color(0, 50, 255);
|
||||
public final static Color blue = new Color(0, 50, 255);
|
||||
private static final int SNAP_DELTA = 4;
|
||||
private static final int WRAP_CONTENT = 0 << 30;
|
||||
|
||||
@@ -65,20 +65,6 @@ public class ResizeOperation implements EditOperation {
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
public static void points(ResizeSelectionDecorator decorator) {
|
||||
width(decorator);
|
||||
height(decorator);
|
||||
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH_EAST, TYPE, "Change layout:width x layout:height"));
|
||||
}
|
||||
|
||||
public static void width(ResizeSelectionDecorator decorator) {
|
||||
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.EAST, TYPE, "Change layout:width"));
|
||||
}
|
||||
|
||||
public static void height(ResizeSelectionDecorator decorator) {
|
||||
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH, TYPE, "Change layout:height"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponent(RadComponent component) {
|
||||
myComponent = (RadViewComponent)component;
|
||||
@@ -338,4 +324,24 @@ public class ResizeOperation implements EditOperation {
|
||||
}
|
||||
return Integer.toString(size) + "dp";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ResizePoint
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void points(ResizeSelectionDecorator decorator) {
|
||||
width(decorator);
|
||||
height(decorator);
|
||||
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH_EAST, TYPE, "Change layout:width x layout:height"));
|
||||
}
|
||||
|
||||
public static void width(ResizeSelectionDecorator decorator) {
|
||||
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.EAST, TYPE, "Change layout:width"));
|
||||
}
|
||||
|
||||
public static void height(ResizeSelectionDecorator decorator) {
|
||||
decorator.addPoint(new DirectionResizePoint(blue, Color.black, Position.SOUTH, TYPE, "Change layout:height"));
|
||||
}
|
||||
}
|
||||
+34
-9
@@ -17,11 +17,14 @@ package com.intellij.android.designer.model.layout.relative;
|
||||
|
||||
import com.intellij.android.designer.designSurface.TreeDropToOperation;
|
||||
import com.intellij.android.designer.designSurface.layout.RelativeLayoutOperation;
|
||||
import com.intellij.android.designer.designSurface.layout.actions.RelativeLayoutResizeOperation;
|
||||
import com.intellij.android.designer.designSurface.layout.relative.RelativeDecorator;
|
||||
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.designer.componentTree.TreeEditOperation;
|
||||
import com.intellij.designer.designSurface.*;
|
||||
import com.intellij.designer.designSurface.selection.ResizeSelectionDecorator;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.designer.propertyTable.Property;
|
||||
import com.intellij.designer.propertyTable.PropertyTable;
|
||||
@@ -29,6 +32,8 @@ import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -38,6 +43,7 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD
|
||||
private static final String[] LAYOUT_PARAMS = {"RelativeLayout_Layout", "ViewGroup_MarginLayout"};
|
||||
|
||||
private RelativeDecorator myRelativeDecorator;
|
||||
private ResizeSelectionDecorator mySelectionDecorator;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -86,15 +92,12 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD
|
||||
}
|
||||
return new RelativeLayoutOperation(myContainer, context);
|
||||
}
|
||||
// XXX
|
||||
if (context.is(RelativeLayoutResizeOperation.TYPE)) {
|
||||
return new RelativeLayoutResizeOperation(context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeComponentFromContainer(RadComponent component) {
|
||||
// TODO: Auto-generated method stub
|
||||
}
|
||||
|
||||
private RelativeDecorator getRelativeDecorator() {
|
||||
if (myRelativeDecorator == null) {
|
||||
myRelativeDecorator = new RelativeDecorator(myContainer);
|
||||
@@ -117,7 +120,11 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD
|
||||
|
||||
@Override
|
||||
public ComponentDecorator getChildSelectionDecorator(RadComponent component, List<RadComponent> selection) {
|
||||
return super.getChildSelectionDecorator(component, selection); // TODO: Auto-generated method stub
|
||||
if (mySelectionDecorator == null) {
|
||||
mySelectionDecorator = new ResizeSelectionDecorator(Color.red, 1);
|
||||
RelativeLayoutResizeOperation.points(mySelectionDecorator);
|
||||
}
|
||||
return mySelectionDecorator;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -131,7 +138,16 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD
|
||||
DefaultActionGroup actionGroup,
|
||||
JComponent shortcuts,
|
||||
List<RadComponent> selection) {
|
||||
super.addContainerSelectionActions(designer, actionGroup, shortcuts, selection); // TODO: Auto-generated method stub
|
||||
if (selection.get(selection.size() - 1) != myContainer) {
|
||||
return;
|
||||
}
|
||||
for (RadComponent component : selection) {
|
||||
if (!(component.getLayout() instanceof RadRelativeLayout)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
actionGroup.add(new AllGravityAction(designer, Arrays.asList(myContainer)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -139,6 +155,15 @@ public class RadRelativeLayout extends RadViewLayoutWithData implements ILayoutD
|
||||
DefaultActionGroup actionGroup,
|
||||
JComponent shortcuts,
|
||||
List<RadComponent> selection) {
|
||||
super.addSelectionActions(designer, actionGroup, shortcuts, selection); // TODO: Auto-generated method stub
|
||||
if (selection.get(selection.size() - 1).getParent() != myContainer) {
|
||||
return;
|
||||
}
|
||||
for (RadComponent component : selection) {
|
||||
if (!(component.getParent() instanceof RadRelativeLayoutComponent)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
actionGroup.add(new AllGravityAction(designer, Arrays.asList(myContainer)));
|
||||
}
|
||||
}
|
||||
+7
-20
@@ -21,8 +21,7 @@ import com.intellij.cvsSupport2.application.CvsEntriesManager;
|
||||
import com.intellij.cvsSupport2.changeBrowser.CvsChangeList;
|
||||
import com.intellij.cvsSupport2.connections.CvsConnectionSettings;
|
||||
import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutor;
|
||||
import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback;
|
||||
import com.intellij.cvsSupport2.cvsExecution.ModalityContext;
|
||||
import com.intellij.cvsSupport2.cvsExecution.DefaultCvsOperationExecutorCallback;
|
||||
import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler;
|
||||
import com.intellij.cvsSupport2.cvsoperations.cvsLog.LocalPathIndifferentLogOperation;
|
||||
import com.intellij.cvsSupport2.cvsoperations.cvsTagOrBranch.ui.TagsPanel;
|
||||
@@ -226,13 +225,8 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
|
||||
final CvsOperationExecutor executor = new CvsOperationExecutor(myProject);
|
||||
final ArrayList<VcsFileRevision> result = new ArrayList<VcsFileRevision>();
|
||||
executor.performActionSync(new CommandCvsHandler(CvsBundle.message("operation.name.load.file.content"), logOperation),
|
||||
new CvsOperationExecutorCallback() {
|
||||
public void executionFinished(boolean successfully) {
|
||||
}
|
||||
|
||||
public void executeInProgressAfterAction(ModalityContext modalityContext) {
|
||||
}
|
||||
|
||||
new DefaultCvsOperationExecutorCallback() {
|
||||
@Override
|
||||
public void executionFinishedSuccessfully() {
|
||||
final CvsConnectionSettings env = CvsEntriesManager.getInstance()
|
||||
.getCvsConnectionSettingsFor(filePath.getVirtualFileParent());
|
||||
@@ -246,7 +240,7 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
|
||||
}
|
||||
}
|
||||
});
|
||||
Collections.sort(result, VcsFileRevisionComparator.INSTANCE);
|
||||
Collections.sort(result, Collections.reverseOrder(VcsFileRevisionComparator.INSTANCE));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -266,12 +260,12 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
|
||||
}
|
||||
|
||||
public List<TreeItem<VcsFileRevision>> createTreeOn(List<VcsFileRevision> allRevisions) {
|
||||
final List<VcsFileRevision> sortedRevisions = sortRevisions(allRevisions);
|
||||
Collections.sort(allRevisions, VcsFileRevisionComparator.INSTANCE);
|
||||
|
||||
final List<TreeItem<VcsFileRevision>> result = new ArrayList<TreeItem<VcsFileRevision>>();
|
||||
|
||||
TreeItem<VcsFileRevision> prevRevision = null;
|
||||
for (final VcsFileRevision sortedRevision : sortedRevisions) {
|
||||
for (final VcsFileRevision sortedRevision : allRevisions) {
|
||||
final CvsFileRevisionImpl cvsFileRevision = (CvsFileRevisionImpl)sortedRevision;
|
||||
final TreeItem<VcsFileRevision> treeItem = new TreeItem<VcsFileRevision>(cvsFileRevision);
|
||||
final TreeItem<VcsFileRevision> commonParent = getCommonParent(prevRevision, treeItem);
|
||||
@@ -281,12 +275,10 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
|
||||
else {
|
||||
result.add(treeItem);
|
||||
}
|
||||
|
||||
prevRevision = treeItem;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -304,11 +296,6 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
|
||||
final CvsFileRevisionImpl data = (CvsFileRevisionImpl)cvsFileRevision.getData();
|
||||
return data.getRevisionNumber().asString().startsWith(prevData.getRevisionNumber().asString());
|
||||
}
|
||||
|
||||
private static List<VcsFileRevision> sortRevisions(List<VcsFileRevision> revisionsList) {
|
||||
Collections.sort(revisionsList, VcsFileRevisionComparator.INSTANCE);
|
||||
return revisionsList;
|
||||
}
|
||||
}
|
||||
|
||||
private static class VcsFileRevisionComparator implements Comparator<VcsFileRevision> {
|
||||
@@ -318,7 +305,7 @@ public class CvsHistoryProvider implements VcsHistoryProvider {
|
||||
private VcsFileRevisionComparator() {}
|
||||
|
||||
public int compare(VcsFileRevision rev1, VcsFileRevision rev2) {
|
||||
return VcsHistoryUtil.compare(rev2, rev1);
|
||||
return VcsHistoryUtil.compare(rev1, rev2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user