Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2014-10-06 15:33:18 +02:00
64 changed files with 892 additions and 240 deletions
+1 -1
View File
@@ -1 +1 @@
138.SNAPSHOT
140.SNAPSHOT
+1
View File
@@ -12,6 +12,7 @@
<fileset dir="${project.home}/build/lib/jps">
<include name="*.jar"/>
</fileset>
<fileset file="${project.home}/jps/lib/optimizedFileManager.jar"/>
<fileset dir="${project.home}/build/kotlinc/jps" erroronmissingdir="false">
<include name="*.jar"/>
</fileset>
+1
View File
@@ -280,6 +280,7 @@ libraryLicense(name: "ReflectASM", libraryName: "reflectasm-1.0.7.jar", version:
libraryLicense(name: "Objenesis", libraryName: "objenesis-1.2.jar", version: "1.2", license: "Apache 2.0", url: "http://objenesis.org/", licenseUrl: "http://apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "EditorConfig Java Core", libraryName: "editorconfig-core-java.jar", version: "1.0", license: "Apache 2.0", url: "https://github.com/editorconfig/editorconfig-core-java/", licenseUrl: "https://github.com/editorconfig/editorconfig-core-java/blob/master/LICENSE")
libraryLicense(name: "Fest", libraryName: "fest", version: "", license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://code.google.com/p/fest/")
libraryLicense(name: "Gherkin", libraryName: "Gherkin", version: "2.12.2", license: "MIT", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://github.com/cucumber/gherkin")
jetbrainsLibrary("Coverage")
jetbrainsLibrary("CoverageReport")
jetbrainsLibrary("JPS")
@@ -16,6 +16,7 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiUtil;
@@ -104,7 +105,25 @@ public class RemoveUnusedVariableUtil {
sideEffects.add(element);
return true;
}
PsiElement[] children = element.getChildren();
IElementType tokenType = null;
PsiExpression operand = null;
if (element instanceof PsiPrefixExpression) {
operand = ((PsiPrefixExpression)element).getOperand();
tokenType = ((PsiPrefixExpression)element).getOperationTokenType();
} else if (element instanceof PsiPostfixExpression) {
operand = ((PsiPostfixExpression)element).getOperand();
tokenType = ((PsiPostfixExpression)element).getOperationTokenType();
}
if (JavaTokenType.MINUSMINUS.equals(tokenType) || JavaTokenType.PLUSPLUS.equals(tokenType)) {
operand = PsiUtil.deparenthesizeExpression(operand);
if (!(operand instanceof PsiReferenceExpression && ((PsiReferenceExpression)operand).resolve() == variable)) {
sideEffects.add(element);
return true;
}
}
PsiElement[] children = element.getChildren();
for (PsiElement child : children) {
checkSideEffects(child, variable, sideEffects);
@@ -203,8 +203,10 @@ public class Java15APIUsageInspectionBase extends BaseJavaBatchLocalInspectionTo
@Override public void visitClass(PsiClass aClass) {
// Don't go into classes (anonymous, locals).
if (!aClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
final LanguageLevel effectiveLanguageLevel = getEffectiveLanguageLevel(ModuleUtilCore.findModuleForPsiElement(aClass));
if (!effectiveLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) &&
final Module module = ModuleUtilCore.findModuleForPsiElement(aClass);
final LanguageLevel effectiveLanguageLevel = module != null ? getEffectiveLanguageLevel(module) : null;
if (effectiveLanguageLevel != null &&
!effectiveLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8) &&
JavaVersionService.getInstance().getJavaSdkVersion(aClass).isAtLeast(JavaSdkVersion.JDK_1_8)) {
final List<PsiMethod> methods = new ArrayList<PsiMethod>();
for (HierarchicalMethodSignature methodSignature : aClass.getVisibleSignatures()) {
@@ -375,8 +375,9 @@ public class UncheckedWarningLocalInspectionBase extends BaseJavaBatchLocalInspe
public void visitReturnStatement(PsiReturnStatement statement) {
super.visitReturnStatement(statement);
if (IGNORE_UNCHECKED_ASSIGNMENT) return;
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(statement, PsiLambdaExpression.class);
final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
if (method != null) {
if (method != null && (lambdaExpression == null || PsiTreeUtil.isAncestor(lambdaExpression, method, true))) {
final PsiType returnType = method.getReturnType();
if (returnType != null && returnType != PsiType.VOID) {
final PsiExpression returnValue = statement.getReturnValue();
@@ -28,7 +28,8 @@ import com.intellij.psi.tree.TokenSet;
public class JavaPairedBraceMatcher extends PairedBraceMatcherAdapter {
private static final TokenSet TYPE_TOKENS =
TokenSet.orSet(StdTokenSets.WHITE_SPACE_OR_COMMENT_BIT_SET,
TokenSet.create(JavaTokenType.IDENTIFIER, JavaTokenType.COMMA,
TokenSet.create(JavaTokenType.IDENTIFIER, JavaTokenType.COMMA,
JavaTokenType.AT,//anno
JavaTokenType.RBRACKET, JavaTokenType.LBRACKET, //arrays
JavaTokenType.QUEST, JavaTokenType.EXTENDS_KEYWORD, JavaTokenType.SUPER_KEYWORD));//wildcards
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -31,7 +31,6 @@ import org.jetbrains.annotations.NotNull;
* @author ven
*/
public class AddOverrideAnnotationAction implements IntentionAction {
private static final String JAVA_LANG_OVERRIDE = "java.lang.Override";
@Override
@NotNull
@@ -51,11 +50,11 @@ public class AddOverrideAnnotationAction implements IntentionAction {
if (!file.getManager().isInProject(file)) return false;
PsiMethod method = findMethod(file, editor.getCaretModel().getOffset());
if (method == null) return false;
if (method.getModifierList().findAnnotation(JAVA_LANG_OVERRIDE) != null) return false;
if (method.getModifierList().findAnnotation(CommonClassNames.JAVA_LANG_OVERRIDE) != null) return false;
PsiMethod[] superMethods = method.findSuperMethods();
for (PsiMethod superMethod : superMethods) {
if (!superMethod.hasModifierProperty(PsiModifier.ABSTRACT)
&& new AddAnnotationFix(JAVA_LANG_OVERRIDE, method).isAvailable(project, editor, file)) {
&& new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method).isAvailable(project, editor, file)) {
return true;
}
}
@@ -67,7 +66,7 @@ public class AddOverrideAnnotationAction implements IntentionAction {
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
PsiMethod method = findMethod(file, editor.getCaretModel().getOffset());
if (method != null) {
new AddAnnotationFix(JAVA_LANG_OVERRIDE, method).invoke(project, editor, file);
new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method).invoke(project, editor, file);
}
}
@@ -56,13 +56,11 @@ public class InvertBooleanHandler implements RefactoringActionHandler {
return;
}
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, var)) return;
if (var instanceof PsiParameter && ((PsiParameter)var).getDeclarationScope() instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)((PsiParameter)var).getDeclarationScope();
final PsiMethod superMethod = SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor"));
if (superMethod != null) {
var = superMethod.getParameterList().getParameters()[method.getParameterList().getParameterIndex((PsiParameter)var)];
}
if (superMethod == null) return;
var = superMethod.getParameterList().getParameters()[method.getParameterList().getParameterIndex((PsiParameter)var)];
}
new InvertBooleanDialog(var).show();
@@ -87,9 +85,8 @@ public class InvertBooleanHandler implements RefactoringActionHandler {
}
final PsiMethod superMethod = SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor"));
if (superMethod != null) method = superMethod;
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, method)) return;
if (superMethod == null) return;
method = superMethod;
new InvertBooleanDialog(method).show();
}
@@ -0,0 +1,65 @@
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
class Test {
private Repository repository = null;
public Stream<Person> test() {
return repository.all()
.flatMap(foo -> {
class AB {
List<String> a() {
return <warning descr="Unchecked assignment: 'java.util.ArrayList' to 'java.util.List<java.lang.String>'">new ArrayList()</warning>;
}
}
AB ab = new AB();
System.out.println(ab);
if (foo != null) {
return repository.update();
}
return Stream.empty();
})
.map(UpdateResult::getPerson);
}
public static class Repository {
public Stream<Person> all() {
return Stream.empty();
}
public Stream<UpdateResult> update() {
return Stream.empty();
}
}
public static class Person {
}
public static class UpdateResult {
private final Person person;
private final Object metadata;
public UpdateResult(Person person, Object metadata) {
this.person = person;
this.metadata = metadata;
}
public Person getPerson() {
return person;
}
public Object getMetadata() {
return metadata;
}
}
}
@@ -762,6 +762,10 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
public void testIDEA78402() { doTest(); }
public void testUncheckedWarningInsideLambdaReturnStatement() throws Exception {
doTest(true);
}
private void doTest() {
doTest(false);
}
@@ -24,10 +24,10 @@ public class JavaBraceMatcherTest extends LightCodeInsightFixtureTestCase {
public void testGenerics() {
myFixture.configureByText("a.java", "import java.util.ArrayList;" +
"class A {" +
" ArrayList<caret><? extends String[]> f;" +
" ArrayList<caret><? extends @Anno String[]> f;" +
"}");
final int offset = BraceMatchingUtil.getMatchedBraceOffset(myFixture.getEditor(), true, myFixture.getFile());
assertEquals(66, offset);
assertEquals(72, offset);
}
public void testBrokenText() {
@@ -86,7 +86,12 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
private static final Comparator<HighlightVisitor> VISITOR_ORDER_COMPARATOR = new Comparator<HighlightVisitor>() {
@Override
public int compare(final HighlightVisitor o1, final HighlightVisitor o2) {
return o1.order() - o2.order();
int delta = o1.order() - o2.order();
if (delta != 0) return delta;
if (o1.getClass() == o2.getClass()) {
LOG.error("Duplicate visitors registered: "+o1 +" and "+o2 + " ("+o1.getClass()+")");
}
return 0;
}
};
protected final EditorColorsScheme myGlobalScheme;
@@ -87,8 +87,7 @@ public abstract class DvcsBranchPopup<Repo extends Repository> {
@NotNull
private String createPopupTitle(@NotNull Repo currentRepository) {
String title = myVcs.getDisplayName() + " Branches";
if (myRepositoryManager.moreThanOneRoot() &&
(myMultiRootBranchConfig.diverged() || myVcsSettings.getSyncSetting() == DvcsSyncSettings.Value.DONT_SYNC)) {
if (myRepositoryManager.moreThanOneRoot() && myVcsSettings.getSyncSetting() == DvcsSyncSettings.Value.DONT_SYNC) {
title += " in " + DvcsUtil.getShortRepositoryName(currentRepository);
}
return title;
@@ -918,7 +918,15 @@ public class CommonCodeStyleSettings {
@Override
public void writeExternal(Element element) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, element, new DifferenceFilter<IndentOptions>(this, new IndentOptions()));
DefaultJDOMExternalizer.writeExternal(this, element, new DefaultJDOMExternalizer.JDOMFilter() {
@Override
public boolean isAccept(@NotNull Field field) {
if ("KEEP_INDENTS_ON_EMPTY_LINES".equals(field.getName())) {
return KEEP_INDENTS_ON_EMPTY_LINES;
}
return true;
}
});
}
public void serialize(Element indentOptionsElement, final IndentOptions defaultOptions) {
@@ -205,7 +205,7 @@ public class ArrangementUtil {
public void visit(@NotNull ArrangementAtomMatchCondition condition) {
ArrangementSettingsToken type = condition.getType();
Object value = condition.getValue();
result.put(condition.getType(), type.equals(value) ? null : value);
result.put(condition.getType(), type.equals(value) ? null : value);
}
@Override
@@ -260,10 +260,10 @@ public class ArrangementUtil {
@Nullable
public static ArrangementEntryMatcher buildMatcher(@NotNull ArrangementAtomMatchCondition condition) {
if (StdArrangementTokenType.ENTRY_TYPE.is(condition.getType())) {
return new ByTypeArrangementEntryMatcher(condition.getType());
return new ByTypeArrangementEntryMatcher(condition);
}
else if (StdArrangementTokenType.MODIFIER.is(condition.getType())) {
return new ByModifierArrangementEntryMatcher(condition.getType());
return new ByModifierArrangementEntryMatcher(condition);
}
else if (StdArrangementTokens.Regexp.NAME.equals(condition.getType())) {
return new ByNameArrangementEntryMatcher(condition.getValue().toString());
@@ -17,6 +17,7 @@ package com.intellij.psi.codeStyle.arrangement.match;
import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
import com.intellij.psi.codeStyle.arrangement.ModifierAwareArrangementEntry;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
@@ -30,20 +31,28 @@ import java.util.Set;
*/
public class ByModifierArrangementEntryMatcher implements ArrangementEntryMatcher {
@NotNull private final Set<ArrangementSettingsToken> myModifiers = ContainerUtilRt.newHashSet();
@NotNull private final Set<ArrangementAtomMatchCondition> myModifiers = ContainerUtilRt.newHashSet();
public ByModifierArrangementEntryMatcher(@NotNull ArrangementSettingsToken interestedModifier) {
public ByModifierArrangementEntryMatcher(@NotNull ArrangementAtomMatchCondition interestedModifier) {
myModifiers.add(interestedModifier);
}
public ByModifierArrangementEntryMatcher(@NotNull Collection<ArrangementSettingsToken> interestedModifiers) {
public ByModifierArrangementEntryMatcher(@NotNull Collection<ArrangementAtomMatchCondition> interestedModifiers) {
myModifiers.addAll(interestedModifiers);
}
@Override
public boolean isMatched(@NotNull ArrangementEntry entry) {
if (entry instanceof ModifierAwareArrangementEntry) {
return ((ModifierAwareArrangementEntry)entry).getModifiers().containsAll(myModifiers);
final Set<ArrangementSettingsToken> modifiers = ((ModifierAwareArrangementEntry)entry).getModifiers();
for (ArrangementAtomMatchCondition condition : myModifiers) {
final Object value = condition.getValue();
boolean isInverted = value instanceof Boolean && !((Boolean)value);
if (isInverted == modifiers.contains(condition.getType())) {
return false;
}
}
return true;
}
return false;
}
@@ -17,6 +17,7 @@ package com.intellij.psi.codeStyle.arrangement.match;
import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
import com.intellij.psi.codeStyle.arrangement.TypeAwareArrangementEntry;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
@@ -36,26 +37,34 @@ import java.util.Set;
*/
public class ByTypeArrangementEntryMatcher implements ArrangementEntryMatcher {
@NotNull private final Set<ArrangementSettingsToken> myTypes = ContainerUtilRt.newHashSet();
@NotNull private final Set<ArrangementAtomMatchCondition> myTypes = ContainerUtilRt.newHashSet();
public ByTypeArrangementEntryMatcher(@NotNull ArrangementSettingsToken interestedType) {
public ByTypeArrangementEntryMatcher(@NotNull ArrangementAtomMatchCondition interestedType) {
myTypes.add(interestedType);
}
public ByTypeArrangementEntryMatcher(@NotNull Collection<ArrangementSettingsToken> interestedTypes) {
public ByTypeArrangementEntryMatcher(@NotNull Collection<ArrangementAtomMatchCondition> interestedTypes) {
myTypes.addAll(interestedTypes);
}
@Override
public boolean isMatched(@NotNull ArrangementEntry entry) {
if (entry instanceof TypeAwareArrangementEntry) {
return ((TypeAwareArrangementEntry)entry).getTypes().containsAll(myTypes);
final Set<ArrangementSettingsToken> types = ((TypeAwareArrangementEntry)entry).getTypes();
for (ArrangementAtomMatchCondition condition : myTypes) {
final Object value = condition.getValue();
boolean isInverted = value instanceof Boolean && !((Boolean)value);
if (isInverted == types.contains(condition.getType())) {
return false;
}
}
return true;
}
return false;
}
@NotNull
public Set<ArrangementSettingsToken> getTypes() {
public Set<ArrangementAtomMatchCondition> getTypes() {
return myTypes;
}
@@ -150,12 +150,30 @@ public class DefaultArrangementEntryMatcherSerializer {
if (text != null && processInnerText) {
text = StringUtil.unescapeStringCharacters(matcherElement.getText());
if (!StringUtil.isEmpty(text)) {
value = text;
final Boolean booleanValue = parseBooleanValue(text);
if (booleanValue != null) {
value = booleanValue;
}
else {
value = text;
}
}
}
return new ArrangementAtomMatchCondition(token, value);
}
@Nullable
private static Boolean parseBooleanValue(@NotNull String text) {
if (StringUtil.equalsIgnoreCase(text, Boolean.TRUE.toString())) {
return true;
}
if (StringUtil.equalsIgnoreCase(text, Boolean.FALSE.toString())) {
return false;
}
return null;
}
private static class MySerializationVisitor implements ArrangementMatchConditionVisitor {
Element result;
@@ -168,6 +186,9 @@ public class DefaultArrangementEntryMatcherSerializer {
if (StdArrangementTokenType.REG_EXP.is(type)) {
element.setText(StringUtil.escapeStringCharacters(condition.getValue().toString()));
}
else if (condition.getValue() instanceof Boolean) {
element.setText(condition.getValue().toString());
}
register(element);
}
@@ -18,10 +18,7 @@ package com.intellij.psi.codeStyle.arrangement.match;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.psi.codeStyle.arrangement.ArrangementEntry;
import com.intellij.psi.codeStyle.arrangement.model.*;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken;
import com.intellij.psi.codeStyle.arrangement.std.StdArrangementSettingsToken;
import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokenType;
import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens;
import com.intellij.psi.codeStyle.arrangement.std.*;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -129,8 +126,8 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher {
* Maps token type to all arrangement tokens that were encountered so far by parsing conditions with
* {@link #onCondition(ArrangementAtomMatchCondition) onCondition} calls.
*/
@NotNull protected final MultiValuesMap<StdArrangementTokenType, ArrangementSettingsToken > context =
new MultiValuesMap<StdArrangementTokenType, ArrangementSettingsToken>();
@NotNull protected final MultiValuesMap<StdArrangementTokenType, ArrangementAtomMatchCondition> context =
new MultiValuesMap<StdArrangementTokenType, ArrangementAtomMatchCondition>();
@Nullable private String myNamePattern;
@Nullable private String myNamespacePattern;
@Nullable private String myText;
@@ -139,9 +136,9 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher {
* Adds given entry to context by given entry type.
* @param token token added to context
*/
protected void addToContext(@NotNull StdArrangementSettingsToken token) {
protected void addToContext(@NotNull StdArrangementSettingsToken token, @NotNull ArrangementAtomMatchCondition condition) {
StdArrangementTokenType tokenType = token.getTokenType();
context.put(tokenType, token);
context.put(tokenType, condition);
}
@Override
@@ -157,10 +154,10 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher {
myText = condition.getValue().toString();
}
Object v = condition.getValue();
//Process any StdArrangementSettingsToken. No need to change it when new types of tokens will be processed.
if (v instanceof StdArrangementSettingsToken) {
StdArrangementSettingsToken token = (StdArrangementSettingsToken)v;
addToContext(token);
final ArrangementSettingsToken type = condition.getType();
if (type instanceof StdArrangementSettingsToken) {
//Process any StdArrangementSettingsToken. No need to change it when new types of tokens will be processed.
addToContext((StdArrangementSettingsToken)type, condition);
}
}
@@ -168,11 +165,11 @@ public class StdArrangementEntryMatcher implements ArrangementEntryMatcher {
@Override
public Collection<ArrangementEntryMatcher> buildMatchers() {
List<ArrangementEntryMatcher> result = ContainerUtilRt.newArrayList(myMatchers);
Collection<ArrangementSettingsToken> entryTokens = context.get(StdArrangementTokenType.ENTRY_TYPE);
Collection<ArrangementAtomMatchCondition> entryTokens = context.get(StdArrangementTokenType.ENTRY_TYPE);
if (entryTokens!= null) {
result.add(new ByTypeArrangementEntryMatcher(entryTokens));
}
Collection<ArrangementSettingsToken> modifierTokens = context.get(StdArrangementTokenType.MODIFIER);
Collection<ArrangementAtomMatchCondition> modifierTokens = context.get(StdArrangementTokenType.MODIFIER);
if (modifierTokens != null) {
result.add(new ByModifierArrangementEntryMatcher(modifierTokens));
}
@@ -22,6 +22,7 @@ import com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokenType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Set;
/**
@@ -55,8 +56,10 @@ public class StdArrangementMatchRule extends ArrangementMatchRule implements Clo
@Override
public int compareTo(@NotNull StdArrangementMatchRule o) {
final Set<ArrangementSettingsToken> tokens = ArrangementUtil.extractTokens(getMatcher().getCondition()).keySet();
final Set<ArrangementSettingsToken> tokens1 = ArrangementUtil.extractTokens(o.getMatcher().getCondition()).keySet();
final Map<ArrangementSettingsToken, Object> tokenValues = ArrangementUtil.extractTokens(getMatcher().getCondition());
final Map<ArrangementSettingsToken, Object> tokenValues1 = ArrangementUtil.extractTokens(o.getMatcher().getCondition());
final Set<ArrangementSettingsToken> tokens = tokenValues.keySet();
final Set<ArrangementSettingsToken> tokens1 = tokenValues1.keySet();
if (tokens1.containsAll(tokens)) {
return tokens.containsAll(tokens1) ? 0 : 1;
}
@@ -65,9 +68,9 @@ public class StdArrangementMatchRule extends ArrangementMatchRule implements Clo
return -1;
}
final String entryType = getEntryType(tokens);
final String entryType1 = getEntryType(tokens1);
final int compare = StringUtil.compare(entryType, entryType1, false);
final String entryType = getEntryType(tokenValues);
final String entryType1 = getEntryType(tokenValues1);
final int compare = StringUtil.compare(entryType1, entryType, false);
if (compare != 0 || tokens.size() == tokens1.size()) {
return compare;
}
@@ -76,10 +79,13 @@ public class StdArrangementMatchRule extends ArrangementMatchRule implements Clo
}
@Nullable
private static String getEntryType(@NotNull Set<ArrangementSettingsToken> tokens) {
for (ArrangementSettingsToken token : tokens) {
if (StdArrangementTokenType.ENTRY_TYPE.is(token)) {
return token.getId();
private static String getEntryType(@NotNull Map<ArrangementSettingsToken, Object> tokens) {
for (Map.Entry<ArrangementSettingsToken, Object> token : tokens.entrySet()) {
if (StdArrangementTokenType.ENTRY_TYPE.is(token.getKey())) {
final Object value = token.getValue();
if (!(value instanceof Boolean) || (Boolean)value) {
return token.getKey().getId();
}
}
}
return null;
@@ -16,6 +16,7 @@
package com.intellij.psi.codeStyle.arrangement.model;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken;
import com.intellij.psi.codeStyle.arrangement.std.InvertibleArrangementSettingsToken;
import org.jetbrains.annotations.NotNull;
/**
@@ -31,10 +32,8 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition
@NotNull private final ArrangementSettingsToken myType;
@NotNull private final Object myValue;
private boolean myInverted;
public ArrangementAtomMatchCondition(@NotNull ArrangementSettingsToken type) {
this(type, type);
this(type, type instanceof InvertibleArrangementSettingsToken ? Boolean.TRUE : type);
}
public ArrangementAtomMatchCondition(@NotNull ArrangementSettingsToken type, @NotNull Object value) {
@@ -57,15 +56,10 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition
visitor.visit(this);
}
public void setInverted(boolean inverted) {
myInverted = inverted;
}
@Override
public int hashCode() {
int result = myType.hashCode();
result = 31 * result + myValue.hashCode();
result = 31 * result + (myInverted ? 1 : 0);
return result;
}
@@ -80,9 +74,6 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition
ArrangementAtomMatchCondition setting = (ArrangementAtomMatchCondition)o;
if (myInverted != setting.myInverted) {
return false;
}
if (!myType.equals(setting.myType)) {
return false;
}
@@ -96,18 +87,16 @@ public class ArrangementAtomMatchCondition implements ArrangementMatchCondition
@NotNull
@Override
public ArrangementAtomMatchCondition clone() {
ArrangementAtomMatchCondition result = new ArrangementAtomMatchCondition(myType, myValue);
result.setInverted(myInverted);
return result;
return new ArrangementAtomMatchCondition(myType, myValue);
}
@Override
public String toString() {
if (myType.equals(myValue)) {
return String.format("%s%s", myInverted ? "not " : "", myType.getRepresentationValue());
if (myValue instanceof Boolean) {
return String.format("%s%s", (Boolean)myValue ? "" : "not " , myType.getRepresentationValue());
}
else {
return String.format("%s: %s%s", myType.getRepresentationValue(), myInverted ? "not " : "", myValue.toString().toLowerCase());
return String.format("%s: %s", myType.getRepresentationValue(), myValue.toString().toLowerCase());
}
}
}
@@ -164,15 +164,22 @@ public class ArrangementStandardSettingsManager {
private int parseWidth(@NotNull ArrangementSettingsToken token, @NotNull SimpleColoredComponent renderer) {
renderer.clear();
renderer.append(token.getRepresentationValue(),
SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, true)));
final String value = getPresentationValue(token);
renderer.append(value, SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, true)));
int result = renderer.getPreferredSize().width;
renderer.clear();
renderer.append(token.getRepresentationValue(),
SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, false)));
renderer.append(value, SimpleTextAttributes.fromTextAttributes(myColorsProvider.getTextAttributes(token, false)));
return Math.max(result, renderer.getPreferredSize().width);
}
@NotNull
private static String getPresentationValue(@NotNull ArrangementSettingsToken token) {
if (token instanceof InvertibleArrangementSettingsToken) {
return ((InvertibleArrangementSettingsToken)token).getInvertedRepresentationValue();
}
return token.getRepresentationValue();
}
public List<ArrangementSettingsToken> sort(@NotNull Collection<ArrangementSettingsToken> tokens) {
List<ArrangementSettingsToken> result = ContainerUtilRt.newArrayList(tokens);
@@ -36,7 +36,7 @@ import java.util.Set;
* @since 3/11/13 10:22 AM
*/
public interface ArrangementUiComponent {
@Nullable ArrangementSettingsToken getToken();
@NotNull Set<ArrangementSettingsToken> getAvailableTokens();
@@ -107,7 +107,20 @@ public interface ArrangementUiComponent {
int getBaselineToUse(int width, int height);
void setListener(@NotNull Listener listener);
/**
* Method to process second click on the component,
* e.g. we can deselect the component or invert it condition
*/
void handleMouseClickOnSelected();
/**
* For condition that can't be disabled,
* e.g. 'not public' can be used with any other rule like 'private' or 'not private'
* @return
*/
boolean alwaysCanBeActive();
interface Factory {
ExtensionPointName<Factory> EP_NAME = ExtensionPointName.create("com.intellij.rearranger.ui");
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2014 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.arrangement.std;
import org.jetbrains.annotations.NotNull;
/**
* Tokens that can be used in conditions in inverted state,
* e.g. 'public' -> 'not public' unlike 'order' or 'name' that can't be inverted
*
* @author Svetlana.Zemlyanskaya
*/
public interface InvertibleArrangementSettingsToken {
/**
* Inverted representation value that will be used in UI
*/
@NotNull
String getInvertedRepresentationValue();
}
@@ -52,9 +52,9 @@ public class StdArrangementSettingsToken extends ArrangementSettingsToken {
return myTokenType;
}
private StdArrangementSettingsToken(@NotNull String id,
@NotNull String uiName,
@NotNull StdArrangementTokenType tokenType) {
protected StdArrangementSettingsToken(@NotNull String id,
@NotNull String uiName,
@NotNull StdArrangementTokenType tokenType) {
super(id, uiName);
myTokenType = tokenType;
}
@@ -87,6 +87,12 @@ public class StdArrangementTokens {
};
}
private static StdArrangementSettingsToken invertible(@NotNull String id, @NotNull StdArrangementTokenType type) {
StdArrangementSettingsToken result = StdInvertibleArrangementSettingsToken.invertibleTokenById(id, type);
TOKENS_BY_ID.put(id, result);
return result;
}
private static StdArrangementSettingsToken token(@NotNull String id, @NotNull StdArrangementTokenType type) {
StdArrangementSettingsToken result = StdArrangementSettingsToken.tokenById(id, type);
TOKENS_BY_ID.put(id, result);
@@ -132,20 +138,23 @@ public class StdArrangementTokens {
}
}
public static class EntryType {
@NotNull public static final ArrangementSettingsToken CLASS = token("CLASS", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken ANONYMOUS_CLASS = token("ANONYMOUS_CLASS", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken FIELD = token("FIELD", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken CONSTRUCTOR = token("CONSTRUCTOR", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken METHOD = token("METHOD", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken ENUM = token("ENUM", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken INTERFACE = token("INTERFACE", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken CONST = token("CONST", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken VAR = token("VAR", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken PROPERTY = token("PROPERTY", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken EVENT_HANDLER = token("EVENT_HANDLER", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken STATIC_INIT = token("STATIC_INIT", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken NAMESPACE = token("NAMESPACE", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken TRAIT = token("TRAIT", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken CLASS = invertible("CLASS", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken ANONYMOUS_CLASS = invertible("ANONYMOUS_CLASS",
StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken FIELD = invertible("FIELD", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken CONSTRUCTOR = invertible("CONSTRUCTOR", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken METHOD = invertible("METHOD", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken ENUM = invertible("ENUM", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken INTERFACE = invertible("INTERFACE", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken CONST = invertible("CONST", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken VAR = invertible("VAR", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken PROPERTY = invertible("PROPERTY", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken EVENT_HANDLER = invertible("EVENT_HANDLER", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken STATIC_INIT = invertible("STATIC_INIT", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken NAMESPACE = invertible("NAMESPACE", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final ArrangementSettingsToken TRAIT = invertible("TRAIT", StdArrangementTokenType.ENTRY_TYPE);
// xml use only two entry types -> invertible tokens make no sense
@NotNull public static final ArrangementSettingsToken XML_TAG =
token("XML_TAG", "arrangement.settings.text.entry.type.xml.tag", StdArrangementTokenType.ENTRY_TYPE);
@NotNull public static final StdArrangementSettingsToken XML_ATTRIBUTE =
@@ -162,17 +171,17 @@ public class StdArrangementTokens {
}
}
public static class Modifier {
@NotNull public static final ArrangementSettingsToken PUBLIC = token("PUBLIC", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken PROTECTED = token("PROTECTED", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken PRIVATE = token("PRIVATE", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken PACKAGE_PRIVATE = token("PACKAGE_PRIVATE", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken STATIC = token("STATIC", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken FINAL = token("FINAL", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken TRANSIENT = token("TRANSIENT", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken VOLATILE = token("VOLATILE", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken SYNCHRONIZED = token("SYNCHRONIZED", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken ABSTRACT = token("ABSTRACT", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken OVERRIDE = token("OVERRIDE", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken PUBLIC = invertible("PUBLIC", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken PROTECTED = invertible("PROTECTED", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken PRIVATE = invertible("PRIVATE", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken PACKAGE_PRIVATE = invertible("PACKAGE_PRIVATE", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken STATIC = invertible("STATIC", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken FINAL = invertible("FINAL", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken TRANSIENT = invertible("TRANSIENT", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken VOLATILE = invertible("VOLATILE", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken SYNCHRONIZED = invertible("SYNCHRONIZED", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken ABSTRACT = invertible("ABSTRACT", StdArrangementTokenType.MODIFIER);
@NotNull public static final ArrangementSettingsToken OVERRIDE = invertible("OVERRIDE", StdArrangementTokenType.MODIFIER);
private static final NotNullLazyValue<Set<ArrangementSettingsToken>> TOKENS = collectFields(Modifier.class);
private Modifier() {
@@ -0,0 +1,44 @@
/*
* Copyright 2000-2014 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.arrangement.std;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* @author Svetlana.Zemlyanskaya
*/
public class StdInvertibleArrangementSettingsToken extends StdArrangementSettingsToken implements InvertibleArrangementSettingsToken {
private static final String NOT = "not ";
private StdInvertibleArrangementSettingsToken(@NotNull String id,
@NotNull String uiName,
@NotNull StdArrangementTokenType tokenType) {
super(id, uiName, tokenType);
}
@NotNull
public static StdInvertibleArrangementSettingsToken invertibleTokenById(@NonNls @NotNull String id,
@NotNull StdArrangementTokenType tokenType) {
return new StdInvertibleArrangementSettingsToken(id, id.toLowerCase().replace("_", " "), tokenType);
}
@NotNull
@Override
public String getInvertedRepresentationValue() {
return NOT + getRepresentationValue();
}
}
@@ -37,9 +37,9 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBScrollPane;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -77,7 +77,7 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
private JPanel myAdditionalSettingsPanel;
private JCheckBox myAutodetectIndentsBox;
private final SmartIndentOptionsEditor myIndentOptionsEditor;
private final JBScrollPane myScrollPane;
private final JScrollPane myScrollPane;
public GeneralCodeStylePanel(CodeStyleSettings settings) {
@@ -106,9 +106,7 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
ApplicationBundle.message("settings.code.style.general.formatter.marker.title"), true));
myMarkerOptionsPanel.setBorder(
IdeBorderFactory.createTitledBorder(ApplicationBundle.message("settings.code.style.general.formatter.marker.options.title"), true));
myScrollPane = new JBScrollPane(myPanel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
myScrollPane.setBorder(IdeBorderFactory.createEmptyBorder());
myScrollPane = ScrollPaneFactory.createScrollPane(myPanel, true);
myAdditionalSettingsPanel.setLayout(new VerticalFlowLayout(true, true));
myAdditionalSettingsPanel.removeAll();
@@ -175,4 +175,9 @@ public abstract class AbstractArrangementUiComponent implements ArrangementUiCom
}
protected abstract void doReset();
@Override
public boolean alwaysCanBeActive() {
return false;
}
}
@@ -16,7 +16,7 @@
package com.intellij.application.options.codeStyle.arrangement.component;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementStandardSettingsManager;
import com.intellij.psi.codeStyle.arrangement.std.*;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchNodeComponentFactory;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
@@ -24,8 +24,6 @@ import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchConditio
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchConditionVisitor;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementSettingsToken;
import com.intellij.psi.codeStyle.arrangement.std.ArrangementUiComponent;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.UIUtil;
@@ -265,6 +263,18 @@ public class ArrangementAndMatchConditionComponent extends JPanel implements Arr
}
}
@Override
public void handleMouseClickOnSelected() {
for (ArrangementUiComponent component : myComponents) {
component.handleMouseClickOnSelected();
}
}
@Override
public boolean alwaysCanBeActive() {
return false;
}
@Override
public String toString() {
return String.format("(%s)", StringUtil.join(myComponents, " and "));
@@ -22,6 +22,7 @@ import com.intellij.application.options.codeStyle.arrangement.color.ArrangementC
import com.intellij.application.options.codeStyle.arrangement.util.InsetsPanel;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.std.*;
import com.intellij.ui.IdeBorderFactory;
@@ -97,10 +98,15 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
@Nullable private Rectangle myScreenBounds;
@Nullable private Listener myListener;
private boolean myInverted = false;
private boolean myEnabled = true;
private boolean mySelected;
private boolean myCloseButtonHovered;
// cached value for inverted atom condition, e.g. condition: 'static', opposite: 'not static'
@Nullable private ArrangementAtomMatchCondition myOppositeCondition;
@Nullable private String myInvertedText;
public ArrangementAtomMatchConditionComponent(@NotNull ArrangementStandardSettingsManager manager,
@NotNull ArrangementColorsProvider colorsProvider,
@NotNull ArrangementAtomMatchCondition condition,
@@ -117,7 +123,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
else {
myBorderStrategy = PREDEFINED_BORDER_STRATEGY;
}
if (type.equals(condition.getValue())) {
if (type.equals(condition.getValue()) || condition.getValue() instanceof Boolean) {
myText = type.getRepresentationValue();
}
else if (StdArrangementTokenType.REG_EXP.is(type)) {
@@ -225,17 +231,27 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
if (myCloseButton != null) {
myCloseButton.setVisible(false);
}
setData(myCondition.getValue());
}
@NotNull
@Override
public ArrangementAtomMatchCondition getMatchCondition() {
if (myInverted == myCondition.getValue()) {
if (myOppositeCondition == null) {
myOppositeCondition = new ArrangementAtomMatchCondition(myCondition.getType(), !myInverted);
}
return myOppositeCondition;
}
return myCondition;
}
@Override
public void setData(@NotNull Object data) {
// Do nothing
if (data instanceof Boolean && myCondition.getType() instanceof InvertibleArrangementSettingsToken) {
myInverted = !((Boolean)data);
updateComponentText(mySelected);
}
}
@NotNull
@@ -259,9 +275,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
public void setSelected(boolean selected) {
boolean notifyListener = selected != mySelected;
mySelected = selected;
myTextControl.clear();
TextAttributes attributes = myColorsProvider.getTextAttributes(myCondition.getType(), selected);
myTextControl.append(myText, SimpleTextAttributes.fromTextAttributes(attributes));
TextAttributes attributes = updateComponentText(selected);
myBorder.setColor(myColorsProvider.getBorderColor(selected));
myBackgroundColor = attributes.getBackgroundColor();
if (notifyListener && myListener != null) {
@@ -269,6 +283,26 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
}
}
@NotNull
private TextAttributes updateComponentText(boolean selected) {
myTextControl.clear();
TextAttributes attributes = myColorsProvider.getTextAttributes(myCondition.getType(), selected);
myTextControl.append(getComponentText(), SimpleTextAttributes.fromTextAttributes(attributes));
return attributes;
}
private String getComponentText() {
if (myInverted) {
if (StringUtil.isEmpty(myInvertedText)) {
final ArrangementSettingsToken token = myCondition.getType();
assert token instanceof InvertibleArrangementSettingsToken;
myInvertedText = ((InvertibleArrangementSettingsToken)token).getInvertedRepresentationValue();
}
return myInvertedText;
}
return myText;
}
@Override
public boolean isEnabled() {
return myEnabled;
@@ -349,7 +383,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
@Override
public String toString() {
return myText;
return getComponentText();
}
@NotNull
@@ -377,6 +411,7 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
@Override
public void reset() {
setSelected(false);
setData(true);
}
@Override
@@ -390,6 +425,19 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementUiComp
myListener = listener;
}
@Override
public void handleMouseClickOnSelected() {
if (myInverted) {
setSelected(false);
}
setData(myInverted);
}
@Override
public boolean alwaysCanBeActive() {
return myInverted;
}
private interface BorderStrategy {
RoundedLineBorder create();
void setup(@NotNull Graphics2D g);
@@ -115,11 +115,16 @@ public class ArrangementCheckBoxUiComponent extends AbstractArrangementUiCompone
@Override
public void setSelected(boolean selected) {
myCheckBox.setSelected(selected);
myCheckBox.setSelected(selected);
}
@Override
public int getBaselineToUse(int width, int height) {
return myTextLabel.getBaseline(width, height);
}
@Override
public void handleMouseClickOnSelected() {
setSelected(false);
}
}
@@ -123,4 +123,9 @@ public class ArrangementComboBoxUiComponent extends AbstractArrangementUiCompone
public int getBaselineToUse(int width, int height) {
return -1;
}
@Override
public void handleMouseClickOnSelected() {
setSelected(false);
}
}
@@ -85,4 +85,9 @@ public class ArrangementLabelUiComponent extends AbstractArrangementUiComponent
public int getBaselineToUse(int width, int height) {
return myLabel.getBaseline(width, height);
}
@Override
public void handleMouseClickOnSelected() {
setSelected(false);
}
}
@@ -114,7 +114,9 @@ public class ArrangementTextFieldUiComponent extends AbstractArrangementUiCompon
@Override
public void setData(@NotNull Object data) {
myTextField.setText(data.toString());
if (data instanceof String) {
myTextField.setText(data.toString());
}
}
@Override
@@ -126,4 +128,9 @@ public class ArrangementTextFieldUiComponent extends AbstractArrangementUiCompon
public int getBaselineToUse(int width, int height) {
return myTextField.getBaseline(width, height);
}
@Override
public void handleMouseClickOnSelected() {
setSelected(false);
}
}
@@ -378,7 +378,8 @@ public class ArrangementMatchingRuleEditor extends JPanel implements Arrangement
// don't allow to remove start/end section indication
final Set<ArrangementSettingsToken> mutexes = ArrangementSectionRuleManager.getSectionMutexes();
if (!mutexes.contains(component.getToken())) {
removeCondition(component);
component.handleMouseClickOnSelected();
refreshConditions();
}
}
else {
@@ -417,7 +418,7 @@ public class ArrangementMatchingRuleEditor extends JPanel implements Arrangement
continue;
}
ArrangementUiComponent c = myComponents.get(key);
if (c != null && c.isEnabled()) {
if (c != null && c.isEnabled() && !c.alwaysCanBeActive()) {
removeCondition(c);
}
}
@@ -425,6 +426,7 @@ public class ArrangementMatchingRuleEditor extends JPanel implements Arrangement
private void removeCondition(@NotNull ArrangementUiComponent component) {
component.setSelected(false);
component.setData(true);
refreshConditions();
}
@@ -280,6 +280,16 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementUi
myDelegate.setListener(listener);
}
@Override
public void handleMouseClickOnSelected() {
myDelegate.handleMouseClickOnSelected();
}
@Override
public boolean alwaysCanBeActive() {
return false;
}
@Override
public String toString() {
return "list row decorator for " + myDelegate.toString();
@@ -40,12 +40,12 @@ import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.impl.PsiDocumentTransactionListener;
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -100,7 +100,7 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable
}
private void updateChangesForDocument(@NotNull final Document document) {
if (DaemonListeners.isUnderIgnoredAction(null)) return;
if (DaemonListeners.isUnderIgnoredAction(null) || myProject.isDisposed()) return;
List<Pair<PsiElement, Boolean>> toUpdate = changedElements.get(document);
if (toUpdate == null) {
// The document has been changed, but psi hasn't
@@ -111,7 +111,7 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable
PsiElement file = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(document);
if (file == null) return;
toUpdate = ContainerUtil.newArrayList(Pair.create(file, true));
toUpdate = Collections.singletonList(Pair.create(file, true));
}
Application application = ApplicationManager.getApplication();
final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.injected.editor.DocumentWindowImpl;
import com.intellij.lang.Language;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.application.ApplicationManager;
@@ -106,7 +107,7 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injectedFile);
if (documentWindow != null) {
handler.navigate(documentWindow.hostToInjected(offset));
handler.navigate(((DocumentWindowImpl)documentWindow).hostToUnescaped(offset));
}
}
return handler;
@@ -648,6 +648,27 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
@Override
public int hostToInjected(int hostOffset) {
synchronized (myLock) {
Segment hostRangeMarker = myShreds.get(0).getHostRangeMarker();
if (hostRangeMarker == null || hostOffset < hostRangeMarker.getStartOffset()) return myShreds.get(0).getPrefix().length();
int offset = 0;
for (int i = 0; i < myShreds.size(); i++) {
offset += myShreds.get(i).getPrefix().length();
Segment currentRange = myShreds.get(i).getHostRangeMarker();
if (currentRange == null) continue;
Segment nextRange = i == myShreds.size() - 1 ? null : myShreds.get(i + 1).getHostRangeMarker();
if (nextRange == null || hostOffset < nextRange.getStartOffset()) {
if (hostOffset >= currentRange.getEndOffset()) hostOffset = currentRange.getEndOffset();
return offset + hostOffset - currentRange.getStartOffset();
}
offset += currentRange.getEndOffset() - currentRange.getStartOffset();
offset += myShreds.get(i).getSuffix().length();
}
return getTextLength() - myShreds.get(myShreds.size() - 1).getSuffix().length();
}
}
public int hostToUnescaped(int hostOffset) {
synchronized (myLock) {
Segment hostRangeMarker = myShreds.get(0).getHostRangeMarker();
if (hostRangeMarker == null || hostOffset < hostRangeMarker.getStartOffset()) return myShreds.get(0).getPrefix().length();
@@ -594,6 +594,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
boolean writeAccessAllowed = isInsideWriteActionEDTOnly();
if (writeAccessAllowed // Disallow running process in separate thread from under write action.
// The thread will deadlock trying to get read action otherwise.
|| isHeadlessEnvironment() && !isUnitTestMode()
) {
LOG.debug("Starting process with progress from within write action makes no sense");
try {
@@ -80,19 +80,17 @@ abstract class SpotlightPainter extends AbstractPainter {
myGlassPanel.clear();
String text = filter.getFilterText();
myVisible = !text.isEmpty();
if (myVisible) {
try {
SearchableConfigurable searchable = new SearchableConfigurable.Delegate(configurable);
SearchUtil.lightOptions(searchable, component, text, myGlassPanel).run();
Runnable search = searchable.enableSearch(text);
if (search != null && !filter.contains(configurable) && !text.equals(myConfigurableOption.get(configurable))) {
search.run();
}
}
finally {
myConfigurableOption.put(configurable, text);
try {
SearchableConfigurable searchable = new SearchableConfigurable.Delegate(configurable);
SearchUtil.lightOptions(searchable, component, text, myGlassPanel).run();
Runnable search = searchable.enableSearch(text); // execute for empty string too
if (search != null && !filter.contains(configurable) && !text.equals(myConfigurableOption.get(configurable))) {
search.run();
}
}
finally {
myConfigurableOption.put(configurable, text);
}
}
else if (!ApplicationManager.getApplication().isUnitTestMode()) {
updateLater();
@@ -142,6 +142,10 @@ public abstract class AbstractRearrangerTest extends LightPlatformCodeInsightFix
return new ArrangementAtomMatchCondition(token);
}
protected static ArrangementAtomMatchCondition atom(@NotNull ArrangementSettingsToken token, boolean included) {
return new ArrangementAtomMatchCondition(token, included);
}
@NotNull
protected static ArrangementAtomMatchCondition atom(@NotNull String nameFilter) {
return new ArrangementAtomMatchCondition(StdArrangementTokens.Regexp.NAME, nameFilter);
@@ -383,10 +383,10 @@ public class FileUtil extends FileUtilRt {
@Nullable
private static File renameToTempFileOrDelete(@NotNull File file) {
final File tempDir = new File(getTempDirectory());
String tempDir = getTempDirectory();
boolean isSameDrive = true;
if (SystemInfo.isWindows) {
String tempDirDrive = tempDir.getAbsolutePath().substring(0, 2);
String tempDirDrive = tempDir.substring(0, 2);
String fileDrive = file.getAbsolutePath().substring(0, 2);
isSameDrive = tempDirDrive.equalsIgnoreCase(fileDrive);
}
@@ -405,7 +405,7 @@ public class FileUtil extends FileUtilRt {
return null;
}
private static File getTempFile(@NotNull String originalFileName, @NotNull File parent) {
private static File getTempFile(@NotNull String originalFileName, @NotNull String parent) {
int randomSuffix = (int)(System.currentTimeMillis() % 1000);
for (int i = randomSuffix; ; i++) {
@NonNls String name = "___" + originalFileName + i + ASYNC_DELETE_EXTENSION;
@@ -2220,7 +2220,7 @@ public class ContainerUtil extends ContainerUtilRt {
@NotNull
@Contract(pure=true)
public static <V> ConcurrentIntObjectMap<V> createConcurrentIntObjectMap() {
return new ConcurrentIntObjectHashMap<V>();
return new StripedLockIntObjectConcurrentHashMap<V>();
}
@NotNull
@@ -31,6 +31,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.impl.DirectoryIndexExcludePolicy;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
@@ -328,8 +329,15 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
}
ProjectFileIndex fileIndex = ProjectFileIndex.SERVICE.getInstance(myProject);
VirtualFileManager virtualFileManager = VirtualFileManager.getInstance();
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
for (String url : ModuleRootManager.getInstance(module).getExcludeRootUrls()) {
VirtualFile file = virtualFileManager.findFileByUrl(url);
if (file != null && !fileIndex.isExcluded(file)) {
//root is included into some inner module so it shouldn't be ignored
continue;
}
addDirectoryToIgnoreImplicitly(VfsUtilCore.urlToPath(url));
}
}
@@ -1,5 +1,6 @@
package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerProjectExtension;
import com.intellij.openapi.vfs.VirtualFile;
@@ -71,6 +72,14 @@ public class ConvertExcludedToIgnoredTest extends PlatformTestCase {
assertIgnored(excluded);
}
public void testDoNotIgnoreInnerModuleExplicitlyMarkedAsExcludedFromOuterModule() throws IOException {
VirtualFile inner = createChildDirectory(myContentRoot, "inner");
PsiTestUtil.addModule(myProject, ModuleType.EMPTY, "inner", inner);
PsiTestUtil.addExcludedRoot(myModule, inner);
getChangeListManager().convertExcludedToIgnored();
assertFalse(getChangeListManager().isIgnoredFile(inner));
}
private void assertIgnored(VirtualFile... ignoredDirs) {
assertIgnoredDirectories(getProject(), ignoredDirs);
}
@@ -576,9 +576,10 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
private class GitCheckinOptions extends DvcsCommitAdditionalComponent implements CheckinChangeListSpecificComponent {
private final GitVcs myVcs;
private final ComboBox myAuthor;
private final ComboBox myAuthorField;
private Date myAuthorDate;
@Nullable private Date myAuthorDate;
@Nullable private String myAuthor;
GitCheckinOptions(@NotNull final Project project, @NotNull CheckinProjectPanel panel) {
super(project, panel);
@@ -606,27 +607,27 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
List<String> list = new ArrayList<String>(authors);
Collections.sort(list);
myAuthor = new ComboBox(ArrayUtil.toObjectArray(list)) {
myAuthorField = new ComboBox(ArrayUtil.toObjectArray(list)) {
@Override
public void addNotify() {
super.addNotify();
// adding in addNotify to make sure the editor is ready for further customization
StringComboboxEditor comboboxEditor = new StringComboboxEditor(project, FileTypes.PLAIN_TEXT, myAuthor, true);
myAuthor.setEditor(comboboxEditor);
StringComboboxEditor comboboxEditor = new StringComboboxEditor(project, FileTypes.PLAIN_TEXT, myAuthorField, true);
myAuthorField.setEditor(comboboxEditor);
EditorEx editor = (EditorEx)comboboxEditor.getEditor();
assert editor != null;
SpellCheckingEditorCustomization.getInstance(false).customize(editor);
myAuthorField.insertItemAt(myAuthor == null ? "" : myAuthor, 0);
myAuthorField.setSelectedIndex(0);
}
};
myAuthor.setMinimumAndPreferredWidth(100);
myAuthor.insertItemAt("", 0);
myAuthor.setSelectedItem("");
myAuthor.setEditable(true);
authorLabel.setLabelFor(myAuthor);
myAuthor.setToolTipText(GitBundle.getString("commit.author.tooltip"));
myPanel.add(myAuthor, c);
myAuthorField.setMinimumAndPreferredWidth(100);
myAuthorField.setEditable(true);
authorLabel.setLabelFor(myAuthorField);
myAuthorField.setToolTipText(GitBundle.getString("commit.author.tooltip"));
myPanel.add(myAuthorField, c);
}
@Override
@@ -667,13 +668,14 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
@Override
public void refresh() {
super.refresh();
myAuthor.setSelectedItem("");
myAuthor = null;
myAuthorDate = null;
reset();
}
@Override
public void saveState() {
String author = (String)myAuthor.getEditor().getItem();
String author = (String)myAuthorField.getEditor().getItem();
if (StringUtil.isEmptyOrSpaces(author)) {
myNextCommitAuthor = null;
}
@@ -695,9 +697,8 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
Object data = list.getData();
if (data instanceof VcsFullCommitDetails) {
VcsFullCommitDetails commit = (VcsFullCommitDetails)data;
String author = String.format("%s <%s>", commit.getAuthor().getName(), commit.getAuthor().getEmail());
myAuthor.getEditor().setItem(author);
myAuthorDate = new Date(commit.getTimestamp());
myAuthor = String.format("%s <%s>", commit.getAuthor().getName(), commit.getAuthor().getEmail());
myAuthorDate = new Date(commit.getAuthorTime());
}
}
}
@@ -310,7 +310,7 @@ public class JUnitConfiguration extends ModuleBasedConfiguration<JavaRunConfigur
EnvironmentVariablesComponent.readExternal(element, getPersistentData().getEnvs());
final Element patternsElement = element.getChild(PATTERNS_EL_NAME);
if (patternsElement != null) {
final Set<String> tests = new LinkedHashSet<String>();
final LinkedHashSet<String> tests = new LinkedHashSet<String>();
for (Object o : patternsElement.getChildren(PATTERN_EL_NAME)) {
Element patternElement = (Element)o;
tests.add(patternElement.getAttributeValue(TEST_CLASS_ATT_NAME));
@@ -403,7 +403,7 @@ public class JUnitConfiguration extends ModuleBasedConfiguration<JavaRunConfigur
public void bePatternConfiguration(List<PsiClass> classes, PsiMethod method) {
myData.TEST_OBJECT = TEST_PATTERN;
final Set<String> patterns = new HashSet<String>();
final LinkedHashSet<String> patterns = new LinkedHashSet<String>();
final String methodSufiix;
if (method != null) {
myData.METHOD_NAME = method.getName();
@@ -437,7 +437,7 @@ public class JUnitConfiguration extends ModuleBasedConfiguration<JavaRunConfigur
public String WORKING_DIRECTORY;
private String FORK_MODE = "none";
private Set<String> myPattern = new LinkedHashSet<String>();
private LinkedHashSet<String> myPattern = new LinkedHashSet<String>();
//iws/ipr compatibility
public String ENV_VARIABLES;
private Map<String, String> myEnvs = new LinkedHashMap<String, String>();
@@ -581,7 +581,7 @@ public class JUnitConfiguration extends ModuleBasedConfiguration<JavaRunConfigur
return StringUtil.join(enabledTests, "||");
}
public void setPatterns(Set<String> pattern) {
public void setPatterns(LinkedHashSet<String> pattern) {
myPattern = pattern;
}
@@ -509,18 +509,18 @@ public abstract class TestObject implements JavaCommandLine {
testNames.add(name);
}
}
final JUnitConfiguration.Data data = myConfiguration.getPersistentData();
if (perModule != null) {
for (List<String> perModuleClasses : perModule.values()) {
Collections.sort(perModuleClasses);
testNames.addAll(perModuleClasses);
}
}
else {
else if (JUnitConfiguration.TEST_PACKAGE.equals(data.TEST_OBJECT)) {
Collections.sort(testNames); //sort tests in FQN order
}
final JUnitConfiguration.Data data = myConfiguration.getPersistentData();
final String category = data.TEST_OBJECT == JUnitConfiguration.TEST_CATEGORY ? data.getCategory() : "";
final String category = JUnitConfiguration.TEST_CATEGORY.equals(data.TEST_OBJECT) ? data.getCategory() : "";
JUnitStarter.printClassesList(testNames, packageName, category, myTempFile);
if (perModule != null && perModule.size() > 1) {
@@ -83,7 +83,7 @@ public class SearchingForTestsTask extends Task.Backgroundable {
myServerSocket = serverSocket;
myConfig = config;
myTempFile = tempFile;
myClasses = new HashMap<PsiClass, Collection<PsiMethod>>();
myClasses = new LinkedHashMap<PsiClass, Collection<PsiMethod>>();
}
public void run(@NotNull ProgressIndicator indicator) {
@@ -190,13 +190,13 @@ public class SearchingForTestsTask extends Task.Backgroundable {
}
private void composeTestSuiteFromClasses() {
Map<String, Collection<String>> map = new HashMap<String, Collection<String>>();
Map<String, Collection<String>> map = new LinkedHashMap<String, Collection<String>>();
final boolean findTestMethodsForClass = shouldSearchForTestMethods();
for (final Map.Entry<PsiClass, Collection<PsiMethod>> entry : myClasses.entrySet()) {
final Collection<PsiMethod> depMethods = entry.getValue();
Collection<String> methods = new HashSet<String>(depMethods.size());
Collection<String> methods = new LinkedHashSet<String>(depMethods.size());
for (PsiMethod method : depMethods) {
methods.add(method.getName());
}
@@ -523,7 +523,7 @@ public class SearchingForTestsTask extends Task.Backgroundable {
final Set<PsiMember> alreadyMarkedToBeChecked,
@Nullable final PsiClass... classes) {
if (classes != null && classes.length > 0) {
final Set<String> groupDependencies = new HashSet<String>();
final Set<String> groupDependencies = new LinkedHashSet<String>();
TestNGUtil.collectAnnotationValues(groupDependencies, "dependsOnGroups", methods, classes);
final Set<PsiMember> membersToCheckNow = new LinkedHashSet<PsiMember>();
if (!groupDependencies.isEmpty()) {
@@ -574,7 +574,7 @@ public class SearchingForTestsTask extends Task.Backgroundable {
final PsiClass... classes) {
final PsiClass[] psiClasses;
if (methods != null && methods.length > 0) {
final Set<PsiClass> containingClasses = new HashSet<PsiClass>();
final Set<PsiClass> containingClasses = new LinkedHashSet<PsiClass>();
for (PsiMethod method : methods) {
containingClasses.add(method.getContainingClass());
}
@@ -583,7 +583,7 @@ public class SearchingForTestsTask extends Task.Backgroundable {
psiClasses = classes;
}
for (final PsiClass containingClass : psiClasses) {
final Set<String> testMethodDependencies = new HashSet<String>();
final Set<String> testMethodDependencies = new LinkedHashSet<String>();
TestNGUtil.collectAnnotationValues(testMethodDependencies, "dependsOnMethods", methods, containingClass);
if (!testMethodDependencies.isEmpty()) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@@ -269,7 +269,7 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
} else {
suffix = "";
}
Set<String> patterns = new LinkedHashSet<String>();
LinkedHashSet<String> patterns = new LinkedHashSet<String>();
for (PsiClass pattern : classes) {
patterns.add(JavaExecutionUtil.getRuntimeQualifiedName(pattern) + suffix);
}
@@ -373,7 +373,7 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
}
final Element patternsElement = element.getChild(PATTERNS_EL_NAME);
if (patternsElement != null) {
final Set<String> tests = new LinkedHashSet<String>();
final LinkedHashSet<String> tests = new LinkedHashSet<String>();
for (Object o : patternsElement.getChildren(PATTERN_EL_NAME)) {
Element patternElement = (Element)o;
tests.add(patternElement.getAttributeValue(TEST_CLASS_ATT_NAME));
@@ -57,7 +57,7 @@ public class TestData implements Cloneable
public List<String> TEST_LISTENERS = new ArrayList<String>();
public boolean USE_DEFAULT_REPORTERS = false;
public String PROPERTIES_FILE;
private Set<String> myPatterns = new LinkedHashSet<String>();
private LinkedHashSet<String> myPatterns = new LinkedHashSet<String>();
public TestData() {
TEST_OBJECT = TestType.CLASS.getType();
@@ -168,7 +168,7 @@ public class TestData implements Cloneable
data.USE_DEFAULT_REPORTERS = USE_DEFAULT_REPORTERS;
data.ENVS = new LinkedHashMap<String, String>(ENVS);
data.myPatterns = new HashSet<String>();
data.myPatterns = new LinkedHashSet<String>();
data.myPatterns.addAll(myPatterns);
data.setScope(getScope());
return data;
@@ -251,7 +251,7 @@ public class TestData implements Cloneable
return myPatterns;
}
public void setPatterns(Set<String> set) {
public void setPatterns(LinkedHashSet<String> set) {
myPatterns = set;
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<id>PythonCore</id>
<name>Python Community Edition</name>
<idea-version since-build="138.0" until-build="138.*"/>
<idea-version since-build="138.0" until-build="140.*"/>
<description><![CDATA[
The Python plug-in provides smart editing for Python scripts. The feature set of the plugin
@@ -35,7 +35,13 @@ public abstract class BaseUpdateAction extends PatchAction {
protected void replaceUpdated(File from, File dest) throws IOException {
// on OS X code signing caches seem to be associated with specific file ids, so we need to remove the original file.
if (!dest.delete()) throw new IOException("Cannot delete file " + dest);
if (!dest.delete()) {
if (Utils.isWindows()) {
throw new RetryException("Cannot delete file " + dest);
} else {
throw new IOException("Cannot delete file " + dest);
}
}
Utils.copy(from, dest);
}
@@ -59,7 +59,15 @@ public class CreateAction extends PatchAction {
private static void prepareToWriteFile(File file) throws IOException {
if (file.exists()) {
Utils.delete(file);
try {
Utils.delete(file);
} catch (IOException e) {
if (Utils.isWindows() && file.exists()) {
throw new RetryException(e);
} else {
throw e;
}
}
return;
}
@@ -43,13 +43,23 @@ public class DeleteAction extends PatchAction {
@Override
protected void doApply(ZipFile patchFile, File toFile) throws IOException {
Utils.delete(toFile);
try {
Utils.delete(toFile);
} catch (IOException e) {
if (Utils.isWindows() && toFile.exists()) {
throw new RetryException(e);
} else {
throw e;
}
}
}
@Override
protected void doBackup(File toFile, File backupFile) throws IOException {
Utils.copy(toFile, backupFile);
}
@Override
protected void doRevert(File toFile, File backupFile) throws IOException {
if (!toFile.exists() || isModified(toFile)) {
Utils.delete(toFile); // make sure there is no directory remained on this path (may remain from previous 'create' actions
@@ -28,7 +28,8 @@ public class Digester {
zipFile = new ZipFile(file);
}
catch (IOException e) {
Runner.printStackTrace(e);
// If this isn't a zip file, this isn't really an error, merely an info.
Runner.infoStackTrace("Can't open file as zip file: " + file.getPath() + "\n", e);
return doDigestRegularFile(file);
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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.updater;
import java.io.IOException;
/**
* Exception thrown when an IOException arises when performing a patch
* action and it's likely that retrying will be successful.
*/
public class RetryException extends IOException {
public RetryException() {
}
public RetryException(String message) {
super(message);
}
public RetryException(String message, Throwable cause) {
super(message, cause);
}
public RetryException(Throwable cause) {
super(cause);
}
}
+66 -12
View File
@@ -38,11 +38,22 @@ public class Runner {
create(oldVersionDesc, newVersionDesc, oldFolder, newFolder, patchFile, ignoredFiles, criticalFiles, optionalFiles);
}
else if (args.length >= 2 && "install".equals(args[0])) {
String destFolder = args[1];
// install [--exit0] <destination_folder>
int nextArg = 1;
// Default install exit code is SwingUpdaterUI.RESULT_REQUIRES_RESTART (42) unless overridden to be 0.
// This is used by testUI/build.gradle as gradle expects a javaexec to exit with code 0.
boolean useExitCode0 = false;
if (args[nextArg].equals("--exit0")) {
useExitCode0 = true;
nextArg++;
}
String destFolder = args[nextArg++];
initLogger();
logger.info("destFolder: " + destFolder);
install(destFolder);
install(useExitCode0, destFolder);
}
else {
printUsage();
@@ -93,6 +104,10 @@ public class Runner {
}
}
public static void infoStackTrace(String msg, Throwable e){
logger.info(msg, e);
}
public static void printStackTrace(Throwable e){
logger.error(e.getMessage(), e);
}
@@ -115,8 +130,8 @@ public class Runner {
private static void printUsage() {
System.err.println("Usage:\n" +
"create <old_version_description> <new_version_description> <old_version_folder> <new_version_folder>" +
" <patch_file_name> [ignored=file1;file2;...] [critical=file1;file2;...] [optional=file1;file2;...]\n" +
"install <destination_folder> [log_directory]\n");
" <patch_file_name> <log_directory> [ignored=file1;file2;...] [critical=file1;file2;...] [optional=file1;file2;...]\n" +
"install [--exit0] <destination_folder> [log_directory]\n");
}
private static void create(String oldBuildDesc,
@@ -127,9 +142,31 @@ public class Runner {
List<String> ignoredFiles,
List<String> criticalFiles,
List<String> optionalFiles) throws IOException, OperationCancelledException {
UpdaterUI ui = new ConsoleUpdaterUI();
File tempPatchFile = Utils.createTempFile();
createImpl(oldBuildDesc,
newBuildDesc,
oldFolder,
newFolder,
patchFile,
tempPatchFile,
ignoredFiles,
criticalFiles,
optionalFiles,
new ConsoleUpdaterUI(), resolveJarFile());
}
static void createImpl(String oldBuildDesc,
String newBuildDesc,
String oldFolder,
String newFolder,
String outPatchJar,
File tempPatchFile,
List<String> ignoredFiles,
List<String> criticalFiles,
List<String> optionalFiles,
UpdaterUI ui,
File resolvedJar) throws IOException, OperationCancelledException {
try {
File tempPatchFile = Utils.createTempFile();
PatchFileCreator.create(new File(oldFolder),
new File(newFolder),
tempPatchFile,
@@ -138,13 +175,13 @@ public class Runner {
optionalFiles,
ui);
logger.info("Packing JAR file: " + patchFile );
ui.startProcess("Packing JAR file '" + patchFile + "'...");
logger.info("Packing JAR file: " + outPatchJar );
ui.startProcess("Packing JAR file '" + outPatchJar + "'...");
FileOutputStream fileOut = new FileOutputStream(patchFile);
FileOutputStream fileOut = new FileOutputStream(outPatchJar);
try {
ZipOutputWrapper out = new ZipOutputWrapper(fileOut);
ZipInputStream in = new ZipInputStream(new FileInputStream(resolveJarFile()));
ZipInputStream in = new ZipInputStream(new FileInputStream(resolvedJar));
try {
ZipEntry e;
while ((e = in.getNextEntry()) != null) {
@@ -186,7 +223,7 @@ public class Runner {
Utils.cleanup();
}
private static void install(final String destFolder) throws Exception {
private static void install(final boolean useExitCode0, final String destFolder) throws Exception {
InputStream in = Runner.class.getResourceAsStream("/" + PATCH_PROPERTIES_ENTRY);
Properties props = new Properties();
try {
@@ -213,7 +250,9 @@ public class Runner {
new SwingUpdaterUI(props.getProperty(OLD_BUILD_DESCRIPTION),
props.getProperty(NEW_BUILD_DESCRIPTION),
useExitCode0 ? 0 : SwingUpdaterUI.RESULT_REQUIRES_RESTART,
new SwingUpdaterUI.InstallOperation() {
@Override
public boolean execute(UpdaterUI ui) throws OperationCancelledException {
logger.info("installing patch to the " + destFolder);
return doInstall(ui, destFolder);
@@ -221,11 +260,26 @@ public class Runner {
});
}
interface IJarResolver {
File resolveJar() throws IOException;
}
private static boolean doInstall(UpdaterUI ui, String destFolder) throws OperationCancelledException {
return doInstallImpl(ui, destFolder, new IJarResolver() {
@Override
public File resolveJar() throws IOException {
return resolveJarFile();
}
});
}
static boolean doInstallImpl(UpdaterUI ui,
String destFolder,
IJarResolver jarResolver) throws OperationCancelledException {
try {
try {
File patchFile = Utils.createTempFile();
ZipFile jarFile = new ZipFile(resolveJarFile());
ZipFile jarFile = new ZipFile(jarResolver.resolveJar());
logger.info("Extracting patch file...");
ui.startProcess("Extracting patch file...");
@@ -10,6 +10,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
@@ -19,7 +20,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
public class SwingUpdaterUI implements UpdaterUI {
private static final int RESULT_REQUIRES_RESTART = 42;
static final int RESULT_REQUIRES_RESTART = 42;
private static final EmptyBorder FRAME_BORDER = new EmptyBorder(8, 8, 8, 8);
private static final EmptyBorder LABEL_BORDER = new EmptyBorder(0, 0, 5, 0);
@@ -32,6 +33,7 @@ public class SwingUpdaterUI implements UpdaterUI {
private static final String PROCEED_BUTTON_TITLE = "Proceed";
private final int mySuccessExitCode;
private final InstallOperation myOperation;
private final JLabel myProcessTitle;
@@ -40,16 +42,30 @@ public class SwingUpdaterUI implements UpdaterUI {
private final JTextArea myConsole;
private final JPanel myConsolePane;
private final JButton myRetryButton;
private final JButton myCancelButton;
private final ConcurrentLinkedQueue<UpdateRequest> myQueue = new ConcurrentLinkedQueue<UpdateRequest>();
private final AtomicBoolean isCancelled = new AtomicBoolean(false);
private final AtomicBoolean isRunning = new AtomicBoolean(false);
private final AtomicBoolean hasError = new AtomicBoolean(false);
private final AtomicBoolean hasRetry = new AtomicBoolean(false);
private final JFrame myFrame;
private boolean myApplied;
public SwingUpdaterUI(String oldBuildDesc, String newBuildDesc, InstallOperation operation) {
/**
* Displays the updater UI and asynchronously runs the operation list.
*
* @param oldBuildDesc The old build description, for display purposes.
* @param newBuildDesc The new build description, for display purposes.
* @param successExitCode The desired exit code on success. Default is {@link #RESULT_REQUIRES_RESTART}.
* @param operation The install operations to perform.
*/
public SwingUpdaterUI(String oldBuildDesc,
String newBuildDesc,
int successExitCode,
InstallOperation operation) {
mySuccessExitCode = successExitCode;
myOperation = operation;
myProcessTitle = new JLabel(" ");
@@ -58,6 +74,10 @@ public class SwingUpdaterUI implements UpdaterUI {
myCancelButton = new JButton(CANCEL_BUTTON_TITLE);
myRetryButton = new JButton("Retry");
myRetryButton.setEnabled(false);
myRetryButton.setVisible(false);
myConsole = new JTextArea();
myConsole.setLineWrap(true);
myConsole.setWrapStyleWord(true);
@@ -70,11 +90,19 @@ public class SwingUpdaterUI implements UpdaterUI {
myConsolePane.setVisible(false);
myCancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doCancel();
}
});
myRetryButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doRetry();
}
});
myFrame = new JFrame();
myFrame.setTitle(TITLE);
@@ -104,6 +132,7 @@ public class SwingUpdaterUI implements UpdaterUI {
buttonsPanel.setBorder(BUTTONS_BORDER);
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
buttonsPanel.add(Box.createHorizontalGlue());
buttonsPanel.add(myRetryButton);
buttonsPanel.add(myCancelButton);
myProcessTitle.setText("<html>Updating " + oldBuildDesc + " to " + newBuildDesc + "...");
@@ -129,6 +158,7 @@ public class SwingUpdaterUI implements UpdaterUI {
private void startRequestDispatching() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
@@ -146,6 +176,7 @@ public class SwingUpdaterUI implements UpdaterUI {
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
for (UpdateRequest each : pendingRequests) {
each.perform();
@@ -172,10 +203,28 @@ public class SwingUpdaterUI implements UpdaterUI {
}
}
private void doRetry() {
hasError.set(false);
hasRetry.set(false);
isCancelled.set(false);
myQueue.add(new UpdateRequest() {
@Override
public void perform() {
myConsole.setText("");
myConsolePane.setVisible(false);
myConsolePane.setPreferredSize(new Dimension(10, 200));
myRetryButton.setEnabled(false);
myCancelButton.setEnabled(true);
}
});
doPerform();
}
private void doPerform() {
isRunning.set(true);
new Thread(new Runnable() {
@Override
public void run() {
try {
myApplied = myOperation.execute(SwingUpdaterUI.this);
@@ -190,6 +239,10 @@ public class SwingUpdaterUI implements UpdaterUI {
finally {
isRunning.set(false);
if (hasRetry.get()) {
myRetryButton.setVisible(true);
myRetryButton.setEnabled(true);
}
if (hasError.get()) {
startProcess("Failed to apply patch");
setProgress(100);
@@ -204,15 +257,17 @@ public class SwingUpdaterUI implements UpdaterUI {
}
private void exit() {
System.exit(myApplied ? RESULT_REQUIRES_RESTART : 0);
System.exit(myApplied ? mySuccessExitCode : 0);
}
@Override
public Map<String, ValidationResult.Option> askUser(final List<ValidationResult> validationResults) throws OperationCancelledException {
if (validationResults.isEmpty()) return Collections.emptyMap();
final Map<String, ValidationResult.Option> result = new HashMap<String, ValidationResult.Option>();
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
final JDialog dialog = new JDialog(myFrame, TITLE, true);
dialog.setLayout(new BorderLayout());
@@ -224,6 +279,7 @@ public class SwingUpdaterUI implements UpdaterUI {
buttonsPanel.add(Box.createHorizontalGlue());
JButton proceedButton = new JButton(PROCEED_BUTTON_TITLE);
proceedButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
@@ -231,6 +287,7 @@ public class SwingUpdaterUI implements UpdaterUI {
JButton cancelButton = new JButton(CANCEL_BUTTON_TITLE);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
isCancelled.set(true);
myCancelButton.setEnabled(false);
@@ -287,8 +344,10 @@ public class SwingUpdaterUI implements UpdaterUI {
return result;
}
@Override
public void startProcess(final String title) {
myQueue.add(new UpdateRequest() {
@Override
public void perform() {
myProcessStatus.setText(title);
myProcessProgress.setIndeterminate(false);
@@ -297,8 +356,10 @@ public class SwingUpdaterUI implements UpdaterUI {
});
}
@Override
public void setProgress(final int percentage) {
myQueue.add(new UpdateRequest() {
@Override
public void perform() {
myProcessProgress.setIndeterminate(false);
myProcessProgress.setValue(percentage);
@@ -306,21 +367,43 @@ public class SwingUpdaterUI implements UpdaterUI {
});
}
@Override
public void setProgressIndeterminate() {
myQueue.add(new UpdateRequest() {
@Override
public void perform() {
myProcessProgress.setIndeterminate(true);
}
});
}
@Override
public void setStatus(final String status) {
}
@Override
public void showError(final Throwable e) {
hasError.set(true);
StringWriter w = new StringWriter();
if (e instanceof RetryException) {
hasRetry.set(true);
w.write("+----------------\n");
w.write("| A file operation failed.\n");
w.write("| This might be due to a file being locked by another\n");
w.write("| application. Please try closing any application\n");
w.write("| that uses the files being updated then press 'Retry'.\n");
w.write("+----------------\n");
w.write("\n\n");
}
e.printStackTrace(new PrintWriter(w));
final String content = w.getBuffer().toString();
myQueue.add(new UpdateRequest() {
@Override
public void perform() {
StringWriter w = new StringWriter();
if (!myConsolePane.isVisible()) {
@@ -328,9 +411,8 @@ public class SwingUpdaterUI implements UpdaterUI {
w.write(System.getProperty("java.io.tmpdir"));
w.write("\n\n");
}
e.printStackTrace(new PrintWriter(w));
w.append("\n");
myConsole.append(w.getBuffer().toString());
myConsole.append(content);
if (!myConsolePane.isVisible()) {
myConsole.setCaretPosition(0);
myConsolePane.setVisible(true);
@@ -341,6 +423,7 @@ public class SwingUpdaterUI implements UpdaterUI {
});
}
@Override
public void checkCancelled() throws OperationCancelledException {
if (isCancelled.get()) throw new OperationCancelledException();
}
@@ -354,7 +437,8 @@ public class SwingUpdaterUI implements UpdaterUI {
}
public static void main(String[] args) {
new SwingUpdaterUI("xxx", "yyy", new InstallOperation() {
new SwingUpdaterUI("xxx", "yyy", RESULT_REQUIRES_RESTART, new InstallOperation() {
@Override
public boolean execute(UpdaterUI ui) throws OperationCancelledException {
ui.startProcess("Process1");
ui.checkCancelled();
@@ -438,6 +522,7 @@ public class SwingUpdaterUI implements UpdaterUI {
}
}
@Override
public int getColumnCount() {
return COLUMNS.length;
}
@@ -464,6 +549,7 @@ public class SwingUpdaterUI implements UpdaterUI {
return super.getColumnClass(columnIndex);
}
@Override
public int getRowCount() {
return myItems.size();
}
@@ -480,6 +566,7 @@ public class SwingUpdaterUI implements UpdaterUI {
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Item item = myItems.get(rowIndex);
switch (columnIndex) {
+32 -4
View File
@@ -10,10 +10,19 @@ public class Utils {
private static final byte[] BUFFER = new byte[64 * 1024];
private static File myTempDir;
public static boolean isWindows() {
return System.getProperty("os.name").startsWith("Windows");
}
public static boolean isZipFile(String fileName) {
return fileName.endsWith(".zip") || fileName.endsWith(".jar");
}
/**
* Creates a new temp file. <br/>
* All the temp files created here are located in a unique root temp directory
* that is automatically deleted by {@link #cleanup()}.
*/
@SuppressWarnings({"SSBasedInspection"})
public static File createTempFile() throws IOException {
if (myTempDir == null) {
@@ -26,6 +35,12 @@ public class Utils {
return File.createTempFile("temp.", ".tmp", myTempDir);
}
/**
* Creates a new temp directory. <br/>
* All the temp directories created here are located in a unique root temp directory
* that is automatically deleted by {@link #cleanup()}.
*/
public static File createTempDir() throws IOException {
File result = createTempFile();
delete(result);
@@ -42,6 +57,15 @@ public class Utils {
myTempDir = null;
}
/**
* Deletes a file or directory with a default timeout of 100 milliseconds.
* Directories are deleted recursively. The timeout occurs on each file.
* If one of the files fails to be deleted, the recursive directory deletion
* is aborted and not retried.
*
* @param file The file or directory to delete.
* @throws IOException
*/
public static void delete(File file) throws IOException {
if (file.isDirectory()) {
File[] files = file.listFiles();
@@ -52,16 +76,20 @@ public class Utils {
}
}
}
for (int i = 0; i < 10; i++) {
if (file.delete() || !file.exists()) return;
if (file.delete() || !file.exists()) {
return;
}
try {
Thread.sleep(10);
}
catch (InterruptedException ignore) {
} catch (InterruptedException ignore) {
Runner.printStackTrace(ignore);
}
}
if (file.exists()) throw new IOException("Cannot delete file " + file);
if (file.exists()) {
throw new IOException("Cannot delete file " + file);
}
}
public static void setExecutable(File file, boolean executable) throws IOException {
@@ -18,6 +18,7 @@ package com.intellij.embedding;
import com.intellij.lang.*;
import com.intellij.lang.impl.PsiBuilderAdapter;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
@@ -26,7 +27,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
* A delegate PsiBuilder that hides or substitutes some tokens (namely, the ones provided by {@link MasqueradingLexer})
@@ -68,45 +68,65 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
@Override
public void advanceLexer() {
// logPos();
myLexPosition++;
skipWhitespace();
synchronizePositions();
// logPos();
synchronizePositions(false);
}
private void synchronizePositions() {
/**
* @param exact if true then positions should be equal;
* else delegate should be behind, not including exactly all foreign (skipped) tokens
*/
private void synchronizePositions(boolean exact) {
final PsiBuilder delegate = getDelegate();
while (!delegate.eof() || myLexPosition < myShrunkSequence.size()) {
if (myLexPosition >= myShrunkSequence.size()) {
if (myLexPosition >= myShrunkSequence.size() || delegate.eof()) {
myLexPosition = myShrunkSequence.size();
while (!delegate.eof()) {
delegate.advanceLexer();
continue;
}
if (delegate.eof()) {
myLexPosition = myShrunkSequence.size();
break;
}
return;
}
if (delegate.getCurrentOffset() > myShrunkSequence.get(myLexPosition).realStart) {
Logger.getInstance(getClass()).error("delegate is ahead of my builder!");
return;
}
final int keepUpPosition = getKeepUpPosition(exact);
while (!delegate.eof()) {
final int delegatePosition = delegate.getCurrentOffset();
final int myPosition = myShrunkSequence.get(myLexPosition).realStart;
if (delegatePosition < myPosition) {
if (delegatePosition < keepUpPosition) {
delegate.advanceLexer();
}
else if (delegatePosition > myPosition) {
myLexPosition++;
}
else {
break;
}
}
}
private int getKeepUpPosition(boolean exact) {
if (exact) {
return myShrunkSequence.get(myLexPosition).realStart;
}
int lexPosition = myLexPosition;
while (lexPosition > 0 && (myShrunkSequence.get(lexPosition - 1).shrunkStart == myShrunkSequence.get(lexPosition).shrunkStart
|| isWhiteSpaceOnPos(lexPosition - 1))) {
lexPosition--;
}
if (lexPosition == 0) {
return myShrunkSequence.get(lexPosition).realStart;
}
return myShrunkSequence.get(lexPosition - 1).realStart + 1;
}
@Override
public IElementType lookAhead(int steps) {
final PsiBuilderImpl delegate = (PsiBuilderImpl)getDelegate();
synchronizePositions();
if (eof()) { // ensure we skip over whitespace if it's needed
return null;
}
@@ -114,7 +134,7 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
while (steps > 0) {
++cur;
while (cur < myShrunkSequence.size() && delegate.whitespaceOrComment(myShrunkSequence.get(cur).elementType)) {
while (cur < myShrunkSequence.size() && isWhiteSpaceOnPos(cur)) {
cur++;
}
@@ -154,7 +174,7 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
if (allIsEmpty()) {
return TokenType.DUMMY_HOLDER;
}
checkWhitespace();
skipWhitespace();
return myLexPosition < myShrunkSequence.size() ? myShrunkSequence.get(myLexPosition).elementType : null;
}
@@ -165,7 +185,7 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
if (allIsEmpty()) {
return getDelegate().getOriginalText().toString();
}
checkWhitespace();
skipWhitespace();
if (myLexPosition >= myShrunkSequence.size()) {
return null;
@@ -175,8 +195,24 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
return myShrunkCharSequence.subSequence(token.shrunkStart, token.shrunkEnd).toString();
}
@Override
public boolean eof() {
boolean isEof = myLexPosition >= myShrunkSequence.size();
if (!isEof) {
return false;
}
synchronizePositions(true);
return true;
}
@Override
public Marker mark() {
// In the case of the topmost node all should be inserted
if (myLexPosition != 0) {
synchronizePositions(true);
}
final Marker mark = super.mark();
return new MyMarker(mark, myLexPosition);
}
@@ -185,12 +221,14 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
return myShrunkSequence.isEmpty() && getDelegate().getOriginalText().length() != 0;
}
private void checkWhitespace() {
while (myLexPosition < myShrunkSequence.size() &&
((PsiBuilderImpl)myDelegate).whitespaceOrComment(myShrunkSequence.get(myLexPosition).elementType)) {
private void skipWhitespace() {
while (myLexPosition < myShrunkSequence.size() && isWhiteSpaceOnPos(myLexPosition)) {
myLexPosition++;
}
synchronizePositions();
}
private boolean isWhiteSpaceOnPos(int pos) {
return ((PsiBuilderImpl)myDelegate).whitespaceOrComment(myShrunkSequence.get(pos).elementType);
}
protected void initShrunkSequence() {
@@ -199,7 +237,6 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
initTokenListAndCharSequence(lexer);
myLexPosition = 0;
// synchronizePositions();
}
private void initTokenListAndCharSequence(MasqueradingLexer lexer) {
@@ -235,7 +272,7 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
@SuppressWarnings({"StringConcatenationInsideStringBufferAppend", "UnusedDeclaration"})
private void logPos() {
final Logger log = Logger.getLogger(this.getClass().getSimpleName());
final Logger log = Logger.getInstance(getClass());
StringBuilder sb = new StringBuilder();
sb.append("\nmyLexPosition=" + myLexPosition + "/" + myShrunkSequence.size());
if (myLexPosition < myShrunkSequence.size()) {
@@ -271,6 +308,11 @@ public class MasqueradingPsiBuilderAdapter extends PsiBuilderAdapter {
this.shrunkStart = shrunkStart;
this.shrunkEnd = shrunkEnd;
}
@Override
public String toString() {
return "MSTk: [" + realStart + ", " + realEnd + "] -> [" + shrunkStart + ", " + shrunkEnd + "]: " + elementType.toString();
}
}
private class MyMarker extends DelegateMarker {