true if there is a data registered for the given anchor within the current rule;
+ * false otherwise
+ */
+ public boolean hasData(@NotNull Anchor anchor) {
+ return myData.containsKey(anchor);
+ }
+
+ /**
+ * Allows to retrieve data associated with the given anchor.
+ *
+ * @param anchor target anchor
+ * @param Integer.MAX_VALUE
* if the number of spaces is not limited. Spaces are deleted if there are
* more than this amount of spaces in the document.
- * @param dependance The text range checked for the presense of line breaks.
+ * @param dependency The text range checked for the presence of line breaks.
* @param keepLineBreaks Whether the existing line breaks between the blocks should be preserved.
* @param keepBlankLines Whether the existing blank lines between the blocks should be preserved.
* @return the spacing setting instance.
*/
public static Spacing createDependentLFSpacing(int minSpaces,
int maxSpaces,
- TextRange dependance,
+ TextRange dependency,
boolean keepLineBreaks,
- int keepBlankLines) {
- return myFactory.createDependentLFSpacing(minSpaces, maxSpaces, dependance, keepLineBreaks, keepBlankLines);
+ int keepBlankLines)
+ {
+ return createDependentLFSpacing(minSpaces, maxSpaces, dependency, keepLineBreaks, keepBlankLines, DependentSpacingRule.DEFAULT);
}
+ /**
+ * Creates a spacing setting instance which uses settings from the given dependent spacing rule if the specified text range changes
+ * its 'has line feed' status during formatting (new line feed is added and the range hasn't contained them before
+ * or it contained line feed(s) and it was removed during formatting).
+ *
+ * Used for formatting rules like the "next line if wrapped" brace placement.
+ *
+ * @param minSpaces The minimum number of spaces that should be present between the blocks
+ * to which the spacing setting instance is related. Spaces are inserted
+ * if there are less than this amount of spaces in the document.
+ * @param maxSpaces The maximum number of spaces that should be present between the blocks
+ * to which the spacing setting instance is related, or Integer.MAX_VALUE
+ * if the number of spaces is not limited. Spaces are deleted if there are
+ * more than this amount of spaces in the document.
+ * @param dependencyRange The text range checked for the presence of line breaks.
+ * @param keepLineBreaks Whether the existing line breaks between the blocks should be preserved.
+ * @param keepBlankLines Whether the existing blank lines between the blocks should be preserved.
+ * @param rule settings to use if dependent region changes its 'contains line feed' status during formatting
+ * @return the spacing setting instance for the given parameters
+ */
+ public static Spacing createDependentLFSpacing(int minSpaces,
+ int maxSpaces,
+ @NotNull TextRange dependencyRange,
+ boolean keepLineBreaks,
+ int keepBlankLines,
+ @NotNull DependentSpacingRule rule)
+ {
+ return myFactory.createDependentLFSpacing(minSpaces, maxSpaces, dependencyRange, keepLineBreaks, keepBlankLines, rule);
+ }
+
/**
* Creates a spacing setting instance which preserves the presence of spaces between the blocks but,
* if spaces are present, may insert or delete the spaces. Used, for example, for HTML formatting
diff --git a/platform/lang-api/src/com/intellij/formatting/SpacingFactory.java b/platform/lang-api/src/com/intellij/formatting/SpacingFactory.java
index 40e6f1f29f27..2c105693a68d 100644
--- a/platform/lang-api/src/com/intellij/formatting/SpacingFactory.java
+++ b/platform/lang-api/src/com/intellij/formatting/SpacingFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,34 +16,43 @@
package com.intellij.formatting;
import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
/**
* Internal interface for creating spacing instances.
*/
interface SpacingFactory {
- public Spacing createSpacing(int minSpaces,
+
+ @NotNull
+ Spacing createSpacing(int minSpaces,
int maxSpaces,
int minLineFeeds,
boolean keepLineBreaks,
int keepBlankLines);
- public Spacing getReadOnlySpacing();
+ @NotNull
+ Spacing getReadOnlySpacing();
+
+ @NotNull
+ Spacing createDependentLFSpacing(int minSpaces,
+ int maxSpaces,
+ @NotNull TextRange dependencyRange,
+ boolean keepLineBreaks,
+ int keepBlankLines,
+ @NotNull DependentSpacingRule rule);
- public Spacing createDependentLFSpacing(int minSpaces,
- int maxSpaces,
- TextRange dependance,
- boolean keepLineBreaks,
- int keepBlankLines);
+ @NotNull
+ Spacing createSafeSpacing(boolean keepLineBreaks,
+ int keepBlankLines);
- public Spacing createSafeSpacing(boolean keepLineBreaks,
- int keepBlankLines);
-
- public Spacing createKeepingFirstColumnSpacing(final int minSpaces,
- final int maxSpaces,
- final boolean keepLineBreaks,
- final int keepBlankLines);
+ @NotNull
+ Spacing createKeepingFirstColumnSpacing(final int minSpaces,
+ final int maxSpaces,
+ final boolean keepLineBreaks,
+ final int keepBlankLines);
+ @NotNull
Spacing createSpacing(final int minSpaces, final int maxSpaces, final int minLineFeeds, final boolean keepLineBreaks,
final int keepBlankLines, final int prefLineFeeds);
}
diff --git a/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java b/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java
index 7f7567838869..b215fad80285 100644
--- a/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java
+++ b/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingBuilder.java
@@ -6,7 +6,6 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -132,7 +131,7 @@ public abstract class CustomFoldingBuilder extends FoldingBuilderEx implements D
* @param node The node which may contain custom region start.
* @return True if the node marks a custom region start.
*/
- protected final boolean isCustomRegionStart(ASTNode node) {
+ public final boolean isCustomRegionStart(ASTNode node) {
if (isCustomFoldingCandidate(node)) {
String nodeText = node.getText();
CustomFoldingProvider defaultProvider = getDefaultProvider(nodeText);
diff --git a/platform/lang-impl/lang-impl.iml b/platform/lang-impl/lang-impl.iml
index c92440432c16..44324243fa93 100644
--- a/platform/lang-impl/lang-impl.iml
+++ b/platform/lang-impl/lang-impl.iml
@@ -23,6 +23,7 @@
'Dependency' here affect {@link #getMinLineFeeds() minLineFieeds} property value. See property contract for more details.
*/
public class DependantSpacingImpl extends SpacingImpl {
- private final TextRange myDependency;
- private static final int DEPENDENCE_CONTAINS_LF_MASK = 0x10;
+ private static final int DEPENDENCE_CONTAINS_LF_MASK = 0x10;
private static final int DEPENDENT_REGION_LF_CHANGED_MASK = 0x20;
+ @NotNull private final TextRange myDependency;
+ @NotNull private final DependentSpacingRule myRule;
+
+
public DependantSpacingImpl(final int minSpaces,
final int maxSpaces,
- TextRange dependency,
+ @NotNull TextRange dependency,
final boolean keepLineBreaks,
- final int keepBlankLines) {
+ final int keepBlankLines,
+ @NotNull DependentSpacingRule rule)
+ {
super(minSpaces, maxSpaces, 0, false, false, keepLineBreaks, keepBlankLines, false, 0);
myDependency = dependency;
+ myRule = rule;
}
/**
* @return 1 if dependency has line feeds; 0 otherwise
*/
public int getMinLineFeeds() {
- if ((myFlags & DEPENDENCE_CONTAINS_LF_MASK) != 0) {
- return 1;
+ if (!isTriggered()) {
+ return super.getMinLineFeeds();
}
- else {
- return 0;
+
+ if (myRule.hasData(DependentSpacingRule.Anchor.MIN_LINE_FEEDS)) {
+ return myRule.getData(DependentSpacingRule.Anchor.MIN_LINE_FEEDS);
}
+
+ if (myRule.hasData(DependentSpacingRule.Anchor.MAX_LINE_FEEDS)) {
+ return myRule.getData(DependentSpacingRule.Anchor.MAX_LINE_FEEDS);
+ }
+ return super.getMinLineFeeds();
+ }
+
+ @Override
+ public int getKeepBlankLines() {
+ if (!isTriggered() || !myRule.hasData(DependentSpacingRule.Anchor.MAX_LINE_FEEDS)) {
+ return super.getKeepBlankLines();
+ }
+
+ return 0;
}
public void refresh(FormatProcessor formatter) {
@@ -58,14 +80,16 @@ public class DependantSpacingImpl extends SpacingImpl {
else myFlags &= ~DEPENDENCE_CONTAINS_LF_MASK;
}
+ @NotNull
public TextRange getDependency() {
return myDependency;
}
/**
- * Allows to answer whether the target dependent regions has been changed during formatting.
+ * Allows to answer whether 'contains line feed' status has been changed for the target dependent region during formatting.
*
- * @return true if target dependent region has been changed during formatting; false otherwise
+ * @return true if target 'contains line feed' status has been changed for the target dependent region during formatting;
+ * false otherwise
*/
public final boolean isDependentRegionChanged() {
return (myFlags & DEPENDENT_REGION_LF_CHANGED_MASK) != 0;
@@ -85,4 +109,9 @@ public class DependantSpacingImpl extends SpacingImpl {
return "'replace whole text' optimization.
*/
private static final int BULK_REPLACE_OPTIMIZATION_CRITERIA = 3000;
-
+
private static final Logger LOG = Logger.getInstance("#com.intellij.formatting.FormatProcessor");
private LeafBlockWrapper myCurrentBlock;
@@ -59,9 +60,9 @@ class FormatProcessor {
private CompositeBlockWrapper myRootBlockWrapper;
private TIntObjectHashMap
* int[] data = {1, 2, 3};
*
- * We want to keep that in one line with possible but place curly braces on separate lines if the width is not enough:
+ * We want to keep that in one line if possible but place curly braces on separate lines if the width is not enough:
*
* int[] data = { | < right margin
* 1, 2, 3 |
@@ -140,11 +141,11 @@ class FormatProcessor {
private final HashSet myAlignAgain = new HashSet();
@NotNull
private final FormattingProgressCallback myProgressCallback;
-
+
private WhiteSpace myLastWhiteSpace;
private boolean myDisposed;
private CommonCodeStyleSettings.IndentOptions myJavaIndentOptions;
-
+
@NotNull
private State myCurrentState;
@@ -164,10 +165,10 @@ class FormatProcessor {
CommonCodeStyleSettings.IndentOptions indentOptions,
@Nullable FormatTextRanges affectedRanges,
int interestingOffset,
- @NotNull FormattingProgressCallback progressCallback)
+ @NotNull FormattingProgressCallback progressCallback)
{
myProgressCallback = progressCallback;
- myIndentOption = indentOptions;
+ myDefaultIndentOption = indentOptions;
mySettings = settings;
myDocument = docModel.getDocument();
myCurrentState = new WrapBlocksState(rootBlock, docModel, affectedRanges, interestingOffset);
@@ -214,7 +215,7 @@ class FormatProcessor {
* from EDT we have no chance of performing any other actions from EDT simultaneously (e.g. we may want to show progress bar
* that reflects current formatting state but the progress bar can' bet updated if formatting is performed during a single long
* method call). So, we can interleave formatting iterations with GUI state updates.
- *
+ *
* @param model target formatting model
* @param sequentially flag that indicates what kind of processing should be used
*/
@@ -232,9 +233,9 @@ class FormatProcessor {
/**
* Asks current processor to perform processing iteration
- *
+ *
* @return true if the processing is finished; false otherwise
- * @see #format(FormattingModel, boolean)
+ * @see #format(FormattingModel, boolean)
*/
public boolean iteration() {
if (myCurrentState.isDone()) {
@@ -250,19 +251,19 @@ class FormatProcessor {
public void stopSequentialProcessing() {
myCurrentState.stop();
}
-
+
public void formatWithoutRealModifications() {
formatWithoutRealModifications(false);
}
-
+
@SuppressWarnings({"WhileLoopSpinsOnField"})
public void formatWithoutRealModifications(boolean sequentially) {
myCurrentState.setNext(new AdjustWhiteSpacesState());
-
+
if (sequentially) {
return;
}
-
+
doIterationsSynchronously(FormattingStateId.PROCESSING_BLOCKS);
}
@@ -279,11 +280,11 @@ class FormatProcessor {
public void performModifications(FormattingModel model) {
performModifications(model, false);
}
-
+
public void performModifications(FormattingModel model, boolean sequentially) {
assert !myDisposed;
myCurrentState.setNext(new ApplyChangesState(model));
-
+
if (sequentially) {
return;
}
@@ -292,9 +293,9 @@ class FormatProcessor {
}
/**
- * Perform iterations against the {@link #myCurrentState current state} until it's {@link FormattingStateId type}
+ * Perform iterations against the {@link #myCurrentState current state} until it's {@link FormattingStateId type}
* is {@link FormattingStateId#getPreviousStates() less} or equal to the given state.
- *
+ *
* @param state target state to process
*/
private void doIterationsSynchronously(@NotNull FormattingStateId state) {
@@ -304,7 +305,7 @@ class FormatProcessor {
myCurrentState.iteration();
}
}
-
+
public void setJavaIndentOptions(final CommonCodeStyleSettings.IndentOptions javaIndentOptions) {
myJavaIndentOptions = javaIndentOptions;
}
@@ -312,7 +313,7 @@ class FormatProcessor {
/**
* Decides whether applying formatter changes should be applied incrementally one-by-one or merge result should be
* constructed locally and the whole document text should be replaced. Performs such single bulk change if necessary.
- *
+ *
* @param blocksToModify changes introduced by formatter
* @param model current formatting model
* @param indentOption indent options to use
@@ -320,8 +321,8 @@ class FormatProcessor {
* false otherwise
*/
@SuppressWarnings({"deprecation"})
- private static boolean applyChangesAtBulkMode(final List blocksToModify, final FormattingModel model,
- CommonCodeStyleSettings.IndentOptions indentOption)
+ private boolean applyChangesAtBulkMode(final List blocksToModify, final FormattingModel model,
+ @NotNull CommonCodeStyleSettings.IndentOptions indentOption)
{
FormattingDocumentModel documentModel = model.getDocumentModel();
Document document = documentModel.getDocument();
@@ -335,7 +336,8 @@ class FormatProcessor {
for (LeafBlockWrapper block : blocksToModify) {
WhiteSpace whiteSpace = block.getWhiteSpace();
CharSequence newWs = documentModel.adjustWhiteSpaceIfNecessary(
- whiteSpace.generateWhiteSpace(indentOption), whiteSpace.getStartOffset(), whiteSpace.getEndOffset(), false
+ whiteSpace.generateWhiteSpace(getIndentOptionsToUse(block, indentOption)), whiteSpace.getStartOffset(),
+ whiteSpace.getEndOffset(), false
);
if (changes.size() > 10000) {
CharSequence mergeResult = BulkChangesMerger.INSTANCE.mergeToCharSequence(document.getChars(), document.getTextLength(), changes);
@@ -361,7 +363,7 @@ class FormatProcessor {
}
blocks.clear();
}
-
+
@Nullable
private static DocumentEx getAffectedDocument(final FormattingModel model) {
if (model instanceof DocumentBasedFormattingModel) {
@@ -408,7 +410,7 @@ class FormatProcessor {
for (LeafBlockWrapper block = myFirstTokenBlock; block != null; block = block.getNextBlock()) {
final WhiteSpace whiteSpace = block.getWhiteSpace();
if (!whiteSpace.isReadOnly()) {
- final String newWhiteSpace = whiteSpace.generateWhiteSpace(myIndentOption);
+ final String newWhiteSpace = whiteSpace.generateWhiteSpace(getIndentOptionsToUse(block, myDefaultIndentOption));
if (!whiteSpace.equalsToString(newWhiteSpace)) {
blocksToModify.add(block);
}
@@ -417,6 +419,22 @@ class FormatProcessor {
return blocksToModify;
}
+ @NotNull
+ private CommonCodeStyleSettings.IndentOptions getIndentOptionsToUse(@NotNull AbstractBlockWrapper block,
+ @NotNull CommonCodeStyleSettings.IndentOptions fallbackIndentOptions)
+ {
+ final Language language = block.getLanguage();
+ if (language == null) {
+ return fallbackIndentOptions;
+ }
+ final CommonCodeStyleSettings commonSettings = mySettings.getCommonSettings(language);
+ if (commonSettings == null) {
+ return fallbackIndentOptions;
+ }
+ final CommonCodeStyleSettings.IndentOptions result = commonSettings.getIndentOptions();
+ return result == null ? fallbackIndentOptions : result;
+ }
+
private static TextRange shiftRange(final TextRange textRange, final int shift) {
return new TextRange(textRange.getStartOffset() + shift, textRange.getEndOffset() + shift);
}
@@ -593,8 +611,8 @@ class FormatProcessor {
private boolean isCandidateToBeWrapped(final WrapImpl wrap) {
return isSuitableInTheCurrentPosition(wrap) &&
- (wrap.getType() == WrapImpl.Type.WRAP_AS_NEEDED || wrap.getType() == WrapImpl.Type.CHOP_IF_NEEDED) &&
- !myCurrentBlock.getWhiteSpace().isReadOnly();
+ (wrap.getType() == WrapImpl.Type.WRAP_AS_NEEDED || wrap.getType() == WrapImpl.Type.CHOP_IF_NEEDED) &&
+ !myCurrentBlock.getWhiteSpace().isReadOnly();
}
private void onCurrentLineChanged() {
@@ -627,9 +645,10 @@ class FormatProcessor {
LOG.error(String.format("Can't find alignment processor for alignment anchor %s", alignment.getAnchor()));
return true;
}
-
+
BlockAlignmentProcessor.Context context = new BlockAlignmentProcessor.Context(
- myDocument, alignment, myCurrentBlock, myAlignmentMappings, myBackwardShiftedAlignedBlocks, myIndentOption
+ myDocument, alignment, myCurrentBlock, myAlignmentMappings, myBackwardShiftedAlignedBlocks,
+ getIndentOptionsToUse(myCurrentBlock, myDefaultIndentOption)
);
BlockAlignmentProcessor.Result result = alignmentProcessor.applyAlignment(context);
final LeafBlockWrapper offsetResponsibleBlock = alignment.getOffsetRespBlockBefore(myCurrentBlock);
@@ -704,7 +723,7 @@ class FormatProcessor {
}
private void adjustSpacingByIndentOffset() {
- IndentData offset = myCurrentBlock.calculateOffset(myIndentOption);
+ IndentData offset = myCurrentBlock.calculateOffset(getIndentOptionsToUse(myCurrentBlock, myDefaultIndentOption));
myCurrentBlock.getWhiteSpace().setSpaces(offset.getSpaces(), offset.getIndentSpaces());
}
@@ -921,11 +940,11 @@ class FormatProcessor {
ChildAttributesInfo info = getChildAttributesInfo(block, index, parent);
if (info == null) {
return new IndentInfo(0, 0, 0);
- }
+ }
return adjustLineIndent(info.parent, info.attributes, info.index);
}
-
+
@Nullable
private static ChildAttributesInfo getChildAttributesInfo(@NotNull final Block block,
final int index,
@@ -972,7 +991,7 @@ class FormatProcessor {
private IndentInfo adjustLineIndent(final AbstractBlockWrapper parent, final ChildAttributes childAttributes, final int index) {
int alignOffset = getAlignOffsetBefore(childAttributes.getAlignment(), null);
if (alignOffset == -1) {
- return parent.calculateChildOffset(myIndentOption, childAttributes, index).createIndentInfo();
+ return parent.calculateChildOffset(getIndentOptionsToUse(parent, myDefaultIndentOption), childAttributes, index).createIndentInfo();
}
else {
AbstractBlockWrapper indentedParentBlock = CoreFormatterUtil.getIndentedParentBlock(myCurrentBlock);
@@ -1062,8 +1081,8 @@ class FormatProcessor {
if (current.getEndOffset() <= offset) {
while (!current.isIncomplete() &&
- current.getParent() != null &&
- current.getParent().getEndOffset() <= offset) {
+ current.getParent() != null &&
+ current.getParent().getEndOffset() <= offset) {
current = current.getParent();
}
if (current.isIncomplete()) return current;
@@ -1101,7 +1120,7 @@ class FormatProcessor {
/**
* There is a possible case that particular block is a composite block that contains number of nested composite blocks
* that all target the same text range. This method allows to derive the most nested block that shares the same range (if any).
- *
+ *
* @param block block to check
* @return the most nested block of the given one that shares the same text range if any; given block otherwise
*/
@@ -1110,7 +1129,7 @@ class FormatProcessor {
if (!(block instanceof CompositeBlockWrapper)) {
return block;
}
-
+
AbstractBlockWrapper result = block;
AbstractBlockWrapper candidate = block;
while (true) {
@@ -1180,11 +1199,11 @@ class FormatProcessor {
}
}
}
-
+
private abstract class State {
private final FormattingStateId myStateId;
-
+
private State myNextState;
private boolean myDone;
@@ -1221,10 +1240,10 @@ class FormatProcessor {
public void stop() {
}
-
+
protected abstract void doIteration();
protected abstract void prepare();
-
+
private void shiftStateIfNecessary() {
if (isDone() && myNextState != null) {
myCurrentState = myNextState;
@@ -1233,7 +1252,7 @@ class FormatProcessor {
}
}
}
-
+
private class WrapBlocksState extends State {
private final InitialInfoBuilder myWrapper;
@@ -1247,7 +1266,7 @@ class FormatProcessor {
super(FormattingStateId.WRAPPING_BLOCKS);
myModel = model;
myWrapper = InitialInfoBuilder.prepareToBuildBlocksSequentially(
- root, model, affectedRanges, myIndentOption, interestingOffset, myProgressCallback
+ root, model, affectedRanges, myDefaultIndentOption, interestingOffset, myProgressCallback
);
}
@@ -1260,7 +1279,7 @@ class FormatProcessor {
if (isDone()) {
return;
}
-
+
setDone(myWrapper.iteration());
if (!isDone()) {
return;
@@ -1273,10 +1292,10 @@ class FormatProcessor {
myCurrentBlock = myFirstTokenBlock;
myTextRangeToWrapper = buildTextRangeToInfoMap(myFirstTokenBlock);
myLastWhiteSpace = new WhiteSpace(getLastBlock().getEndOffset(), false);
- myLastWhiteSpace.append(myModel.getTextLength(), myModel, myIndentOption);
+ myLastWhiteSpace.append(myModel.getTextLength(), myModel, myDefaultIndentOption);
}
}
-
+
private class AdjustWhiteSpacesState extends State {
AdjustWhiteSpacesState() {
@@ -1294,11 +1313,11 @@ class FormatProcessor {
if (blockToProcess != null) {
myProgressCallback.afterProcessingBlock(blockToProcess);
}
-
+
if (myCurrentBlock != null) {
return;
}
-
+
if (myAlignAgain.isEmpty()) {
setDone(true);
}
@@ -1309,7 +1328,7 @@ class FormatProcessor {
}
}
}
-
+
private class ApplyChangesState extends State {
private final FormattingModel myModel;
@@ -1343,7 +1362,7 @@ class FormatProcessor {
setDone(true);
return;
}
-
+
//for GeneralCodeFormatterTest
if (myJavaIndentOptions == null) {
myJavaIndentOptions = mySettings.getIndentOptions(StdFileTypes.JAVA);
@@ -1358,7 +1377,9 @@ class FormatProcessor {
updatedDocument.setInBulkUpdate(true);
myResetBulkUpdateState = true;
}
- if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA && applyChangesAtBulkMode(myBlocksToModify, myModel, myIndentOption)) {
+ if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA
+ && applyChangesAtBulkMode(myBlocksToModify, myModel, myDefaultIndentOption))
+ {
setDone(true);
}
}
@@ -1367,7 +1388,11 @@ class FormatProcessor {
protected void doIteration() {
LeafBlockWrapper blockWrapper = myBlocksToModify.get(myIndex);
myShift = replaceWhiteSpace(
- myModel, blockWrapper, myShift, blockWrapper.getWhiteSpace().generateWhiteSpace(myIndentOption), myJavaIndentOptions
+ myModel,
+ blockWrapper,
+ myShift,
+ blockWrapper.getWhiteSpace().generateWhiteSpace(getIndentOptionsToUse(blockWrapper, myDefaultIndentOption)),
+ myJavaIndentOptions
);
myProgressCallback.afterApplyingChange(blockWrapper);
// block could be gc'd
@@ -1375,7 +1400,7 @@ class FormatProcessor {
blockWrapper.dispose();
myBlocksToModify.set(myIndex, null);
myIndex++;
-
+
if (myIndex >= myBlocksToModify.size()) {
setDone(true);
}
@@ -1384,7 +1409,7 @@ class FormatProcessor {
@Override
protected void setDone(boolean done) {
super.setDone(done);
-
+
if (myResetBulkUpdateState) {
DocumentEx document = getAffectedDocument(myModel);
if (document != null) {
@@ -1392,7 +1417,7 @@ class FormatProcessor {
myResetBulkUpdateState = false;
}
}
-
+
if (done) {
myModel.commitChanges();
}
diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
index 0b47d69e55ef..afefeb6b6774 100644
--- a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
+++ b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
@@ -133,6 +133,7 @@ public class FormatterImpl extends FormatterEx
return result;
}
+ @NotNull
public Spacing createSpacing(int minOffset,
int maxOffset,
int minLineFeeds,
@@ -141,13 +142,21 @@ public class FormatterImpl extends FormatterEx
return getSpacingImpl(minOffset, maxOffset, minLineFeeds, false, false, keepLineBreaks, keepBlankLines,false, 0);
}
+ @NotNull
public Spacing getReadOnlySpacing() {
return myReadOnlySpacing;
}
-
- public Spacing createDependentLFSpacing(int minOffset, int maxOffset, TextRange dependence, boolean keepLineBreaks,
- int keepBlankLines) {
- return new DependantSpacingImpl(minOffset, maxOffset, dependence, keepLineBreaks, keepBlankLines);
+
+ @NotNull
+ @Override
+ public Spacing createDependentLFSpacing(int minSpaces,
+ int maxSpaces,
+ @NotNull TextRange dependencyRange,
+ boolean keepLineBreaks,
+ int keepBlankLines,
+ @NotNull DependentSpacingRule rule)
+ {
+ return new DependantSpacingImpl(minSpaces, maxSpaces, dependencyRange, keepLineBreaks, keepBlankLines, rule);
}
@NotNull
@@ -669,10 +678,12 @@ public class FormatterImpl extends FormatterEx
return myAbsoluteLabelIndent;
}
+ @NotNull
public Spacing createSafeSpacing(final boolean shouldKeepLineBreaks, final int keepBlankLines) {
return getSpacingImpl(0, 0, 0, false, true, shouldKeepLineBreaks, keepBlankLines, false, 0);
}
+ @NotNull
public Spacing createKeepingFirstColumnSpacing(final int minSpace,
final int maxSpace,
final boolean keepLineBreaks,
@@ -680,6 +691,7 @@ public class FormatterImpl extends FormatterEx
return getSpacingImpl(minSpace, maxSpace, -1, false, false, keepLineBreaks, keepBlankLines, true, 0);
}
+ @NotNull
public Spacing createSpacing(final int minSpaces, final int maxSpaces, final int minLineFeeds, final boolean keepLineBreaks, final int keepBlankLines,
final int prefLineFeeds) {
return getSpacingImpl(minSpaces, maxSpaces, -1, false, false, keepLineBreaks, keepBlankLines, false, prefLineFeeds);
diff --git a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java
index 1ee76f43d19a..7350201edbb8 100644
--- a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java
+++ b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java
@@ -126,8 +126,8 @@ class InitialInfoBuilder {
@Nullable final CompositeBlockWrapper parent,
@Nullable WrapImpl currentWrapParent,
@Nullable final Block parentBlock,
- boolean rootBlockIsRightBlock
- ) {
+ boolean rootBlockIsRightBlock)
+ {
final WrapImpl wrap = (WrapImpl)rootBlock.getWrap();
if (wrap != null) {
wrap.registerParent(currentWrapParent);
diff --git a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java
index 108e089ab6cf..e721405fa300 100644
--- a/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java
+++ b/platform/lang-impl/src/com/intellij/formatting/templateLanguages/DataLanguageBlockWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,9 @@ package com.intellij.formatting.templateLanguages;
import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;
+import com.intellij.lang.Language;
import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.formatter.common.AbstractBlock;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import org.jetbrains.annotations.NotNull;
@@ -31,9 +33,10 @@ import java.util.List;
* Date: Jun 30, 2009
* Time: 7:18:37 PM
*/
-public class DataLanguageBlockWrapper implements ASTBlock, BlockWithParent {
+public class DataLanguageBlockWrapper implements ASTBlock, BlockEx, BlockWithParent {
private final Block myOriginal;
private final Indent myIndent;
+ @Nullable private final Language myLanguage;
private List myBlocks;
private List myTlBlocks;
private BlockWithParent myParent;
@@ -44,8 +47,18 @@ public class DataLanguageBlockWrapper implements ASTBlock, BlockWithParent {
assert !(original instanceof DataLanguageBlockWrapper) && !(original instanceof TemplateLanguageBlock);
myOriginal = original;
myIndent = indent;
- }
+ final ASTNode node = getNode();
+ Language language = null;
+ if (node != null) {
+ final PsiElement psi = node.getPsi();
+ if (psi != null) {
+ language = psi.getLanguage();
+ }
+ }
+ myLanguage = language;
+ }
+
@NotNull
public TextRange getTextRange() {
return myOriginal.getTextRange();
@@ -59,6 +72,13 @@ public class DataLanguageBlockWrapper implements ASTBlock, BlockWithParent {
return myBlocks;
}
+ @Nullable
+ @Override
+ public Language getLanguage() {
+ // Use base language code style settings for the template blocks.
+ return myLanguage;
+ }
+
private List buildBlocks() {
assert myBlocks == null;
if (isLeaf()) {
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/nodes/TodoFileNode.java b/platform/lang-impl/src/com/intellij/ide/todo/nodes/TodoFileNode.java
index 6a629737c801..1c16566a1fd0 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/nodes/TodoFileNode.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/nodes/TodoFileNode.java
@@ -31,7 +31,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.search.TodoItemImpl;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.search.PsiTodoSearchHelper;
import com.intellij.psi.search.TodoItem;
import com.intellij.ui.HighlightedRegion;
@@ -102,7 +102,7 @@ public final class TodoFileNode extends PsiFileNode implements HighlightedRegion
@Override
public void visitElement(PsiElement element) {
if (element instanceof PsiLanguageInjectionHost) {
- InjectedLanguageFacadeImpl.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ InjectedLanguageUtil.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) {
if (places.size() == 1) {
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java
index ff69f00bccb2..46341c274783 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindow.java
@@ -43,7 +43,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -113,7 +113,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
if (!editorWindow.isValid()) {
editorWindow.dispose();
- InjectedLanguageFacadeImpl.clearCaches(editorWindow.myInjectedFile, editorWindow.getDocument());
+ InjectedLanguageUtil.clearCaches(editorWindow.myInjectedFile, editorWindow.getDocument());
iterator.remove();
}
}
diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
index 0556784022bc..ee7a882a21a3 100644
--- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
+++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
@@ -23,7 +23,7 @@ import com.intellij.formatting.ASTBlock;
import com.intellij.formatting.Block;
import com.intellij.formatting.FormattingModel;
import com.intellij.formatting.FormattingModelBuilder;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeRenderer;
@@ -821,7 +821,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
if (currentElem == null) {
currentElem =
- InjectedLanguageFacadeImpl
+ InjectedLanguageUtil
.findElementAtNoCommit(psiEl.getContainingFile(), rootBlockNode.getBlock().getTextRange().getStartOffset());
}
myPsiToBlockMap.put(currentElem, rootBlockNode);
@@ -980,7 +980,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
BlockTreeNode descriptor = (BlockTreeNode)blockElementsSet.iterator().next();
PsiElement rootPsi = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
int blockStart = descriptor.getBlock().getTextRange().getStartOffset();
- PsiElement currentPsiEl = InjectedLanguageFacadeImpl.findElementAtNoCommit(rootPsi.getContainingFile(), blockStart);
+ PsiElement currentPsiEl = InjectedLanguageUtil.findElementAtNoCommit(rootPsi.getContainingFile(), blockStart);
int blockLength = descriptor.getBlock().getTextRange().getLength();
while (currentPsiEl.getParent() != null &&
currentPsiEl.getTextRange().getStartOffset() == blockStart &&
@@ -1237,7 +1237,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final PsiElement rootElement = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
int baseOffset = rootPsiElement.getTextRange().getStartOffset();
final int offset = myEditor.getCaretModel().getOffset() + baseOffset;
- final PsiElement element = InjectedLanguageFacadeImpl.findElementAtNoCommit(rootElement.getContainingFile(), offset);
+ final PsiElement element = InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), offset);
if (element != null && myBlockTreeBuilder != null) {
TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
selectBlockNode(findBlockNode(rangeInHostFile, true));
@@ -1258,8 +1258,8 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final int start = selection.getSelectionStart()+baseOffset;
final int end = selection.getSelectionEnd()+baseOffset - 1;
final PsiElement element =
- findCommonParent(InjectedLanguageFacadeImpl.findElementAtNoCommit(rootElement.getContainingFile(), start),
- InjectedLanguageFacadeImpl.findElementAtNoCommit(rootElement.getContainingFile(), end));
+ findCommonParent(InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), start),
+ InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), end));
if (element != null && myBlockTreeBuilder != null) {
if (myEditor.getContentComponent().hasFocus()) {
TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/ViewerTreeStructure.java b/platform/lang-impl/src/com/intellij/internal/psiView/ViewerTreeStructure.java
index 3f037ebdece6..48f1e2d4c506 100644
--- a/platform/lang-impl/src/com/intellij/internal/psiView/ViewerTreeStructure.java
+++ b/platform/lang-impl/src/com/intellij/internal/psiView/ViewerTreeStructure.java
@@ -29,7 +29,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -99,7 +99,7 @@ public class ViewerTreeStructure extends AbstractTreeStructure {
}
final PsiElement psi = root.getPsi();
if (psi instanceof PsiLanguageInjectionHost) {
- InjectedLanguageFacadeImpl.enumerate(psi, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ InjectedLanguageUtil.enumerate(psi, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) {
list.add(new Inject(psi, injectedPsi));
diff --git a/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionAction.java b/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionAction.java
new file mode 100644
index 000000000000..9a45520091ef
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionAction.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.customFolding;
+
+import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class GotoCustomRegionAction extends AnAction implements DumbAware {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final Project project = e.getProject();
+ final Editor editor = e.getData(PlatformDataKeys.EDITOR);
+ if (Boolean.TRUE.equals(e.getData(PlatformDataKeys.IS_MODAL_CONTEXT))) {
+ return;
+ }
+ if (project != null && editor != null) {
+ if (DumbService.getInstance(project).isDumb()) {
+ DumbService.getInstance(project).showDumbModeNotification(IdeBundle.message("goto.custom.region.message.dumb.mode"));
+ return;
+ }
+ CommandProcessor processor = CommandProcessor.getInstance();
+ processor.executeCommand(
+ project,
+ new Runnable() {
+ public void run() {
+ GotoCustomRegionDialog dialog = new GotoCustomRegionDialog(project, editor);
+ dialog.show();
+ if (dialog.isOK()) {
+ PsiElement navigationElement = dialog.getNavigationElement();
+ if (navigationElement != null) {
+ navigateTo(editor, navigationElement);
+ IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation();
+ }
+ }
+ }
+ },
+ IdeBundle.message("goto.custom.region.command"),
+ null);
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ Presentation presentation = e.getPresentation();
+ presentation.setText("Custom Region...");
+ final Editor editor = e.getData(PlatformDataKeys.EDITOR);
+ final Project project = e.getProject();
+ boolean isAvailable = editor != null && project != null;
+ presentation.setEnabled(isAvailable);
+ presentation.setVisible(isAvailable);
+ }
+
+ private static void navigateTo(Editor editor, PsiElement element) {
+ int offset = element.getTextRange().getStartOffset();
+ if (offset >= 0 && offset < editor.getDocument().getTextLength()) {
+ editor.getCaretModel().moveToOffset(offset);
+ editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
+ editor.getSelectionModel().removeSelection();
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionDialog.form b/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionDialog.form
new file mode 100644
index 000000000000..cf1369bd01a7
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionDialog.form
@@ -0,0 +1,25 @@
+
+
diff --git a/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionDialog.java b/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionDialog.java
new file mode 100644
index 000000000000..8873074402e3
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/lang/customFolding/GotoCustomRegionDialog.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.customFolding;
+
+import com.intellij.ide.IdeBundle;
+import com.intellij.lang.Language;
+import com.intellij.lang.folding.*;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.components.JBScrollPane;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Rustam Vishnyakov
+ */
+public class GotoCustomRegionDialog extends DialogWrapper {
+ private JBList myRegionsList;
+ private JPanel myContentPane;
+ private JBScrollPane myScrollPane;
+ private final Editor myEditor;
+ private final Project myProject;
+
+ protected GotoCustomRegionDialog(@Nullable Project project, @NotNull Editor editor) {
+ super(project);
+ myEditor = editor;
+ myProject = project;
+ Collection descriptors = getCustomFoldingDescriptors();
+ init();
+ if (descriptors.size() == 0) {
+ myScrollPane.setVisible(false);
+ myContentPane.add(new JLabel(IdeBundle.message("goto.custom.region.message.unavailable")), BorderLayout.NORTH);
+ setOKActionEnabled(false);
+ }
+ else {
+ myRegionsList.setModel(new MyListModel(orderByPosition(descriptors)));
+ myRegionsList.setSelectedIndex(0);
+ }
+ setTitle(IdeBundle.message("goto.custom.region.command"));
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ if (!myRegionsList.isEmpty()) {
+ return myRegionsList;
+ }
+ return super.getPreferredFocusedComponent();
+ }
+
+ @Override
+ protected JComponent createCenterPanel() {
+ return myContentPane;
+ }
+
+ private Collection getCustomFoldingDescriptors() {
+ Set foldingDescriptors = new HashSet();
+ final Document document = myEditor.getDocument();
+ PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
+ PsiFile file = documentManager != null ? documentManager.getPsiFile(document) : null;
+ if (file != null) {
+ final FileViewProvider viewProvider = file.getViewProvider();
+ for (final Language language : viewProvider.getLanguages()) {
+ final PsiFile psi = viewProvider.getPsi(language);
+ final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(language);
+ if (psi != null) {
+ for (FoldingDescriptor descriptor : LanguageFolding.buildFoldingDescriptors(foldingBuilder, psi, document, false)) {
+ CustomFoldingBuilder customFoldingBuilder = getCustomFoldingBuilder(foldingBuilder, descriptor);
+ if (customFoldingBuilder != null) {
+ if (customFoldingBuilder.isCustomRegionStart(descriptor.getElement())) {
+ foldingDescriptors.add(descriptor);
+ }
+ }
+ }
+ }
+ }
+ }
+ return foldingDescriptors;
+ }
+
+ private static Collection orderByPosition(Collection descriptors) {
+ List sorted = new ArrayList(descriptors.size());
+ sorted.addAll(descriptors);
+ Collections.sort(sorted, new Comparator() {
+ @Override
+ public int compare(FoldingDescriptor descriptor1, FoldingDescriptor descriptor2) {
+ int pos1 = descriptor1.getElement().getTextRange().getStartOffset();
+ int pos2 = descriptor2.getElement().getTextRange().getStartOffset();
+ return pos1 - pos2;
+ }
+ });
+ return sorted;
+ }
+
+ private void createUIComponents() {
+ myRegionsList = new JBList();
+ myRegionsList.setPreferredSize(new Dimension(200, 100));
+ }
+
+ @Nullable
+ private static CustomFoldingBuilder getCustomFoldingBuilder(FoldingBuilder builder, FoldingDescriptor descriptor) {
+ if (builder instanceof CustomFoldingBuilder) return (CustomFoldingBuilder)builder;
+ FoldingBuilder originalBuilder = descriptor.getElement().getUserData(CompositeFoldingBuilder.FOLDING_BUILDER);
+ if (originalBuilder instanceof CustomFoldingBuilder) return (CustomFoldingBuilder)originalBuilder;
+ return null;
+ }
+
+
+ private static class MyListModel extends DefaultListModel {
+ private MyListModel(Collection descriptors) {
+ for (FoldingDescriptor descriptor : descriptors) {
+ super.addElement(new MyFoldingDescriptorWrapper(descriptor));
+ }
+ }
+ }
+
+ private static class MyFoldingDescriptorWrapper {
+ private final @NotNull FoldingDescriptor myDescriptor;
+
+ private MyFoldingDescriptorWrapper(@NotNull FoldingDescriptor descriptor) {
+ myDescriptor = descriptor;
+ }
+
+ @NotNull
+ public FoldingDescriptor getDescriptor() {
+ return myDescriptor;
+ }
+
+ @Nullable
+ @Override
+ public String toString() {
+ return myDescriptor.getPlaceholderText();
+ }
+ }
+
+ @Nullable
+ public PsiElement getNavigationElement() {
+ Object selection = myRegionsList.getSelectedValue();
+ if (selection instanceof MyFoldingDescriptorWrapper) {
+ return ((MyFoldingDescriptorWrapper)selection).getDescriptor().getElement().getPsi();
+ }
+ return null;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java
index e35ddf938039..d5761461754b 100644
--- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java
@@ -27,7 +27,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.problems.WolfTheProblemSolver;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.docking.DockManager;
import org.jetbrains.annotations.NotNull;
@@ -99,7 +99,7 @@ public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl {
return editor;
}
- return InjectedLanguageFacadeImpl.getEditorForInjectedLanguageNoCommit(editor, psiFile);
+ return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, psiFile);
}
/**
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java
index ef799405eea6..0238e016a128 100644
--- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java
+++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorPsiDataProvider.java
@@ -28,7 +28,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilBase;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +48,7 @@ public class TextEditorPsiDataProvider implements EditorDataProvider {
return e;
}
else {
- return InjectedLanguageFacadeImpl.getEditorForInjectedLanguageNoCommit(e, getPsiFile(e, file));
+ return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(e, getPsiFile(e, file));
}
}
if (dataId.equals(injectedId(PSI_ELEMENT.getName()))) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java
index 1fe19548c3e9..e7885e247551 100644
--- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java
@@ -285,7 +285,7 @@ public class ModuleImpl extends ComponentManagerImpl implements ModuleEx {
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
if (myName == null) return "Module (not initialized)";
- return "Module: '" + getName() + "' " +(isDisposed() ? "(Disposed)" : "path: '" + getModuleFilePath() + "'");
+ return "Module: '" + getName();
}
private static String moduleNameByFileName(@NotNull String fileName) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/paths/StaticPathReferenceProvider.java b/platform/lang-impl/src/com/intellij/openapi/paths/StaticPathReferenceProvider.java
index c6a15535bc30..7928ae5c37e8 100644
--- a/platform/lang-impl/src/com/intellij/openapi/paths/StaticPathReferenceProvider.java
+++ b/platform/lang-impl/src/com/intellij/openapi/paths/StaticPathReferenceProvider.java
@@ -20,10 +20,10 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
+import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -64,7 +64,7 @@ public class StaticPathReferenceProvider extends PathReferenceProviderBase {
@Nullable
public PathReference getPathReference(@NotNull final String path, @NotNull final PsiElement element) {
- final ArrayList list = new ArrayList(5);
+ final List list = new SmartList();
createReferences(element, list, true);
if (list.isEmpty()) return null;
diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/FormattingDocumentModelImpl.java b/platform/lang-impl/src/com/intellij/psi/formatter/FormattingDocumentModelImpl.java
index c0ab0725a6c1..c177b80b5dee 100644
--- a/platform/lang-impl/src/com/intellij/psi/formatter/FormattingDocumentModelImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/formatter/FormattingDocumentModelImpl.java
@@ -28,7 +28,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.impl.PsiToDocumentSynchronizer;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -128,7 +128,7 @@ public class FormattingDocumentModelImpl implements FormattingDocumentModel {
if (strategy.check(myDocument.getCharsSequence(), startOffset, endOffset) >= endOffset) {
return true;
}
- PsiElement injectedElement = myFile != null ? InjectedLanguageFacadeImpl.findElementAtNoCommit(myFile, startOffset) : null;
+ PsiElement injectedElement = myFile != null ? InjectedLanguageUtil.findElementAtNoCommit(myFile, startOffset) : null;
if (injectedElement != null) {
Language injectedLanguage = injectedElement.getLanguage();
if (!injectedLanguage.equals(myFile.getLanguage())) {
diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java b/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java
index 68bcf08c59ba..5fb63836e61d 100644
--- a/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java
+++ b/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java
@@ -28,7 +28,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.TokenType;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -117,7 +117,7 @@ public class PsiBasedFormattingModel implements FormattingModel {
Project project = containingFile.getProject();
assert !PsiDocumentManager.getInstance(project).isUncommited(myDocumentModel.getDocument());
// TODO:default project can not be used for injections, because latter might wants (unavailable) indices
- PsiElement psiElement = project.isDefault() ? null : InjectedLanguageFacadeImpl.findInjectedElementNoCommit(containingFile, offset);
+ PsiElement psiElement = project.isDefault() ? null : InjectedLanguageUtil.findInjectedElementNoCommit(containingFile, offset);
if (psiElement == null) psiElement = containingFile.findElementAt(offset);
if (psiElement == null) return null;
return psiElement.getNode();
diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java b/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java
index 4d06bdc3b8e5..7070493c72a1 100644
--- a/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java
+++ b/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockBuilder.java
@@ -27,7 +27,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -76,7 +76,7 @@ public abstract class InjectedLanguageBlockBuilder {
}
}
};
- InjectedLanguageFacadeImpl.enumerate(injectionHost.getPsi(), injectedPsiVisitor);
+ InjectedLanguageUtil.enumerate(injectionHost.getPsi(), injectedPsiVisitor);
if (injectedFile[0] != null) {
final Language childLanguage = injectedFile[0].getLanguage();
diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockWrapper.java b/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockWrapper.java
index 717973a5c62c..38b968f912f6 100644
--- a/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockWrapper.java
+++ b/platform/lang-impl/src/com/intellij/psi/formatter/common/InjectedLanguageBlockWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -132,7 +132,7 @@ public final class InjectedLanguageBlockWrapper implements Block {
DependantSpacingImpl hostSpacing = (DependantSpacingImpl)spacing;
return new DependantSpacingImpl(
hostSpacing.getMinSpaces(), hostSpacing.getMaxSpaces(), hostSpacing.getDependency().shiftRight(shift),
- hostSpacing.shouldKeepLineFeeds(), hostSpacing.getKeepBlankLines()
+ hostSpacing.shouldKeepLineFeeds(), hostSpacing.getKeepBlankLines(), DependentSpacingRule.DEFAULT
);
}
return spacing;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java
index e251006a5428..f4a0db2a0ab2 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/InjectedSelfElementInfo.java
@@ -25,7 +25,7 @@ import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
@@ -86,7 +86,7 @@ class InjectedSelfElementInfo extends SelfElementInfo {
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(hostFile.getProject());
Document document = documentManager.getDocument(hostFile);
if (document != null && documentManager.isUncommited(document)) {
- for (DocumentWindow documentWindow : InjectedLanguageFacadeImpl.getCachedInjectedDocuments(hostFile)) {
+ for (DocumentWindow documentWindow : InjectedLanguageUtil.getCachedInjectedDocuments(hostFile)) {
PsiFile injected = documentManager.getPsiFile(documentWindow);
if (injected != null) {
visitor.visit(injected, Collections.emptyList());
@@ -94,7 +94,7 @@ class InjectedSelfElementInfo extends SelfElementInfo {
}
}
else {
- InjectedLanguageFacadeImpl.enumerate(hostContext, hostFile, true, visitor);
+ InjectedLanguageUtil.enumerate(hostContext, hostFile, true, visitor);
}
return result.get();
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java
index 29442fd80cdf..fb8722d0156b 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java
@@ -29,7 +29,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.reference.SoftReference;
import com.intellij.util.containers.UnsafeWeakList;
import org.jetbrains.annotations.NotNull;
@@ -72,7 +72,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
}
}
- for (DocumentWindow injectedDoc : InjectedLanguageFacadeImpl.getCachedInjectedDocuments(file)) {
+ for (DocumentWindow injectedDoc : InjectedLanguageUtil.getCachedInjectedDocuments(file)) {
PsiFile injectedFile = psiDocumentManager.getPsiFile(injectedDoc);
if (injectedFile == null) continue;
RangeMarker cachedMarker = getCachedRangeMarkerToInjectedFragment(injectedFile);
@@ -114,7 +114,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
}
}
- for (DocumentWindow injectedDoc : InjectedLanguageFacadeImpl.getCachedInjectedDocuments(file)) {
+ for (DocumentWindow injectedDoc : InjectedLanguageUtil.getCachedInjectedDocuments(file)) {
PsiFile injectedFile = psiDocumentManager.getPsiFile(injectedDoc);
if (injectedFile == null) continue;
unfastenBelts(injectedFile, 0);
@@ -145,7 +145,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
}
final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(file.getProject());
- for (Document document : InjectedLanguageFacadeImpl.getCachedInjectedDocuments(file)) {
+ for (Document document : InjectedLanguageUtil.getCachedInjectedDocuments(file)) {
PsiFile injectedfile = psiDocumentManager.getPsiFile(document);
if (injectedfile == null) continue;
_synchronizePointers(injectedfile);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
index 1f87406009a6..42b4ee1f167b 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
@@ -45,7 +45,7 @@ import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
import com.intellij.psi.impl.source.codeStyle.IndentHelperImpl;
import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.TestOnly;
@@ -168,7 +168,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
if (changeSet == null) return;
final PsiElement psiElement = changeSet.getRootElement().getPsi();
if (psiElement == null) return;
- PsiFile containingFile = InjectedLanguageFacadeImpl.getTopLevelFile(psiElement);
+ PsiFile containingFile = InjectedLanguageUtil.getTopLevelFile(psiElement);
final FileViewProvider viewProvider = containingFile.getViewProvider();
if (!viewProvider.isEventSystemEnabled()) return;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
index f6be88df1c35..d9af7a4b628a 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java
@@ -45,7 +45,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.DocumentBasedFormattingModel;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.testFramework.LightVirtualFile;
@@ -88,7 +88,7 @@ public class CodeFormatterFacade {
final Document document = file.getViewProvider().getDocument();
final RangeMarker rangeMarker = document != null && endOffset < document.getTextLength()? document.createRangeMarker(startOffset, endOffset):null;
- PsiElement elementToFormat = document instanceof DocumentWindow ? InjectedLanguageFacadeImpl.getTopLevelFile(file) : psiElement;
+ PsiElement elementToFormat = document instanceof DocumentWindow ? InjectedLanguageUtil.getTopLevelFile(file) : psiElement;
final PsiFile fileToFormat = elementToFormat.getContainingFile();
final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(fileToFormat);
@@ -137,7 +137,7 @@ public class CodeFormatterFacade {
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
final List textRanges = ranges.getRanges();
if (document instanceof DocumentWindow) {
- file = InjectedLanguageFacadeImpl.getTopLevelFile(file);
+ file = InjectedLanguageUtil.getTopLevelFile(file);
final DocumentWindow documentWindow = (DocumentWindow)document;
for (FormatTextRanges.FormatTextRange range : textRanges) {
range.setTextRange(documentWindow.injectedToHost(range.getTextRange()));
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
index b6685b1e5e08..c0d69b38c25c 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
@@ -38,7 +38,7 @@ import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.CharTable;
import com.intellij.util.IncorrectOperationException;
@@ -274,7 +274,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
TextRange textRange = addedElement.getTextRange();
final Document document = fileViewProvider.getDocument();
if (document instanceof DocumentWindow) {
- containingFile = InjectedLanguageFacadeImpl.getTopLevelFile(containingFile);
+ containingFile = InjectedLanguageUtil.getTopLevelFile(containingFile);
textRange = ((DocumentWindow)document).injectedToHost(textRange);
}
@@ -614,7 +614,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
if (!(astNode instanceof FileElement)) {
return new Pair(null, null);
}
- PsiElement elementAt = InjectedLanguageFacadeImpl.findInjectedElementNoCommit(file, offset);
+ PsiElement elementAt = InjectedLanguageUtil.findInjectedElementNoCommit(file, offset);
final CharTable charTable = ((FileElement)astNode).getCharTable();
if (elementAt == null) {
elementAt = findElementInTreeWithFormatterEnabled(file, offset);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java
index 3862e08e4749..de0243002b23 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java
@@ -28,7 +28,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.formatter.DocumentBasedFormattingModel;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.Nullable;
@@ -56,7 +56,7 @@ abstract class CodeStyleManagerRunnable {
Document document = documentManager.getDocument(file);
if (document instanceof DocumentWindow) {
final DocumentWindow documentWindow = (DocumentWindow)document;
- final PsiFile topLevelFile = InjectedLanguageFacadeImpl.getTopLevelFile(file);
+ final PsiFile topLevelFile = InjectedLanguageUtil.getTopLevelFile(file);
if (!file.equals(topLevelFile)) {
if (range != null) {
range = documentWindow.injectedToHost(range);
@@ -125,7 +125,7 @@ abstract class CodeStyleManagerRunnable {
return false;
}
- if (element instanceof PsiLanguageInjectionHost && InjectedLanguageFacadeImpl.hasInjections((PsiLanguageInjectionHost)element)) {
+ if (element instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)element)) {
return false;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java
index b76d8c89d481..2d73b9b02f82 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java
@@ -25,7 +25,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -306,7 +306,7 @@ public class FileReferenceSet {
@Nullable
private PsiFile getContainingFile() {
- final PsiFile file = InjectedLanguageFacadeImpl.getTopLevelFile(myElement.getContainingFile());
+ final PsiFile file = InjectedLanguageUtil.getTopLevelFile(myElement.getContainingFile());
if (file == null) {
LOG.error("Invalid element: " + myElement);
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java
index 21b6a6a4841c..4cd558854598 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedFileViewProvider.java
@@ -90,7 +90,7 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
PsiFile hostFile = documentManager.getPsiFile(hostDocument);
Language language = getBaseLanguage();
PsiFile file = getPsi(language);
- final Language hostFileLanguage = InjectedLanguageFacadeImpl.getTopLevelFile(file).getLanguage();
+ final Language hostFileLanguage = InjectedLanguageUtil.getTopLevelFile(file).getLanguage();
PsiFile hostPsiFileCopy = (PsiFile)hostFile.copy();
Segment firstTextRange = oldDocumentWindow.getHostRanges()[0];
PsiElement hostElementCopy = hostPsiFileCopy.getViewProvider().findElementAt(firstTextRange.getStartOffset(), hostFileLanguage);
@@ -108,7 +108,7 @@ public class InjectedFileViewProvider extends SingleRootFileViewProvider impleme
for (PsiElement current = hostElementCopy; current != null && current != hostPsiFileCopy; current = current.getParent()) {
current.putUserData(LANGUAGE_FOR_INJECTED_COPY_KEY, language);
try {
- InjectedLanguageFacadeImpl.enumerate(current, hostPsiFileCopy, false, visitor);
+ InjectedLanguageUtil.enumerate(current, hostPsiFileCopy, false, visitor);
}
finally {
current.putUserData(LANGUAGE_FOR_INJECTED_COPY_KEY, null);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
index 8a086947820c..250bcbed8cd1 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageManagerImpl.java
@@ -131,7 +131,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
if (hostPsiFile == null) return;
final CopyOnWriteArrayList injected =
- (CopyOnWriteArrayList)InjectedLanguageFacadeImpl.getCachedInjectedDocuments(hostPsiFile);
+ (CopyOnWriteArrayList)InjectedLanguageUtil.getCachedInjectedDocuments(hostPsiFile);
if (injected.isEmpty()) return;
if (myProgress.isCanceled()) {
@@ -157,7 +157,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
}
final DocumentWindow[] stillInjectedDocument = {null};
// it is here where the reparse happens and old file contents replaced
- InjectedLanguageFacadeImpl.enumerate(element, hostPsiFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ InjectedLanguageUtil.enumerate(element, hostPsiFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) {
stillInjectedDocument[0] = (DocumentWindow)injectedPsi.getViewProvider().getDocument();
@@ -333,7 +333,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
@SuppressWarnings({"ConstantConditions", "unchecked"})
@NotNull
public List intersectWithAllEditableFragments(@NotNull PsiFile injectedPsi, @NotNull TextRange rangeToEdit) {
- Place shreds = InjectedLanguageFacadeImpl.getShreds(injectedPsi);
+ Place shreds = InjectedLanguageUtil.getShreds(injectedPsi);
if (shreds == null) return Collections.emptyList();
Object result = null; // optimization: TextRange or ArrayList
int count = 0;
@@ -381,12 +381,12 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
@Override
public PsiElement findInjectedElementAt(@NotNull PsiFile hostFile, int hostDocumentOffset) {
- return InjectedLanguageFacadeImpl.findInjectedElementNoCommit(hostFile, hostDocumentOffset);
+ return InjectedLanguageUtil.findInjectedElementNoCommit(hostFile, hostDocumentOffset);
}
@Override
public void dropFileCaches(@NotNull PsiFile file) {
- InjectedLanguageFacadeImpl.clearCachedInjectedFragmentsForFile(file);
+ InjectedLanguageUtil.clearCachedInjectedFragmentsForFile(file);
}
private final Map myInjectorsClone = new HashMap();
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageFacadeImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
similarity index 99%
rename from platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageFacadeImpl.java
rename to platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
index 4a019a46fac2..c0508eab7a08 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageFacadeImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
@@ -46,7 +46,7 @@ import java.util.List;
/**
* @author cdr
*/
-public class InjectedLanguageFacadeImpl extends InjectedLanguageFacade {
+public class InjectedLanguageUtil extends InjectedLanguageFacade {
static final Key, TextRange>>> HIGHLIGHT_TOKENS = Key.create("HIGHLIGHT_TOKENS");
public static void forceInjectionOnElement(@NotNull PsiElement host) {
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
index 19ca2be6c298..d1ee84f27989 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
@@ -256,7 +256,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
PsiFile newFile = registerDocument(documentWindow, psiFile, place, myHostPsiFile, documentManager);
boolean mergeHappened = newFile != psiFile;
if (mergeHappened) {
- InjectedLanguageFacadeImpl.clearCaches(psiFile, documentWindow);
+ InjectedLanguageUtil.clearCaches(psiFile, documentWindow);
psiFile = newFile;
viewProvider = (InjectedFileViewProvider)psiFile.getViewProvider();
documentWindow = (DocumentWindowImpl)viewProvider.getDocument();
@@ -274,7 +274,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
try {
List, TextRange>> tokens = obtainHighlightTokensFromLexer(myLanguage, outChars, escapers, place, virtualFile, myProject);
- psiFile.putUserData(InjectedLanguageFacadeImpl.HIGHLIGHT_TOKENS, tokens);
+ psiFile.putUserData(InjectedLanguageUtil.HIGHLIGHT_TOKENS, tokens);
}
catch (ProcessCanceledException e) {
throw e;
@@ -385,7 +385,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
final Place shreds,
final PsiFile hostPsiFile,
final PsiDocumentManager documentManager) {
- List injected = InjectedLanguageFacadeImpl.getCachedInjectedDocuments(hostPsiFile);
+ List injected = InjectedLanguageUtil.getCachedInjectedDocuments(hostPsiFile);
for (int i = injected.size()-1; i>=0; i--) {
DocumentWindowImpl oldDocument = (DocumentWindowImpl)injected.get(i);
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java b/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java
index 47a07ed76341..ab7347afcf4b 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java
@@ -19,6 +19,7 @@
*/
package com.intellij.psi.stubs;
+import com.intellij.util.indexing.IOUtils;
import com.intellij.util.io.UnsyncByteArrayInputStream;
import org.jetbrains.annotations.Nullable;
@@ -38,15 +39,12 @@ public class SerializedStubTree {
}
public SerializedStubTree(DataInput in) throws IOException {
- myLength = in.readInt();
- myBytes = new byte[myLength];
- myStubElement = null;
- in.readFully(myBytes);
+ myBytes = IOUtils.readCompressed(in);
+ myLength = myBytes.length;
}
- public void write(DataOutput out) throws IOException{
- out.writeInt(myLength);
- out.write(myBytes, 0, myLength);
+ public void write(DataOutput out) throws IOException {
+ IOUtils.writeCompressed(out, myBytes, myLength);
}
// willIndexStub is one time optimization hint, once can safely pass false
diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java b/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java
index a15dfa42e4f2..0afa6b6545fc 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/move/FileReferenceContextUtil.java
@@ -22,7 +22,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceOwner;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
@@ -43,7 +43,7 @@ public class FileReferenceContextUtil {
element.accept(new PsiRecursiveElementWalkingVisitor(true) {
@Override public void visitElement(PsiElement element) {
if (element instanceof PsiLanguageInjectionHost) {
- InjectedLanguageFacadeImpl.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ InjectedLanguageUtil.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List places) {
encodeFileReferences(injectedPsi);
}
@@ -89,7 +89,7 @@ public class FileReferenceContextUtil {
}
if (element instanceof PsiLanguageInjectionHost) {
- InjectedLanguageFacadeImpl.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
+ InjectedLanguageUtil.enumerate(element, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
public void visit(@NotNull final PsiFile injectedPsi, @NotNull final List places) {
decodeFileReferences(injectedPsi);
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
index 3b5c3f49bdfd..c23fe24e664d 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/PsiElementRenameHandler.java
@@ -31,7 +31,7 @@ import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.meta.PsiMetaOwner;
import com.intellij.psi.meta.PsiWritableMetaData;
import com.intellij.refactoring.RefactoringBundle;
@@ -57,7 +57,7 @@ public class PsiElementRenameHandler implements RenameHandler {
public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
PsiElement element = getElement(dataContext);
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
- final PsiElement nameSuggestionContext = InjectedLanguageFacadeImpl.findElementAtNoCommit(file, editor.getCaretModel().getOffset());
+ final PsiElement nameSuggestionContext = InjectedLanguageUtil.findElementAtNoCommit(file, editor.getCaretModel().getOffset());
invoke(element, project, nameSuggestionContext, editor);
}
@@ -127,7 +127,7 @@ public class PsiElementRenameHandler implements RenameHandler {
}
}
- if (InjectedLanguageFacadeImpl.isInInjectedLanguagePrefixSuffix(element)) {
+ if (InjectedLanguageUtil.isInInjectedLanguagePrefixSuffix(element)) {
final String message = RefactoringBundle.message("error.in.injected.lang.prefix.suffix", UsageViewUtil.getType(element));
return RefactoringBundle.getCannotRefactorMessage(message);
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java
index 80542b6a3c6a..2a963e5ad5fa 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java
@@ -62,7 +62,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.PsiSearchHelper;
@@ -151,7 +151,7 @@ public abstract class InplaceRefactoring {
public boolean performInplaceRefactoring(final LinkedHashSet nameSuggestions) {
myNameSuggestions = nameSuggestions;
- if (InjectedLanguageFacadeImpl.isInInjectedLanguagePrefixSuffix(myElementToRename)) {
+ if (InjectedLanguageUtil.isInInjectedLanguagePrefixSuffix(myElementToRename)) {
return false;
}
@@ -274,7 +274,7 @@ public abstract class InplaceRefactoring {
}
else {
revertState();
- final TemplateState templateState = TemplateManagerImpl.getTemplateState(InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor));
+ final TemplateState templateState = TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(myEditor));
if (templateState != null) {
templateState.gotoEnd(true);
}
@@ -332,7 +332,7 @@ public abstract class InplaceRefactoring {
TextRange range = myScope.getTextRange();
assert range != null;
myHighlighters = new ArrayList();
- Editor topLevelEditor = InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor);
+ Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor);
topLevelEditor.getCaretModel().moveToOffset(range.getStartOffset());
TemplateManager.getInstance(myProject).startTemplate(topLevelEditor, template, templateListener);
@@ -508,7 +508,7 @@ public abstract class InplaceRefactoring {
if (myOldName == null) return;
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
public void run() {
- final Editor topLevelEditor = InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor);
+ final Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
final TemplateState state = TemplateManagerImpl.getTemplateState(topLevelEditor);
@@ -751,7 +751,7 @@ public abstract class InplaceRefactoring {
finally {
if (!bind) {
try {
- ((EditorImpl)InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor)).stopDumb();
+ ((EditorImpl)InjectedLanguageUtil.getTopLevelEditor(myEditor)).stopDumb();
}
finally {
FinishMarkAction.finish(myProject, myEditor, myMarkAction);
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.java
index f6a107357ad9..45d74ff03420 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenameHandler.java
@@ -28,7 +28,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.intellij.psi.PsiNamedElement;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.rename.RenamePsiElementProcessor;
import org.jetbrains.annotations.NotNull;
@@ -73,7 +73,7 @@ public class MemberInplaceRenameHandler extends VariableInplaceRenameHandler {
else {
final InplaceRefactoring inplaceRefactoring = editor.getUserData(InplaceRefactoring.INPLACE_RENAMER);
if (inplaceRefactoring != null && inplaceRefactoring.getClass() == MemberInplaceRenamer.class) {
- final TemplateState templateState = TemplateManagerImpl.getTemplateState(InjectedLanguageFacadeImpl.getTopLevelEditor(editor));
+ final TemplateState templateState = TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(editor));
if (templateState != null) {
templateState.gotoEnd(true);
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java
index 062fc1aa8a65..caf14daadbf3 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java
@@ -30,7 +30,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.SearchScope;
@@ -202,7 +202,7 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer {
}
finally {
try {
- ((EditorImpl)InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor)).stopDumb();
+ ((EditorImpl)InjectedLanguageUtil.getTopLevelEditor(myEditor)).stopDumb();
}
finally {
FinishMarkAction.finish(myProject, myEditor, markAction);
@@ -248,7 +248,7 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer {
@Override
protected void revertStateOnFinish() {
- final Editor editor = InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor);
+ final Editor editor = InjectedLanguageUtil.getTopLevelEditor(myEditor);
if (editor == FileEditorManager.getInstance(myProject).getSelectedTextEditor()) {
((EditorImpl)editor).startDumb();
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java
index 70960742e739..7db3a3693faf 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java
@@ -30,7 +30,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.refactoring.rename.NameSuggestionProvider;
import com.intellij.refactoring.rename.PreferrableNameSuggestionProvider;
@@ -78,7 +78,7 @@ public class MyLookupExpression extends Expression {
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
if (shouldSelectAll) return;
- final Editor topLevelEditor = InjectedLanguageFacadeImpl.getTopLevelEditor(context.getEditor());
+ final Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(context.getEditor());
final TemplateState templateState = TemplateManagerImpl.getTemplateState(topLevelEditor);
if (templateState != null) {
final TextRange range = templateState.getCurrentVariableRange();
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
index 222ca0db8098..f52e6635ef16 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
@@ -32,7 +32,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.rename.AutomaticRenamingDialog;
@@ -249,7 +249,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
}
finally {
try {
- ((EditorImpl)InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor)).stopDumb();
+ ((EditorImpl)InjectedLanguageUtil.getTopLevelEditor(myEditor)).stopDumb();
}
finally {
FinishMarkAction.finish(myProject, myEditor, markAction);
@@ -298,7 +298,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
revertStateOnFinish();
}
else {
- ((EditorImpl)InjectedLanguageFacadeImpl.getTopLevelEditor(myEditor)).stopDumb();
+ ((EditorImpl)InjectedLanguageUtil.getTopLevelEditor(myEditor)).stopDumb();
}
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IOUtils.java b/platform/lang-impl/src/com/intellij/util/indexing/IOUtils.java
new file mode 100644
index 000000000000..b775f9fa4a13
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IOUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.indexing;
+
+import com.intellij.util.io.DataInputOutputUtil;
+import org.xerial.snappy.Snappy;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Field;
+
+/**
+ * @author Maxim.Mossienko
+ */
+public class IOUtils {
+ private static volatile boolean canUseSnappy;
+ static {
+ try {
+ Field impl = Snappy.class.getDeclaredField("impl");
+ impl.setAccessible(true);
+ canUseSnappy = impl.get(null) != null && System.getProperty("idea.no.snappy") == null;
+ }
+ catch (Throwable e) {}
+ }
+
+ private static final int COMPRESSION_THRESHOLD = 64;
+ private static final ThreadLocal> spareBufferLocal = new ThreadLocal>();
+
+ public static int writeCompressed(DataOutput out, byte[] bytes, int length) throws IOException {
+ if (length > COMPRESSION_THRESHOLD && canUseSnappy) {
+ SoftReference reference = spareBufferLocal.get();
+ byte[] compressedOutputBuffer = reference != null ? reference.get():null;
+ int maxCompressedSize = 32 + length + length / 6; // snappy.cc#MaxCompressedLength
+ if (compressedOutputBuffer == null || compressedOutputBuffer.length < maxCompressedSize) {
+ compressedOutputBuffer = new byte[maxCompressedSize];
+ spareBufferLocal.set(new SoftReference(compressedOutputBuffer));
+ }
+ int compressedSize = Snappy.rawCompress(bytes, 0, length, compressedOutputBuffer, 0);
+ DataInputOutputUtil.writeINT(out, -compressedSize);
+ out.write(compressedOutputBuffer, 0, compressedSize);
+ return compressedSize;
+ } else {
+ DataInputOutputUtil.writeINT(out, length);
+ out.write(bytes, 0, length);
+ return length;
+ }
+ }
+
+ public static final byte[] readCompressed(DataInput in) throws IOException {
+ int size = DataInputOutputUtil.readINT(in);
+ byte[] bytes = new byte[Math.abs(size)];
+ in.readFully(bytes);
+ if (size >= 0) {
+ return bytes;
+ } else {
+ if (!canUseSnappy) throw new IOException("Can not read compressed data");
+ return Snappy.uncompress(bytes);
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java
index 36ef41459f42..c7280faea5c1 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerImpl.java
@@ -85,7 +85,7 @@ class ValueContainerImpl extends UpdatableValueContainer implement
final Value value = valueIterator.next();
if (isAssociated(value, inputId)) {
if (toRemove == null) toRemove = new SmartList();
- else LOG.error("Expected only one value per-inputId");
+ else LOG.error("Expected only one value per-inputId", String.valueOf(toRemove.get(0)), String.valueOf(value));
toRemove.add(value);
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
index f366cb5e69b5..b6fa20a49a20 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
@@ -67,7 +67,7 @@ public interface IdeActions {
@NonNls String ACTION_SHOW_INTENTION_ACTIONS = "ShowIntentionActions";
@NonNls String ACTION_CODE_COMPLETION = "CodeCompletion";
@NonNls String ACTION_SMART_TYPE_COMPLETION = "SmartTypeCompletion";
- @NonNls String ACTION_CLASS_NAME_COMPLETION = "ClassNameCompletion";
+ @Deprecated @NonNls String ACTION_CLASS_NAME_COMPLETION = "ClassNameCompletion";
@NonNls String ACTION_CHOOSE_LOOKUP_ITEM = "EditorChooseLookupItem";
@NonNls String ACTION_CHOOSE_LOOKUP_ITEM_ALWAYS = "EditorChooseLookupItemAlways";
@NonNls String ACTION_CHOOSE_LOOKUP_ITEM_REPLACE = "EditorChooseLookupItemReplace";
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java
index feb8f7752514..a5b9bf5ad80a 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java
@@ -675,6 +675,9 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable {
protected void processMouseEvent(MouseEvent e) {
super.processMouseEvent(e);
+ if (!isShowing()) {
+ return;
+ }
switch (e.getID()) {
case MouseEvent.MOUSE_ENTERED:
setCursor(getResizeCursor());
diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java b/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java
index 5423add1433a..ff9fc814f2f1 100644
--- a/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java
+++ b/platform/platform-api/src/com/intellij/ui/speedSearch/ListWithFilter.java
@@ -111,7 +111,7 @@ public class ListWithFilter extends JPanel implements DataProvider {
private class MySpeedSearch extends SpeedSearch {
boolean searchFieldShown = false;
- protected void update() {
+ public void update() {
mySpeedSearchPatternField.setBackground(new JTextField().getBackground());
onSpeedSearchPatternChanged();
mySpeedSearchPatternField.setText(getFilter());
diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java
index 1d3f237955e4..4749a4845a4c 100644
--- a/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java
+++ b/platform/platform-api/src/com/intellij/ui/speedSearch/SpeedSearch.java
@@ -68,7 +68,7 @@ public class SpeedSearch {
}
}
- protected void update() {
+ public void update() {
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
index e8d503e2f35d..17ff11cc8d1f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
@@ -474,7 +474,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
}
myPluginsListUrl = DEFAULT_PLUGINS_HOST + "/plugins/list/";
- myPluginsDownloadUrl = DEFAULT_PLUGINS_HOST + "/pluginManager";
+ myPluginsDownloadUrl = DEFAULT_PLUGINS_HOST + "/pluginManager/";
Element pluginsElement = parentNode.getChild(ELEMENT_PLUGINS);
if (pluginsElement != null) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/HungryBackspaceAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/HungryBackspaceAction.java
new file mode 100644
index 000000000000..548b4ff95107
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/HungryBackspaceAction.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor.actions;
+
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
+import com.intellij.openapi.editor.actionSystem.EditorActionManager;
+import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.text.CharArrayUtil;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Works like a usual backspace except the situation when the caret is located after white space - all white space symbols
+ * (white spaces, tabulations, line feeds) are removed then.
+ *
+ * @author Denis Zhdanov
+ * @since 6/27/12 4:10 PM
+ */
+public class HungryBackspaceAction extends TextComponentEditorAction {
+
+ public HungryBackspaceAction() {
+ super(new Handler());
+ }
+
+ private static class Handler extends EditorWriteActionHandler {
+ @Override
+ public void executeWriteAction(@NotNull Editor editor, DataContext dataContext) {
+ final Document document = editor.getDocument();
+ final int prevSymbolOffset = editor.getCaretModel().getOffset() - 1;
+ if (prevSymbolOffset < 0) {
+ return;
+ }
+
+ final SelectionModel selectionModel = editor.getSelectionModel();
+ final CharSequence text = document.getCharsSequence();
+ final char c = text.charAt(prevSymbolOffset);
+ final boolean doHungryCheck = !selectionModel.hasSelection() && !selectionModel.hasBlockSelection() && StringUtil.isWhiteSpace(c);
+ final EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE);
+ handler.execute(editor, dataContext);
+
+ if (!doHungryCheck) {
+ return;
+ }
+
+ final int endOffset = prevSymbolOffset;
+ if (endOffset > document.getTextLength()) {
+ return;
+ }
+ int startOffset = CharArrayUtil.shiftBackward(text, endOffset - 1, "\t \n");
+ if (startOffset < 0) {
+ // No non-white space symbol before the current caret offset has been found.
+ startOffset = 0;
+ }
+ else {
+ // Offset now points to the first non-white space symbol before the caret.
+ // Increment it to point to the first white space symbol instead.
+ startOffset++;
+ }
+ if (startOffset >= endOffset) {
+ return;
+ }
+ document.deleteString(startOffset, endOffset);
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index c6a1c0747dac..c6f987bfe094 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -1336,23 +1336,78 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return new Point(x, y);
}
- private int getTabbedTextWidth(int startOffset, int length, int xOffset) {
+ private int calcEndOffset(int startOffset, int visualColumn) {
+ FoldRegion[] regions = myFoldingModel.fetchTopLevel();
+ if (regions == null) {
+ return startOffset + visualColumn;
+ }
+
+ int low = 0;
+ int high = regions.length - 1;
+ int i = -1;
+
+ while (low <= high) {
+ int mid = (low + high) >>> 1;
+ FoldRegion midVal = regions[mid];
+
+ if (midVal.getStartOffset() <= startOffset && midVal.getEndOffset() > startOffset) {
+ i = mid;
+ break;
+ }
+
+ if (midVal.getStartOffset() < startOffset)
+ low = mid + 1;
+ else if (midVal.getStartOffset() > startOffset)
+ high = mid - 1;
+ }
+ if (i < 0) {
+ i = low;
+ }
+
+ int result = startOffset;
+ int columnsToProcess = visualColumn;
+ for (; i < regions.length; i++) {
+ FoldRegion region = regions[i];
+
+ // Process text between the last fold region end and current fold region start.
+ int nonFoldTextColumnsNumber = region.getStartOffset() - result;
+ if (nonFoldTextColumnsNumber >= columnsToProcess) {
+ return result + columnsToProcess;
+ }
+ columnsToProcess -= nonFoldTextColumnsNumber;
+
+ // Process fold region.
+ int placeHolderLength = region.getPlaceholderText().length();
+ if (placeHolderLength >= columnsToProcess) {
+ return region.getEndOffset();
+ }
+ result = region.getEndOffset();
+ columnsToProcess -= placeHolderLength;
+ }
+ return result + columnsToProcess;
+ }
+
+ private int getTabbedTextWidth(int startOffset, int targetColumn, int xOffset) {
int x = xOffset;
if (startOffset == 0 && myPrefixText != null) {
x += myPrefixWidthInPixels;
}
- if (length <= 0) return x;
+ if (targetColumn <= 0) return x;
int offset = startOffset;
CharSequence text = myDocument.getCharsNoThreadCheck();
int textLength = myDocument.getTextLength();
- IterationState state = new IterationState(this, startOffset, startOffset + length, false);
+
+ // We need to calculate max offset to provide to the IterationState here based on the given start offset and target
+ // visual column. The problem is there is a possible case that there is a collapsed fold region at the target interval,
+ // so, we can't just use 'startOffset + targetColumn' as a max end offset.
+ IterationState state = new IterationState(this, startOffset, calcEndOffset(startOffset, targetColumn), false);
try {
int fontType = state.getMergedAttributes().getFontType();
int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
int column = 0;
outer:
- while (column < length) {
+ while (column < targetColumn) {
if (offset >= textLength) break;
if (offset >= state.getEndOffset()) {
@@ -1375,7 +1430,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
for (char aPlaceholder : placeholder) {
x += EditorUtil.charWidth(aPlaceholder, fontType, this);
column++;
- if (column >= length) break outer;
+ if (column >= targetColumn) break outer;
}
offset = region.getEndOffset();
}
@@ -1404,8 +1459,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
- if (column != length) {
- x += EditorUtil.getSpaceWidth(fontType, this) * (length - column);
+ if (column != targetColumn) {
+ x += EditorUtil.getSpaceWidth(fontType, this) * (targetColumn - column);
}
return x;
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
index 78cce1952c4f..978af235243e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.*;
import com.intellij.ide.startup.StartupActionScriptManager;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
@@ -374,10 +375,12 @@ public class PluginDownloader {
}
public static PluginDownloader createDownloader(IdeaPluginDescriptor pluginDescriptor) throws UnsupportedEncodingException {
+ String installationUUID = UpdateChecker.getInstallationUID(PropertiesComponent.getInstance());
+
final BuildNumber buildNumber = ApplicationInfo.getInstance().getBuild();
@NonNls String url = RepositoryHelper.DOWNLOAD_URL +
URLEncoder.encode(pluginDescriptor.getPluginId().getIdString(), "UTF8") +
- "&build=" + buildNumber.asString();
+ "&build=" + buildNumber.asString() + "&uuid=" + URLEncoder.encode(installationUUID, "UTF8");
if (pluginDescriptor instanceof PluginNode && ((PluginNode)pluginDescriptor).getDownloadUrl() != null){
url = ((PluginNode)pluginDescriptor).getDownloadUrl();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
index 139541d85171..007487984356 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
@@ -93,9 +93,10 @@ public class FileWatcher {
private FileWatcher() {
// to avoid deadlock (PY-1215), initialize ManagingFS reference in main thread, not in FileWatcher thread
myManagingFS = ManagingFS.getInstance();
-
+
+ final boolean explicitlyDisabled = Boolean.parseBoolean(System.getProperty(PROPERTY_WATCHER_DISABLED));
try {
- if (!"true".equals(System.getProperty(PROPERTY_WATCHER_DISABLED))) {
+ if (!explicitlyDisabled) {
startupProcess(false);
}
}
@@ -117,8 +118,10 @@ public class FileWatcher {
}, "FileWatcher shutdown hook"));
}
else {
- LOG.info("Native file watcher failed to startup.");
- notifyOnFailure("File watcher failed to startup", null);
+ String message = explicitlyDisabled ? String.format("File watcher is disabled ('%s' property is set)", PROPERTY_WATCHER_DISABLED)
+ : "File watcher failed to startup";
+ LOG.info(message);
+ notifyOnFailure(message, null);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
index d8c59f6c95f4..2edbd3308861 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
@@ -51,7 +51,7 @@ import java.util.concurrent.ScheduledFuture;
public class FSRecords implements Forceable {
private static final Logger LOG = Logger.getInstance("#com.intellij.vfs.persistent.FSRecords");
- private static final int VERSION = 16;
+ private static final int VERSION = 17;
private static final int PARENT_OFFSET = 0;
private static final int PARENT_SIZE = 4;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java
index 613a2f188726..c8365cf2b222 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java
@@ -513,7 +513,9 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent {
// we should cache every local files content
// because the local history feature is currently depends on this cache,
// perforce offline mode as well
- if ((!delegate.isReadOnly() || !application.isInternal() && !application.isUnitTestMode()) &&
+ if ((!delegate.isReadOnly() ||
+ // do not cache archive content unless asked
+ (cacheContent && !application.isInternal() && !application.isUnitTestMode())) &&
content.length <= PersistentFSConstants.FILE_LENGTH_TO_CACHE_THRESHOLD) {
synchronized (INPUT_LOCK) {
writeContent(canonicalFile, new ByteSequence(content), delegate.isReadOnly());
diff --git a/platform/platform-impl/src/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java b/platform/platform-impl/src/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java
index bcac9e54ca38..16b6967f9e4f 100644
--- a/platform/platform-impl/src/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/psi/statistics/impl/StatisticsManagerImpl.java
@@ -17,9 +17,11 @@ package com.intellij.psi.statistics.impl;
import com.intellij.CommonBundle;
import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Disposer;
import com.intellij.psi.statistics.StatisticsInfo;
import com.intellij.psi.statistics.StatisticsManager;
import com.intellij.reference.SoftReference;
@@ -43,6 +45,7 @@ public class StatisticsManagerImpl extends StatisticsManager {
private final SoftReference[] myUnits = new SoftReference[UNIT_COUNT];
private final HashSet myModifiedUnits = new HashSet();
+ private boolean myTestingStatistics;
public int getUseCount(@NotNull final StatisticsInfo info) {
if (info == StatisticsInfo.EMPTY) return 0;
@@ -57,6 +60,9 @@ public class StatisticsManagerImpl extends StatisticsManager {
public void incUseCount(@NotNull final StatisticsInfo info) {
if (info == StatisticsInfo.EMPTY) return;
+ if (ApplicationManager.getApplication().isUnitTestMode() && !myTestingStatistics) {
+ return;
+ }
final String key1 = info.getContext();
int unitNumber = getUnitNumber(key1);
@@ -177,9 +183,17 @@ public class StatisticsManagerImpl extends StatisticsManager {
}
@TestOnly
- public void clearStatistics() {
- synchronized (LOCK) {
- Arrays.fill(myUnits, null);
- }
+ public void enableStatistics(@NotNull Disposable parentDisposable) {
+ myTestingStatistics = true;
+ Disposer.register(parentDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ synchronized (LOCK) {
+ Arrays.fill(myUnits, null);
+ }
+ myTestingStatistics = false;
+ }
+ });
}
+
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacFullScreenListener.java b/platform/platform-impl/src/com/intellij/ui/mac/MacFullScreenListener.java
deleted file mode 100644
index d92a4690be18..000000000000
--- a/platform/platform-impl/src/com/intellij/ui/mac/MacFullScreenListener.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.ui.mac;
-
-import com.apple.eawt.AppEvent;
-import com.apple.eawt.FullScreenAdapter;
-import com.intellij.Patches;
-import com.intellij.openapi.wm.impl.IdeFrameImpl;
-
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-public class MacFullScreenListener extends FullScreenAdapter {
- private final MacMainFrameDecorator myDecorator;
- private final IdeFrameImpl myFrame;
-
- public MacFullScreenListener(final MacMainFrameDecorator decorator,
- final IdeFrameImpl frame) {
- myDecorator = decorator;
- myFrame = frame;
- }
-
- @Override
- public void windowEnteredFullScreen(AppEvent.FullScreenEvent event) {
- myDecorator.setInFullScreen(true);
-
- JRootPane rootPane = myFrame.getRootPane();
- if (rootPane != null) rootPane.putClientProperty(MacMainFrameDecorator.FULL_SCREEN, Boolean.TRUE);
- if (Patches.APPLE_BUG_ID_10207064) {
- // fix problem with bottom empty bar
- // it seems like the title is still visible in fullscreen but the window itself shifted up for titlebar height
- // and the size of the frame is still calculated to be the height of the screen which is wrong
- // so just add these titlebar height to the frame height once again
- Timer timer = new Timer(300, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- myFrame.setSize(myFrame.getWidth(), myFrame.getHeight() + myFrame.getInsets().top);
- }
- });
- }
- });
- timer.setRepeats(false);
- timer.start();
- }
- }
-
- @Override
- public void windowExitedFullScreen(AppEvent.FullScreenEvent event) {
- myDecorator.setInFullScreen(false);
- myFrame.storeFullScreenStateIfNeeded(false);
-
- JRootPane rootPane = myFrame.getRootPane();
- if (rootPane != null) rootPane.putClientProperty(MacMainFrameDecorator.FULL_SCREEN, null);
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java
index 46d4b8f1836c..fe295604c47b 100644
--- a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java
+++ b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java
@@ -15,6 +15,9 @@
*/
package com.intellij.ui.mac;
+import com.apple.eawt.AppEvent;
+import com.apple.eawt.FullScreenAdapter;
+import com.apple.eawt.FullScreenUtilities;
import com.intellij.Patches;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
@@ -33,6 +36,8 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.atomic.AtomicInteger;
@@ -145,10 +150,43 @@ public class MacMainFrameDecorator implements UISettingsListener, Disposable {
if (SystemInfo.isMacOSLion) {
if (!FULL_SCREEN_AVAILABLE) return;
- try {
- Class> clazz = Class.forName("com.apple.eawt.FullScreenUtilities");
- clazz.getMethod("addFullScreenListenerTo").invoke(null, frame, new MacFullScreenListener(this, frame));
- } catch (Exception ignored) {}
+ FullScreenUtilities.addFullScreenListenerTo(frame, new FullScreenAdapter() {
+ @Override
+ public void windowEnteredFullScreen(AppEvent.FullScreenEvent event) {
+ myInFullScreen = true;
+
+ JRootPane rootPane = frame.getRootPane();
+ if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, Boolean.TRUE);
+ if (Patches.APPLE_BUG_ID_10207064) {
+ // fix problem with bottom empty bar
+ // it seems like the title is still visible in fullscreen but the window itself shifted up for titlebar height
+ // and the size of the frame is still calculated to be the height of the screen which is wrong
+ // so just add these titlebar height to the frame height once again
+ Timer timer = new Timer(300, new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ frame.setSize(frame.getWidth(), frame.getHeight() + frame.getInsets().top);
+ }
+ });
+ }
+ });
+ timer.setRepeats(false);
+ timer.start();
+ }
+ }
+
+ @Override
+ public void windowExitedFullScreen(AppEvent.FullScreenEvent event) {
+ myInFullScreen = false;
+ frame.storeFullScreenStateIfNeeded(false);
+
+ JRootPane rootPane = frame.getRootPane();
+ if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, null);
+ }
+ });
} else {
// toggle toolbar
String className = "IdeaToolbar" + v;
@@ -205,8 +243,4 @@ public class MacMainFrameDecorator implements UISettingsListener, Disposable {
invoke(window, "toggleFullScreen:", window);
}
}
-
- void setInFullScreen(boolean inFullScreen) {
- myInFullScreen = inFullScreen;
- }
}
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
index 9afcbb16edde..505f4c4bab15 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
@@ -126,7 +126,7 @@ public class AbstractPopup implements JBPopup {
protected final SpeedSearch mySpeedSearch = new SpeedSearch() {
boolean searchFieldShown = false;
- protected void update() {
+ public void update() {
mySpeedSearchPatternField.setBackground(new JTextField().getBackground());
onSpeedSearchPatternChanged();
mySpeedSearchPatternField.setText(getFilter());
diff --git a/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java b/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java
index 7c06e6c39075..331903f3b691 100644
--- a/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java
+++ b/platform/platform-impl/src/com/intellij/util/ui/ValidatingTableEditor.java
@@ -190,7 +190,7 @@ public abstract class ValidatingTableEditor- implements ComponentWithEmptyT
myFixLink = new HoverHyperlinkLabel(null);
}
- protected ValidatingTableEditor(AnActionButton extraButton) {
+ protected ValidatingTableEditor(@Nullable AnActionButton ... extraButtons) {
ToolbarDecorator decorator =
ToolbarDecorator.createDecorator(myTable).disableRemoveAction().disableUpAction().disableDownAction();
decorator.setAddAction(new AnActionButtonRunnable() {
@@ -211,8 +211,10 @@ public abstract class ValidatingTableEditor
- implements ComponentWithEmptyT
myRemoveButton.setShortcut(CustomShortcutSet.fromString("alt DELETE")); //NON-NLS
decorator.addExtraAction(myRemoveButton);
- if (extraButton != null) {
- decorator.addExtraAction(extraButton);
+ if (extraButtons != null && extraButtons.length != 0) {
+ for (AnActionButton extraButton : extraButtons) {
+ decorator.addExtraAction(extraButton);
+ }
}
myTablePanel.add(decorator.createPanel(), BorderLayout.CENTER);
@@ -240,6 +242,7 @@ public abstract class ValidatingTableEditor
- implements ComponentWithEmptyT
}
protected ValidatingTableEditor() {
+ //noinspection NullArgumentToVariableArgMethod
this(null);
}
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index dcf12af29677..ec400d719c25 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -69,6 +69,8 @@ action.EditorPasteSimple.description=Paste without formatting, autoimport, liter
action.EditorPasteFromX11.text=Paste from X clipboard
action.EditorDelete.text=Delete
action.EditorBackSpace.text=Backspace
+action.EditorHungryBackSpace.text=Hungry Backspace
+action.EditorHungryBackSpace.description=Acts as the Backspace except that removes all whitespace symbols before the caret (if any)
action.EditorMoveToPageTop.text=Move Caret to Page Top
action.EditorMoveToPageBottom.text=Move Caret to Page Bottom
action.EditorMoveToPageTopWithSelection.text=Move Caret to Page Top with Selection
diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties
index 82d004cf780e..9fa986238706 100644
--- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties
+++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties
@@ -207,6 +207,9 @@ intention.remove.literal.underscores=Remove underscores from literal
intention.insert.literal.underscores=Insert underscores into literal
intention.replace.cast.with.var.text=Replace ''{0}'' with ''{1}''
intention.replace.cast.with.var.family=Replace cast with variable
+intention.convert.color.representation.text=Convert to ''new Color{0}''
+intention.convert.color.representation.family=Convert Color representation
+intention.break.string.on.line.breaks.text=Break string on '\\n'
intention.create.test=Create Test
@@ -465,7 +468,7 @@ i18nize.empty.file.path=Please specify properties file path
choose.type.popup.title=Choose Type
cast.expression=Cast expression
cast.to.0=Cast to ''{0}''
-class.completion.file.path=Press {0} to search for all matching project files
+class.completion.file.path=Press {0} again to search for all matching project files
class.completion.file.path.all.variants=Press {0} to search for matching files of any type
property.has.more.parameters.than.passed=Property ''{0}'' expected {1} {1, choice, 1#parameter|2#parameters}, passed {2}
create.file.family=Create File
diff --git a/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties b/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties
index 883ebe769e70..14f3326d6b9d 100644
--- a/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties
+++ b/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties
@@ -38,12 +38,9 @@ navigation.select.in=Select In popup
navigation.goto.declaration=Go to declaration
navigation.goto.implementation=Go to implementation
editing.completion.basic=Basic code completion
-editing.completion.classname=Class name completion
editing.completion.smarttype.general=Smart type completion
-editing.completion.smarttype.anonymous=Smart anonymous class instantiation
editing.completion.smarttype.afternew=Smart type completion after new
editing.completion.smarttype.casting=Smart type casting
-editing.completion.second.classname=Second class name completion
editing.completion.second.basic=Second basic completion
editing.completion.second.smarttype.chain=Second smart type completion: chained method calls
editing.completion.second.smarttype.toar=Second smart type completion: toArray() conversion
diff --git a/platform/platform-resources-en/src/messages/FindBundle.properties b/platform/platform-resources-en/src/messages/FindBundle.properties
index c476b43c767e..01f60d0a1e09 100644
--- a/platform/platform-resources-en/src/messages/FindBundle.properties
+++ b/platform/platform-resources-en/src/messages/FindBundle.properties
@@ -76,7 +76,7 @@ find.filter.invalid.file.mask.error=Bad file mask \"{0}\"
find.filter.empty.file.mask.error=Empty file mask
find.options.case.sensitive=&Case sensitive
find.options.replace.preserve.case=Preser&ve case
-find.options.whole.words.only=W&hole words only
+find.options.whole.words.only=W&hole words only (may be faster)
find.options.string.literals.only=S&tring literals only
find.options.comments.only=Comm&ents only
find.options.regular.expressions=Re&gular expression
diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties
index 1801a40ee8e3..3bbfc016da00 100644
--- a/platform/platform-resources-en/src/messages/IdeBundle.properties
+++ b/platform/platform-resources-en/src/messages/IdeBundle.properties
@@ -1090,3 +1090,6 @@ whatsnew.action.custom.text=What''s _New in {0}
whatsnew.action.custom.description=Find out about the new features in this version of {0}
diff.dialog.title=Diff Between ''{0}'' and ''{1}''
+goto.custom.region.command=Go to Custom Region
+goto.custom.region.message.dumb.mode=Go to Custom Region action is not available until indices are built.
+goto.custom.region.message.unavailable=There are no custom folding regions in the current file.
\ No newline at end of file
diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
index 779ff6223685..c955353a1bff 100644
--- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
@@ -49,6 +49,7 @@ inspection.data.flow.nullable.quickfix.option=Suggest @Nullable anno
inspection.data.flow.true.asserts.option=Don't report assert statements with condition statically proven to be always
true
inspection.data.flow.redundant.instanceof.quickfix=Replace with != null
inspection.data.flow.simplify.boolean.expression.quickfix=Simplify Boolean Expression
+inspection.data.flow.simplify.to.assignment.quickfix.name=Simplify to normal assignment
configure.annotations.option=Configure annotations
#messages from dataflow inspection
diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
index a6458b03d218..86fda522dc82 100644
--- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties
+++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties
@@ -141,6 +141,7 @@ refactoring.introduceVariable=Extract Variable refactoring
refactoring.introduce.selection.error=Cannot perform refactoring using selected element(s)
refactoring.introduce.name.error=Incorrect name
refactoring.introduce.name.used.error=This name is already used
+refactoring.introduce.variable.scope.error=Name clashes with existing variable
refactoring.introduce.placing.error=Cannot extract {0} variable
variable.of.type=Variable of &type:
diff --git a/platform/platform-resources-en/src/tips/TagNameCompletion.html b/platform/platform-resources-en/src/tips/TagNameCompletion.html
index 69668ea3624d..cdce27443c63 100644
--- a/platform/platform-resources-en/src/tips/TagNameCompletion.html
+++ b/platform/platform-resources-en/src/tips/TagNameCompletion.html
@@ -3,7 +3,8 @@
-A special variant of the CodeCompletion feature invoked by &shortcut:ClassNameCompletion; allows you to
+
+ A special variant of the Code Completion feature invoked by pressing &shortcut:CodeCompletion; twice allows you to
complete
XML tag names from namespaces not declared in the current file.
If the namespace is not declared yet the declaration is generated automatically.
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index 78eedf74f4ef..bd57ac5cbe59 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -51,7 +51,7 @@
serviceImplementation="com.intellij.application.options.CodeStyleSettingsUtilImpl"/>
+ serviceImplementation="com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil"/>
+
diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml
index 801ea6a0fbfb..368f63db950d 100644
--- a/platform/platform-resources/src/idea/Keymap_Default.xml
+++ b/platform/platform-resources/src/idea/Keymap_Default.xml
@@ -406,6 +406,9 @@
+
+
+
diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml
index 7422ec6184f8..19469e244507 100644
--- a/platform/platform-resources/src/idea/LangActions.xml
+++ b/platform/platform-resources/src/idea/LangActions.xml
@@ -178,6 +178,7 @@
+
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index ee0461368bd7..bd266acce041 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -41,6 +41,7 @@
+
diff --git a/platform/platform-tests/testSrc/com/intellij/statistics/StatisticsManagerTest.java b/platform/platform-tests/testSrc/com/intellij/statistics/StatisticsManagerTest.java
index 8e85860d83c8..4087b43e3cad 100644
--- a/platform/platform-tests/testSrc/com/intellij/statistics/StatisticsManagerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/statistics/StatisticsManagerTest.java
@@ -19,22 +19,16 @@ public class StatisticsManagerTest extends LightPlatformTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
- ((StatisticsManagerImpl)StatisticsManager.getInstance()).clearStatistics();
+ ((StatisticsManagerImpl)StatisticsManager.getInstance()).enableStatistics(getTestRootDisposable());
}
- @Override
- protected void tearDown() throws Exception {
- ((StatisticsManagerImpl)StatisticsManager.getInstance()).clearStatistics();
- super.tearDown();
- }
-
- private void incUseCount(String value, int times) {
+ private static void incUseCount(String value, int times) {
for (int i = 0; i < times; i++) {
StatisticsManager.getInstance().incUseCount(new StatisticsInfo(TEST_CONTEXT, value));
}
}
- private int getUseCount(String value) {
+ private static int getUseCount(String value) {
return StatisticsManager.getInstance().getUseCount(new StatisticsInfo(TEST_CONTEXT, value));
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java
index 07e54aab89dc..7c2664f91de5 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ContentFolderBaseImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,6 +73,9 @@ public abstract class ContentFolderBaseImpl extends RootModelComponentBase imple
@Override
public VirtualFile getFile() {
+ if (!myFilePointer.isValid()) {
+ return null;
+ }
final VirtualFile file = myFilePointer.getFile();
return file == null || !file.isDirectory() ? null : file;
}
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java
index c8833bd7de58..24c85967cdd1 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTestProxy.java
@@ -420,12 +420,13 @@ public class SMTestProxy extends AbstractTestProxy {
public void printOn(final Printer printer) {
final Printer rightPrinter = getRightPrinter(printer);
super.printOn(rightPrinter);
+ final AbstractState oldState = myState;
invokeInAlarm(new Runnable() {
@Override
public void run() {
//Tests State, that provide and formats additional output
- myState.printOn(rightPrinter);
+ oldState.printOn(rightPrinter);
}
});
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
index 15aab99d6495..6d3ec85e2459 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.rt.execution.junit.FileComparisonFailure;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -225,7 +225,7 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
}
private static void setupEditorForInjectedLanguage() {
- Editor editor = InjectedLanguageFacadeImpl.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
+ Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
if (editor instanceof EditorWindow) {
myFile = ((EditorWindow)editor).getInjectedFile();
myEditor = editor;
@@ -444,13 +444,13 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
return myEditor;
}
if (dataId.equals(AnActionEvent.injectedId(PlatformDataKeys.EDITOR.getName()))) {
- return InjectedLanguageFacadeImpl.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
+ return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
}
if (LangDataKeys.PSI_FILE.is(dataId)) {
return myFile;
}
if (dataId.equals(AnActionEvent.injectedId(LangDataKeys.PSI_FILE.getName()))) {
- Editor editor = InjectedLanguageFacadeImpl.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
+ Editor editor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(getEditor(), getFile());
return editor instanceof EditorWindow ? ((EditorWindow)editor).getInjectedFile() : getFile();
}
return super.getData(dataId);
@@ -514,69 +514,69 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
}
}
protected static void backspace() {
- doAction(IdeActions.ACTION_EDITOR_BACKSPACE);
+ executeAction(IdeActions.ACTION_EDITOR_BACKSPACE);
}
protected static void delete() {
- doAction(IdeActions.ACTION_EDITOR_DELETE);
+ executeAction(IdeActions.ACTION_EDITOR_DELETE);
}
protected static void home() {
- doAction(IdeActions.ACTION_EDITOR_MOVE_LINE_START);
+ executeAction(IdeActions.ACTION_EDITOR_MOVE_LINE_START);
}
protected static void end() {
- doAction(IdeActions.ACTION_EDITOR_MOVE_LINE_END);
+ executeAction(IdeActions.ACTION_EDITOR_MOVE_LINE_END);
}
protected static void copy() {
- doAction(IdeActions.ACTION_EDITOR_COPY);
+ executeAction(IdeActions.ACTION_EDITOR_COPY);
}
protected static void paste() {
- doAction(IdeActions.ACTION_EDITOR_PASTE);
+ executeAction(IdeActions.ACTION_EDITOR_PASTE);
}
protected static void moveCaretToPreviousWordWithSelection() {
- doAction("EditorPreviousWordWithSelection");
+ executeAction("EditorPreviousWordWithSelection");
}
protected static void moveCaretToNextWordWithSelection() {
- doAction("EditorNextWordWithSelection");
+ executeAction("EditorNextWordWithSelection");
}
protected static void cutLineBackward() {
- doAction("EditorCutLineBackward");
+ executeAction("EditorCutLineBackward");
}
protected static void cutToLineEnd() {
- doAction("EditorCutLineEnd");
+ executeAction("EditorCutLineEnd");
}
protected static void killToWordStart() {
- doAction("EditorKillToWordStart");
+ executeAction("EditorKillToWordStart");
}
protected static void killToWordEnd() {
- doAction("EditorKillToWordEnd");
+ executeAction("EditorKillToWordEnd");
}
protected static void killRegion() {
- doAction("EditorKillRegion");
+ executeAction("EditorKillRegion");
}
protected static void killRingSave() {
- doAction("EditorKillRingSave");
+ executeAction("EditorKillRingSave");
}
protected static void unindent() {
- doAction("EditorUnindentSelection");
+ executeAction("EditorUnindentSelection");
}
protected static void lineComment() {
new CommentByLineCommentHandler().invoke(getProject(), getEditor(), getFile());
}
- private static void doAction(@NotNull final String actionId) {
+ protected static void executeAction(@NotNull final String actionId) {
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
@Override
public void run() {
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
index 8154d996b0e6..923e91eaed8d 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
@@ -68,7 +68,10 @@ import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.*;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.openapi.vfs.encoding.EncodingManagerImpl;
import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
@@ -209,7 +212,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
new Throwable(projectFile.getPath()).printStackTrace(new PrintStream(buffer));
- ourProject = PlatformTestCase.createProject(projectFile, LIGHT_PROJECT_MARK +buffer.toString());
+ ourProject = PlatformTestCase.createProject(projectFile, LIGHT_PROJECT_MARK + buffer.toString());
if (!ourHaveShutdownHook) {
ourHaveShutdownHook = true;
registerShutdownHook();
@@ -233,7 +236,10 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
FileBasedIndex.getInstance().registerIndexableSet(new IndexableFileSet() {
@Override
public boolean isInSet(@NotNull final VirtualFile file) {
- return ourSourceRoot != null && file.getFileSystem() == ourSourceRoot.getFileSystem() && ourProject.isOpen();
+ return ourSourceRoot != null &&
+ file.getFileSystem() == ourSourceRoot.getFileSystem() &&
+ ourProject != null &&
+ ourProject.isOpen();
}
@Override
@@ -313,7 +319,8 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
super.setUp();
initApplication();
ourApplication.setDataProvider(this);
- doSetup(new SimpleLightProjectDescriptor(getModuleType(), getProjectJDK()), configureLocalInspectionTools(), myAvailableInspectionTools);
+ doSetup(new SimpleLightProjectDescriptor(getModuleType(), getProjectJDK()), configureLocalInspectionTools(),
+ myAvailableInspectionTools);
((InjectedLanguageManagerImpl)InjectedLanguageManager.getInstance(getProject())).pushInjectors();
storeSettings();
@@ -326,7 +333,8 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
}
public static void doSetup(final LightProjectDescriptor descriptor,
- final LocalInspectionTool[] localInspectionTools, final Map availableInspectionTools) throws Exception {
+ final LocalInspectionTool[] localInspectionTools, final Map availableInspectionTools)
+ throws Exception {
assertNull("Previous test " + ourTestCase + " hasn't called tearDown(). Probably overriden without super call.", ourTestCase);
IdeaLogger.ourErrorsOccurred = null;
@@ -348,7 +356,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
@Override
@NotNull
public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
- if (availableInspectionTools != null){
+ if (availableInspectionTools != null) {
final Collection tools = availableInspectionTools.values();
return tools.toArray(new InspectionTool[tools.size()]);
}
@@ -405,7 +413,13 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
catch (Exception e) {
}
- assertTrue("open: "+getProject().isOpen()+"; disposed:"+getProject().isDisposed()+"; startup passed:"+ passed+"; all open projects: "+
+ assertTrue("open: " +
+ getProject().isOpen() +
+ "; disposed:" +
+ getProject().isDisposed() +
+ "; startup passed:" +
+ passed +
+ "; all open projects: " +
Arrays.asList(ProjectManager.getInstance().getOpenProjects()), getProject().isInitialized());
CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(new CodeStyleSettings());
@@ -443,8 +457,10 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
private static void enableInspectionTool(final Map availableLocalTools, InspectionTool wrapper) {
final String shortName = wrapper.getShortName();
final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
- if (key == null){
- HighlightDisplayKey.register(shortName, wrapper.getDisplayName(), wrapper instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)wrapper).getTool().getID() : wrapper.getShortName());
+ if (key == null) {
+ HighlightDisplayKey.register(shortName, wrapper.getDisplayName(), wrapper instanceof LocalInspectionToolWrapper
+ ? ((LocalInspectionToolWrapper)wrapper).getTool().getID()
+ : wrapper.getShortName());
}
availableLocalTools.put(shortName, wrapper);
}
@@ -528,7 +544,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
public void run() {
((UndoManagerImpl)UndoManager.getGlobalInstance()).dropHistoryInTests();
((UndoManagerImpl)UndoManager.getInstance(project)).dropHistoryInTests();
-
+
UIUtil.dispatchAllInvocationEvents();
}
});
@@ -546,7 +562,8 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
checkEditorsReleased();
}
if (isLight(project)) {
- ((ProjectImpl)project).setTemporarilyDisposed(true); // mark temporarily as disposed so that rogue component trying to access it will fail
+ ((ProjectImpl)project)
+ .setTemporarilyDisposed(true); // mark temporarily as disposed so that rogue component trying to access it will fail
documentManager.clearUncommitedDocuments();
}
}
@@ -631,11 +648,11 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
}
finally {
//try{
- tearDown();
+ tearDown();
//}
//catch(Throwable th){
// noinspection CallToPrintStackTrace
- //th.printStackTrace();
+ //th.printStackTrace();
//}
}
}
@@ -665,15 +682,18 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
* @param text - file text.
* @return dummy psi file.
* @throws com.intellij.util.IncorrectOperationException
+ *
*/
protected static PsiFile createFile(@NonNls String fileName, @NonNls String text) throws IncorrectOperationException {
FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
- return PsiFileFactory.getInstance(getProject()).createFileFromText(fileName, fileType, text, LocalTimeCounter.currentTime(), true, false);
+ return PsiFileFactory.getInstance(getProject())
+ .createFileFromText(fileName, fileType, text, LocalTimeCounter.currentTime(), true, false);
}
protected static PsiFile createLightFile(@NonNls String fileName, String text) throws IncorrectOperationException {
FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
- return PsiFileFactory.getInstance(getProject()).createFileFromText(fileName, fileType, text, LocalTimeCounter.currentTime(), false, false);
+ return PsiFileFactory.getInstance(getProject())
+ .createFileFromText(fileName, fileType, text, LocalTimeCounter.currentTime(), false, false);
}
/**
@@ -795,6 +815,5 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
final String[] newUrls = newSdk.getRootProvider().getUrls(OrderRootType.CLASSES);
return CollectionFactory.hashSet(myUrls).equals(CollectionFactory.hashSet(newUrls));
}
-
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java b/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java
index 971d52ca8039..7230e1b67f53 100644
--- a/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java
+++ b/platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java
@@ -62,7 +62,7 @@ public class TestLoggerFactory implements Logger.Factory {
return;
}
- final String logDir = PathManager.getSystemPath() + "/" + LOG_DIR;
+ final String logDir = getTestLogDir();
String text = FileUtil.loadFile(logXmlFile);
text = StringUtil.replace(text, SYSTEM_MACRO, StringUtil.replace(PathManager.getSystemPath(), "\\", "\\\\"));
text = StringUtil.replace(text, APPLICATION_MACRO, StringUtil.replace(PathManager.getHomePath(), "\\", "\\\\"));
@@ -90,4 +90,8 @@ public class TestLoggerFactory implements Logger.Factory {
e.printStackTrace();
}
}
+
+ public static String getTestLogDir() {
+ return PathManager.getSystemPath() + "/" + LOG_DIR;
+ }
}
\ No newline at end of file
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 01fcccbf1368..49a98fed2b1d 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -367,15 +367,17 @@ public abstract class UsefulTestCase extends TestCase {
assertOrderedCollection(Arrays.asList(collection), checkers);
}
- public static void assertSameElements(@NotNull T[] collection, @NotNull T... expected) {
+ public static void assertSameElements(T[] collection, T... expected) {
assertSameElements(Arrays.asList(collection), expected);
}
- public static void assertSameElements(@NotNull Collection extends T> collection, @NotNull T... expected) {
+ public static void assertSameElements(Collection extends T> collection, T... expected) {
assertSameElements(collection, Arrays.asList(expected));
}
- public static void assertSameElements(@NotNull Collection extends T> collection, @NotNull Collection expected) {
+ public static void assertSameElements(Collection extends T> collection, Collection expected) {
+ assertNotNull(collection);
+ assertNotNull(expected);
if (collection.size() != expected.size() || !new HashSet(expected).equals(new HashSet(collection))) {
Assert.assertEquals(toString(expected, "\n"), toString(collection, "\n"));
Assert.assertEquals(new HashSet(expected), new HashSet(collection));
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
index e017c1790cc6..74f21c4e530d 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
@@ -95,11 +95,9 @@ import com.intellij.psi.impl.cache.CacheManager;
import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.impl.source.PsiFileImpl;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.UsageSearchContext;
-import com.intellij.psi.statistics.StatisticsManager;
-import com.intellij.psi.statistics.impl.StatisticsManagerImpl;
import com.intellij.psi.stubs.StubUpdatingIndex;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
@@ -955,7 +953,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Nullable
protected Editor getCompletionEditor() {
- return InjectedLanguageFacadeImpl.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
+ return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
}
@Override
@@ -1050,8 +1048,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
public void tearDown() throws Exception {
- ((StatisticsManagerImpl)StatisticsManager.getInstance()).clearStatistics();
-
FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
VirtualFile[] openFiles = editorManager.getOpenFiles();
for (VirtualFile openFile : openFiles) {
diff --git a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java
index 5ca43ada3991..01974698c398 100644
--- a/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java
+++ b/platform/util/src/com/intellij/execution/rmi/RemoteUtil.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.util.containers.ConcurrentFactoryMap;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.lang.reflect.*;
import java.rmi.Remote;
@@ -59,34 +60,23 @@ public class RemoteUtil {
}
};
+ @Nullable
+ public static T castToRemote(final Object object, final Class clazz) {
+ if (!Proxy.isProxyClass(object.getClass())) return null;
+ final InvocationHandler handler = Proxy.getInvocationHandler(object);
+ if (handler instanceof RemoteInvocationHandler) {
+ final RemoteInvocationHandler rih = (RemoteInvocationHandler)handler;
+ if (clazz.isInstance(rih.myRemote)) {
+ return (T)rih.myRemote;
+ }
+ }
+ return null;
+ }
+
public static T castToLocal(final Object remote, final Class clazz) {
final ClassLoader loader = clazz.getClassLoader();
- Object proxy = Proxy.newProxyInstance(loader, new Class[]{clazz}, new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if (method.getDeclaringClass() == Object.class) {
- return method.invoke(remote, args);
- }
- else {
- Method m = ourRemoteToLocalMap.get(Pair., Class>>create(remote.getClass(), clazz)).get(method);
- if (m == null) throw new NoSuchMethodError(method.getName() + " in " + remote.getClass());
- try {
- Object result = m.invoke(remote, args);
- if (result instanceof Remote) {
- return castToLocal(result, tryFixReturnType(result, method.getReturnType(), loader));
- }
- return result;
- }
- catch (InvocationTargetException e) {
- Throwable cause = e.getCause();
- if (cause instanceof RuntimeException) throw cause;
- if (cause instanceof Error) throw cause;
- if (canThrow(cause, method)) throw cause;
- throw new RuntimeException(cause);
- }
- }
- }
- });
- return (T)proxy;
+ //noinspection unchecked
+ return (T)Proxy.newProxyInstance(loader, new Class[]{clazz}, new RemoteInvocationHandler(remote, clazz, loader));
}
private static Class> tryFixReturnType(Object result, Class> returnType, ClassLoader loader) throws Exception {
@@ -170,4 +160,40 @@ public class RemoteUtil {
}
return e;
}
+
+ private static class RemoteInvocationHandler implements InvocationHandler {
+ private final Object myRemote;
+ private final Class> myClazz;
+ private final ClassLoader myLoader;
+
+ public RemoteInvocationHandler(Object remote, Class> clazz, ClassLoader loader) {
+ myRemote = remote;
+ myClazz = clazz;
+ myLoader = loader;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getDeclaringClass() == Object.class) {
+ return method.invoke(myRemote, args);
+ }
+ else {
+ Method m = ourRemoteToLocalMap.get(Pair., Class>>create(myRemote.getClass(), myClazz)).get(method);
+ if (m == null) throw new NoSuchMethodError(method.getName() + " in " + myRemote.getClass());
+ try {
+ Object result = m.invoke(myRemote, args);
+ if (result instanceof Remote) {
+ return castToLocal(result, tryFixReturnType(result, method.getReturnType(), myLoader));
+ }
+ return result;
+ }
+ catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) throw cause;
+ if (cause instanceof Error) throw cause;
+ if (canThrow(cause, method)) throw cause;
+ throw new RuntimeException(cause);
+ }
+ }
+ }
+ }
}
diff --git a/platform/util/src/com/intellij/ui/ClickListener.java b/platform/util/src/com/intellij/ui/ClickListener.java
index 9b5346127a77..e7ed54769a99 100644
--- a/platform/util/src/com/intellij/ui/ClickListener.java
+++ b/platform/util/src/com/intellij/ui/ClickListener.java
@@ -33,28 +33,31 @@ public abstract class ClickListener {
public void installOn(final Component c) {
myListener = new MouseAdapter() {
- private Point clickPoint;
+ private Point pressPoint;
+ private Point lastClickPoint;
private long lastTimeClicked = -1;
private int clickCount = 0;
@Override
public void mousePressed(MouseEvent e) {
- if (Math.abs(lastTimeClicked - e.getWhen()) > TIME_EPS) {
+ if (Math.abs(lastTimeClicked - e.getWhen()) > TIME_EPS || (lastClickPoint != null && !isWithinEps(lastClickPoint, e.getPoint()))) {
clickCount = 0;
+ lastClickPoint = null;
}
clickCount++;
lastTimeClicked = e.getWhen();
if (!e.isPopupTrigger()) {
- clickPoint = e.getPoint();
+ pressPoint = e.getPoint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
Point releasedAt = e.getPoint();
- Point clickedAt = clickPoint;
- clickPoint = null;
+ Point clickedAt = pressPoint;
+ lastClickPoint = clickedAt;
+ pressPoint = null;
if (e.isConsumed()) return;
@@ -62,7 +65,7 @@ public abstract class ClickListener {
if (e.isPopupTrigger()) return;
if (releasedAt.x < 0 || releasedAt.y < 0 || releasedAt.x >= c.getWidth() || releasedAt.y >= c.getHeight()) return;
- if (Math.abs(clickedAt.x - releasedAt.x) < EPS && Math.abs(clickedAt.y - releasedAt.y) < EPS) {
+ if (isWithinEps(releasedAt, clickedAt)) {
if (onClick(e, clickCount)) {
e.consume();
}
@@ -73,6 +76,10 @@ public abstract class ClickListener {
c.addMouseListener(myListener);
}
+ private static boolean isWithinEps(Point releasedAt, Point clickedAt) {
+ return Math.abs(clickedAt.x - releasedAt.x) < EPS && Math.abs(clickedAt.y - releasedAt.y) < EPS;
+ }
+
public void uninstall(Component c) {
c.removeMouseListener(myListener);
}
diff --git a/platform/util/src/com/intellij/util/CommonProcessors.java b/platform/util/src/com/intellij/util/CommonProcessors.java
index e0b3492610ae..0d0a6033b235 100644
--- a/platform/util/src/com/intellij/util/CommonProcessors.java
+++ b/platform/util/src/com/intellij/util/CommonProcessors.java
@@ -59,19 +59,6 @@ public class CommonProcessors {
return myCollection;
}
- public static class Sync extends CollectProcessor {
- public Sync(final Collection collection) {
- super(collection);
- }
-
- public Sync() {
- }
-
- @Override
- public synchronized boolean process(final T t) {
- return super.process(t);
- }
- }
}
@NotNull
diff --git a/platform/util/src/com/intellij/util/io/DataInputOutputUtil.java b/platform/util/src/com/intellij/util/io/DataInputOutputUtil.java
index f19ee9881643..31c3b4f81205 100644
--- a/platform/util/src/com/intellij/util/io/DataInputOutputUtil.java
+++ b/platform/util/src/com/intellij/util/io/DataInputOutputUtil.java
@@ -38,12 +38,10 @@ public class DataInputOutputUtil {
public static void writeNAME(DataOutput record, final String name, AbstractStringEnumerator nameStore) throws IOException {
final int nameId = name != null ? nameStore.enumerate(name) : 0;
- record.writeByte(nameId & 0xFF);
- writeINT(record, (nameId >> 8));
+ writeINT(record, nameId);
}
public static void skipNAME(DataInput record) throws IOException {
- record.readUnsignedByte();
readINT(record);
}
diff --git a/platform/util/src/com/intellij/util/io/StringRef.java b/platform/util/src/com/intellij/util/io/StringRef.java
index a45c08e93bba..d2b8c281aef1 100644
--- a/platform/util/src/com/intellij/util/io/StringRef.java
+++ b/platform/util/src/com/intellij/util/io/StringRef.java
@@ -99,8 +99,7 @@ public class StringRef {
}
public static StringRef fromStream(DataInput in, AbstractStringEnumerator store) throws IOException {
- final int low = in.readUnsignedByte();
- final int nameId = (DataInputOutputUtil.readINT(in) << 8) | low;
+ final int nameId = DataInputOutputUtil.readINT(in);
return nameId != 0 ? new StringRef(nameId, store) : null;
}
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/EditInjectionSettingsAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/EditInjectionSettingsAction.java
index ee119a8a08e1..cc97dfd8c000 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/EditInjectionSettingsAction.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/EditInjectionSettingsAction.java
@@ -26,7 +26,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.FileContentUtil;
import com.intellij.util.IncorrectOperationException;
import org.intellij.plugins.intelliLang.Configuration;
@@ -53,7 +53,7 @@ public class EditInjectionSettingsAction implements IntentionAction, LowPriority
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final int offset = editor.getCaretModel().getOffset();
- final PsiFile psiFile = InjectedLanguageFacadeImpl.findInjectedPsiNoCommit(file, offset);
+ final PsiFile psiFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, offset);
if (psiFile == null) return false;
final LanguageInjectionSupport support = psiFile.getUserData(LanguageInjectionSupport.SETTINGS_EDITOR);
return support != null;
@@ -68,7 +68,7 @@ public class EditInjectionSettingsAction implements IntentionAction, LowPriority
}
private static void invokeImpl(Project project, Editor editor, PsiFile file) {
- final PsiFile psiFile = InjectedLanguageFacadeImpl.findInjectedPsiNoCommit(file, editor.getCaretModel().getOffset());
+ final PsiFile psiFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, editor.getCaretModel().getOffset());
if (psiFile == null) return;
final PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(project).getInjectionHost(psiFile);
if (host == null) return;
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
index ff564b8899f7..78986215c8a8 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
@@ -16,7 +16,7 @@
package org.intellij.plugins.intelliLang.inject;
import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.lang.Language;
@@ -65,7 +65,7 @@ public class InjectLanguageAction implements IntentionAction {
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiLanguageInjectionHost host = findInjectionHost(editor, file);
if (host == null) return false;
- final List> injectedPsi = InjectedLanguageFacadeImpl.getInstance().getInjectedPsiFiles(host);
+ final List> injectedPsi = InjectedLanguageUtil.getInstance().getInjectedPsiFiles(host);
return injectedPsi == null || injectedPsi.isEmpty();
}
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/UnInjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/UnInjectLanguageAction.java
index 3829287efc27..c079935c2010 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/UnInjectLanguageAction.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/UnInjectLanguageAction.java
@@ -28,7 +28,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.FileContentUtil;
import com.intellij.util.IncorrectOperationException;
import gnu.trove.THashSet;
@@ -55,7 +55,7 @@ public class UnInjectLanguageAction implements IntentionAction, LowPriorityActio
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final int offset = editor.getCaretModel().getOffset();
- final PsiFile psiFile = InjectedLanguageFacadeImpl.findInjectedPsiNoCommit(file, offset);
+ final PsiFile psiFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, offset);
if (psiFile == null) return false;
final LanguageInjectionSupport support = psiFile.getUserData(LanguageInjectionSupport.INJECTOR_SUPPORT);
return support != null;
@@ -70,7 +70,7 @@ public class UnInjectLanguageAction implements IntentionAction, LowPriorityActio
}
private static void invokeImpl(Project project, Editor editor, PsiFile file) {
- final PsiFile psiFile = InjectedLanguageFacadeImpl.findInjectedPsiNoCommit(file, editor.getCaretModel().getOffset());
+ final PsiFile psiFile = InjectedLanguageUtil.findInjectedPsiNoCommit(file, editor.getCaretModel().getOffset());
if (psiFile == null) return;
final PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(project).getInjectionHost(psiFile);
if (host == null) return;
@@ -88,7 +88,7 @@ public class UnInjectLanguageAction implements IntentionAction, LowPriorityActio
private static boolean defaultFunctionalityWorked(final PsiLanguageInjectionHost host) {
final THashSet languages = new THashSet();
- final List> files = InjectedLanguageFacadeImpl.getInstance().getInjectedPsiFiles(host);
+ final List> files = InjectedLanguageUtil.getInstance().getInjectedPsiFiles(host);
if (files == null) return false;
for (Pair pair : files) {
for (Language lang = pair.first.getLanguage(); lang != null; lang = lang.getBaseLanguage()) {
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/CommentOnLineWithSourcePredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/CommentOnLineWithSourcePredicate.java
index ed366ec1b1ef..a76a86fedbbe 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/CommentOnLineWithSourcePredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/CommentOnLineWithSourcePredicate.java
@@ -16,7 +16,7 @@
package com.siyeh.ipp.comment;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
@@ -37,7 +37,7 @@ class CommentOnLineWithSourcePredicate implements PsiElementPredicate {
}
final PsiComment comment = (PsiComment)element;
- if (comment instanceof PsiLanguageInjectionHost && InjectedLanguageFacadeImpl.hasInjections((PsiLanguageInjectionHost)comment)) {
+ if (comment instanceof PsiLanguageInjectionHost && InjectedLanguageUtil.hasInjections((PsiLanguageInjectionHost)comment)) {
return false;
}
final IElementType type = comment.getTokenType();
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java
index 9efdeaf805a6..9e0b492f28cb 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/opassign/ReplaceOperatorAssignmentWithAssignmentIntention.java
@@ -31,21 +31,19 @@ import java.util.Map;
public class ReplaceOperatorAssignmentWithAssignmentIntention
extends MutablyNamedIntention {
- private static final Map tokenMap = new HashMap();
-
- static {
- tokenMap.put(JavaTokenType.PLUSEQ, JavaTokenType.PLUS);
- tokenMap.put(JavaTokenType.MINUSEQ, JavaTokenType.MINUS);
- tokenMap.put(JavaTokenType.ASTERISKEQ, JavaTokenType.ASTERISK);
- tokenMap.put(JavaTokenType.DIVEQ, JavaTokenType.DIV);
- tokenMap.put(JavaTokenType.ANDEQ, JavaTokenType.AND);
- tokenMap.put(JavaTokenType.OREQ, JavaTokenType.OR);
- tokenMap.put(JavaTokenType.XOREQ, JavaTokenType.XOR);
- tokenMap.put(JavaTokenType.PERCEQ, JavaTokenType.PERC);
- tokenMap.put(JavaTokenType.LTLTEQ, JavaTokenType.LTLT);
- tokenMap.put(JavaTokenType.GTGTEQ, JavaTokenType.GTGT);
- tokenMap.put(JavaTokenType.GTGTGTEQ, JavaTokenType.GTGTGT);
- }
+ private static final Map tokenMap = new HashMap() {{
+ put(JavaTokenType.PLUSEQ, JavaTokenType.PLUS);
+ put(JavaTokenType.MINUSEQ, JavaTokenType.MINUS);
+ put(JavaTokenType.ASTERISKEQ, JavaTokenType.ASTERISK);
+ put(JavaTokenType.DIVEQ, JavaTokenType.DIV);
+ put(JavaTokenType.ANDEQ, JavaTokenType.AND);
+ put(JavaTokenType.OREQ, JavaTokenType.OR);
+ put(JavaTokenType.XOREQ, JavaTokenType.XOR);
+ put(JavaTokenType.PERCEQ, JavaTokenType.PERC);
+ put(JavaTokenType.LTLTEQ, JavaTokenType.LTLT);
+ put(JavaTokenType.GTGTEQ, JavaTokenType.GTGT);
+ put(JavaTokenType.GTGTGTEQ, JavaTokenType.GTGTGT);
+ }};
@Override
@NotNull
diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java b/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java
index 060aa7b71f82..e67384ab57f7 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/model/ModelParser.java
@@ -364,7 +364,7 @@ public class ModelParser extends XmlRecursiveElementVisitor {
if (myRootComponent == null) {
myRootComponent = createComponent(myXmlFile.getRootTag(), myMetaManager.getModelByTag(""));
}
- else if (session.getRootViews().size() == 1) {
+ else if (myRootComponent.getMetaModel() != myMetaManager.getModelByTag("merge")) {
RadViewComponent rootComponent = myRootComponent;
myRootComponent = createComponent(myXmlFile.getRootTag(), myMetaManager.getModelByTag(""));
myRootComponent.add(rootComponent, null);
diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java
index 8c5ddb5ec3fe..e1f0a6e4a45e 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadCustomViewComponent.java
@@ -25,7 +25,6 @@ import com.intellij.designer.model.MetaModel;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.propertyTable.Property;
import com.intellij.designer.propertyTable.PropertyTable;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiClass;
import com.intellij.psi.xml.XmlTag;
@@ -71,7 +70,7 @@ public class RadCustomViewComponent extends RadViewComponent implements IConfigu
new ChooseClassDialog(moduleProvider.getModule(), "Views", false, "android.view.View");
dialog.show();
- if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ if (dialog.isOK()) {
return dialog.getClassName();
}
diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java
index aa5b172006ae..78fcf85129f9 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadFragment.java
@@ -24,7 +24,6 @@ import com.intellij.designer.ModuleProvider;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.propertyTable.Property;
import com.intellij.designer.propertyTable.editors.TextEditor;
-import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.android.dom.attrs.AttributeFormat;
import org.jetbrains.annotations.Nullable;
@@ -86,7 +85,7 @@ public class RadFragment extends RadViewComponent implements IConfigurableCompon
new ChooseClassDialog(moduleProvider.getModule(), "Fragments", true, "android.app.Fragment", "android.support.v4.app.Fragment");
dialog.show();
- if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ if (dialog.isOK()) {
return dialog.getClassName();
}
diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadIncludeLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadIncludeLayout.java
index 8dfc12729da3..25c18d6113c4 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/model/RadIncludeLayout.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadIncludeLayout.java
@@ -41,7 +41,7 @@ public class RadIncludeLayout extends RadViewComponent implements IConfigurableC
public void configure(RadComponent rootComponent) throws Exception {
ModuleProvider moduleProvider = rootComponent.getClientProperty(ModelParser.MODULE_KEY);
- ResourceDialog dialog = new ResourceDialog(moduleProvider.getModule(), IncludeLayoutProperty.TYPES, null);
+ ResourceDialog dialog = new ResourceDialog(moduleProvider.getModule(), IncludeLayoutProperty.TYPES, null, null);
dialog.show();
if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ChooseClassDialog.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ChooseClassDialog.java
index 23b901043cb0..67df90be0adf 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ChooseClassDialog.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ChooseClassDialog.java
@@ -80,7 +80,7 @@ public class ChooseClassDialog extends DialogWrapper implements ListSelectionLis
};
setTitle(title);
- getOKAction().setEnabled(false);
+ setOKActionEnabled(false);
init();
}
@@ -119,7 +119,7 @@ public class ChooseClassDialog extends DialogWrapper implements ListSelectionLis
@Override
public void valueChanged(ListSelectionEvent e) {
PsiClass psiClass = (PsiClass)myList.getSelectedValue();
- getOKAction().setEnabled(psiClass != null);
+ setOKActionEnabled(psiClass != null);
myResultClassName = psiClass == null ? null : psiClass.getQualifiedName();
}
}
diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ExtractStyleDialog.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ExtractStyleDialog.java
new file mode 100644
index 000000000000..705f7cf6ef0c
--- /dev/null
+++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ExtractStyleDialog.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.android.designer.propertyTable.editors;
+
+import com.android.resources.ResourceType;
+import com.intellij.openapi.actionSystem.ActionToolbarPosition;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.ui.*;
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.android.actions.CreateXmlResourceDialog;
+import org.jetbrains.android.util.AndroidResourceUtil;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Alexander Lobas
+ */
+public class ExtractStyleDialog extends DialogWrapper {
+ private final Module myModule;
+ private final String myFileName;
+ private final List myDirNames;
+
+ private final JPanel myPanel;
+ private final JTextField myNameText;
+ private final CheckboxTree myTree;
+
+ private final CheckedTreeNode myRootNode;
+
+ public ExtractStyleDialog(Module module, String fileName, List dirNames, XmlTag tag) {
+ super(module.getProject());
+ myModule = module;
+ myFileName = fileName;
+ myDirNames = dirNames;
+
+ myPanel = new JPanel(new GridLayoutManager(3, 2));
+
+ JLabel nameLabel = new JLabel("Style name:");
+ nameLabel.setDisplayedMnemonic('n');
+ myPanel.add(nameLabel,
+ new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, 0, 0, null, null, null));
+
+ myNameText = new JTextField();
+ myPanel.add(myNameText, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL,
+ GridConstraints.SIZEPOLICY_CAN_GROW, 0, null, null, null));
+
+ nameLabel.setLabelFor(myNameText);
+
+ myNameText.getDocument().addDocumentListener(new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ checkFinish();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ checkFinish();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ checkFinish();
+ }
+ });
+
+ JLabel attributesLabel = new JLabel("Attributes:");
+ attributesLabel.setDisplayedMnemonic('A');
+ myPanel.add(attributesLabel,
+ new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, 0, 0, null, null, null));
+
+ myRootNode = new CheckedTreeNode(null);
+ for (XmlAttribute attribute : tag.getAttributes()) {
+ String name = attribute.getName();
+ if (!"style".equalsIgnoreCase(name)) {
+ CheckedTreeNode treeNode = new CheckedTreeNode(attribute);
+ treeNode.setChecked(!"android:layout_width".equalsIgnoreCase(name) && !"android:layout_height".equalsIgnoreCase(name));
+ myRootNode.add(treeNode);
+ }
+ }
+
+ CheckboxTree.CheckboxTreeCellRenderer renderer = new CheckboxTree.CheckboxTreeCellRenderer() {
+ @Override
+ public void customizeRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ if (value instanceof CheckedTreeNode) {
+ XmlAttribute attribute = (XmlAttribute)((CheckedTreeNode)value).getUserObject();
+ if (attribute != null) {
+ getTextRenderer().append(attribute.getLocalName());
+ getTextRenderer().append(" [" + attribute.getValue() + "]", SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
+ }
+ }
+ }
+ };
+ myTree = new CheckboxTree(renderer, myRootNode) {
+ @Override
+ protected void onNodeStateChanged(CheckedTreeNode node) {
+ checkFinish();
+ }
+
+ protected void installSpeedSearch() {
+ new TreeSpeedSearch(this, new Convertor() {
+ public String convert(TreePath path) {
+ Object object = path.getLastPathComponent();
+ if (object instanceof CheckedTreeNode) {
+ XmlAttribute attribute = (XmlAttribute)((CheckedTreeNode)object).getUserObject();
+ if (attribute != null) {
+ return attribute.getLocalName();
+ }
+ }
+ return "";
+ }
+ });
+ }
+ };
+ myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+ myTree.setRootVisible(false);
+ myTree.setShowsRootHandles(false);
+ TreeUtil.expandAll(myTree);
+
+ attributesLabel.setLabelFor(myTree);
+
+ ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTree);
+ decorator.setToolbarPosition(ActionToolbarPosition.RIGHT);
+ decorator.setEditAction(null);
+ decorator.disableUpDownActions();
+
+ AnActionButton selectAll = new AnActionButton("Select All", null, PlatformIcons.SELECT_ALL_ICON) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ setChecked(true);
+ }
+ };
+ decorator.addExtraAction(selectAll);
+
+ AnActionButton unselectAll = new AnActionButton("Unselect All", null, PlatformIcons.UNSELECT_ALL_ICON) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ setChecked(false);
+ }
+ };
+ decorator.addExtraAction(unselectAll);
+
+
+ myPanel.add(decorator.createPanel(),
+ new GridConstraints(2, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
+ GridConstraints.SIZEPOLICY_CAN_GROW, 0, null, null, null));
+
+ myPanel.setPreferredSize(new Dimension(400, -1));
+
+ setTitle("Extract Style");
+ checkFinish();
+ init();
+ }
+
+ private void checkFinish() {
+ if (AndroidResourceUtil.isCorrectAndroidResourceName(myNameText.getText().trim())) {
+ int count = myRootNode.getChildCount();
+ for (int i = 0; i < count; i++) {
+ CheckedTreeNode treeNode = (CheckedTreeNode)myRootNode.getChildAt(i);
+ if (treeNode.isChecked()) {
+ setOKActionEnabled(true);
+ return;
+ }
+ }
+ }
+ setOKActionEnabled(false);
+ }
+
+ private void setChecked(boolean value) {
+ int count = myRootNode.getChildCount();
+ for (int i = 0; i < count; i++) {
+ ((CheckedTreeNode)myRootNode.getChildAt(i)).setChecked(value);
+ }
+ myTree.repaint();
+ checkFinish();
+ }
+
+ @Override
+ protected JComponent createCenterPanel() {
+ return myPanel;
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myNameText;
+ }
+
+ @Override
+ protected ValidationInfo doValidate() {
+ return CreateXmlResourceDialog.checkIfResourceAlreadyExists(myModule, getStyleName(), ResourceType.STYLE, myDirNames, myFileName);
+ }
+
+ @NotNull
+ public String getStyleName() {
+ return myNameText.getText();
+ }
+
+ @NotNull
+ public List getStyledAttributes() {
+ List attributes = new ArrayList();
+
+ int count = myRootNode.getChildCount();
+ for (int i = 0; i < count; i++) {
+ CheckedTreeNode treeNode = (CheckedTreeNode)myRootNode.getChildAt(i);
+ if (treeNode.isChecked()) {
+ attributes.add((XmlAttribute)treeNode.getUserObject());
+ }
+ }
+
+ return attributes;
+ }
+}
\ No newline at end of file
diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceDialog.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceDialog.java
index e2803d2928b4..9ec76683bcd1 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceDialog.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceDialog.java
@@ -15,7 +15,9 @@
*/
package com.intellij.android.designer.propertyTable.editors;
+import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
+import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.android.designer.propertyTable.renderers.ResourceRenderer;
import com.intellij.designer.componentTree.TreeNodeDescriptor;
import com.intellij.icons.AllIcons;
@@ -23,19 +25,30 @@ import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.NodeRenderer;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlAttribute;
import com.intellij.ui.*;
import com.intellij.ui.components.JBTabbedPane;
import com.intellij.ui.speedSearch.SpeedSearchUtil;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.android.actions.CreateResourceFileAction;
+import org.jetbrains.android.actions.CreateXmlResourceDialog;
import org.jetbrains.android.facet.AndroidFacet;
+import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.resourceManagers.ResourceManager;
import org.jetbrains.android.util.AndroidCommonUtils;
+import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -60,23 +73,53 @@ import java.util.List;
*/
public class ResourceDialog extends DialogWrapper implements TreeSelectionListener {
private static final String ANDROID = "@android:";
+ private static final String TYPE_KEY = "ResourceType";
private static final Icon RESOURCE_ITEM_ICON = AllIcons.Css.Property;
+ private final Module myModule;
+ private final RadViewComponent myComponent;
+
private final JBTabbedPane myContentPanel;
private final ResourcePanel myProjectPanel;
private final ResourcePanel mySystemPanel;
private ColorPicker myColorPicker;
- private final Action myNewResourceAction = new AbstractAction("New Resource...") {
+
+ private final Action myNewResourceAction = new AbstractAction("New Resource", AllIcons.General.ComboArrowDown) {
@Override
public void actionPerformed(ActionEvent e) {
- // TODO: Auto-generated method stub
+ JComponent component = (JComponent)e.getSource();
+ ActionPopupMenu popupMenu = createNewResourcePopupMenu();
+ popupMenu.getComponent().show(component, 0, component.getHeight());
}
};
+ private final AnAction myNewResourceValueAction = new AnAction() {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ ResourceType type = (ResourceType)getTemplatePresentation().getClientProperty(TYPE_KEY);
+ createNewResourceValue(type);
+ }
+ };
+ private final AnAction myNewResourceFileAction = new AnAction() {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ ResourceType type = (ResourceType)getTemplatePresentation().getClientProperty(TYPE_KEY);
+ createNewResourceFile(type);
+ }
+ };
+ private final AnAction myExtractStyleAction = new AnAction("Extract Style...") {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ extractStyle();
+ }
+ };
+
private String myResultResourceName;
- public ResourceDialog(Module module, ResourceType[] types, String value) {
+ public ResourceDialog(Module module, ResourceType[] types, String value, RadViewComponent component) {
super(module.getProject());
+ myModule = module;
+ myComponent = component;
setTitle("Resources");
@@ -123,13 +166,126 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
myContentPanel.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
- myNewResourceAction.setEnabled(myContentPanel.getSelectedComponent() == myProjectPanel.myComponent);
valueChanged(null);
}
});
- init();
valueChanged(null);
+ init();
+ }
+
+ private ActionPopupMenu createNewResourcePopupMenu() {
+ ActionManager actionManager = ActionManager.getInstance();
+ DefaultActionGroup actionGroup = new DefaultActionGroup();
+
+ ResourceGroup resourceGroup = getSelectedElement(myProjectPanel.myTreeBuilder, ResourceGroup.class);
+ if (resourceGroup == null) {
+ resourceGroup = getSelectedElement(myProjectPanel.myTreeBuilder, ResourceItem.class).getGroup();
+ }
+
+ if (AndroidResourceUtil.VALUE_RESOURCE_TYPES.contains(resourceGroup.getType())) {
+ myNewResourceValueAction.getTemplatePresentation().setText("New " + resourceGroup + " Value...");
+ myNewResourceValueAction.getTemplatePresentation().putClientProperty(TYPE_KEY, resourceGroup.getType());
+ actionGroup.add(myNewResourceValueAction);
+ }
+ if (AndroidResourceUtil.XML_FILE_RESOURCE_TYPES.contains(resourceGroup.getType())) {
+ myNewResourceFileAction.getTemplatePresentation().setText("New " + resourceGroup + " File...");
+ myNewResourceFileAction.getTemplatePresentation().putClientProperty(TYPE_KEY, resourceGroup.getType());
+ actionGroup.add(myNewResourceFileAction);
+ }
+ if (myComponent != null && ResourceType.STYLE.equals(resourceGroup.getType()) && myComponent.getTag().getAttributes().length > 0) {
+ // TODO: add StyleItem
+ //actionGroup.add(myExtractStyleAction);
+ }
+
+ return actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, actionGroup);
+ }
+
+ private void createNewResourceValue(ResourceType resourceType) {
+ CreateXmlResourceDialog dialog = new CreateXmlResourceDialog(myModule, resourceType, null, null, true);
+ dialog.setTitle("New " + StringUtil.capitalize(resourceType.getDisplayName()) + " Value Resource");
+ dialog.show();
+
+ if (!dialog.isOK()) {
+ return;
+ }
+
+ Module moduleToPlaceResource = dialog.getModule();
+ if (moduleToPlaceResource == null) {
+ return;
+ }
+
+ String fileName = dialog.getFileName();
+ List dirNames = dialog.getDirNames();
+ String resValue = dialog.getValue();
+ String resName = dialog.getResourceName();
+ if (!AndroidResourceUtil.createValueResource(moduleToPlaceResource, resName, resourceType, fileName, dirNames, resValue)) {
+ return;
+ }
+
+ PsiDocumentManager.getInstance(myModule.getProject()).commitAllDocuments();
+
+ myResultResourceName = "@" + resourceType.getName() + "/" + resName;
+ close(OK_EXIT_CODE);
+ }
+
+ private void createNewResourceFile(ResourceType resourceType) {
+ AndroidFacet facet = AndroidFacet.getInstance(myModule);
+ PsiElement[] elements = CreateResourceFileAction.createFileResource(facet, resourceType, null, true);
+
+ if (elements.length == 1) {
+ String name = ((PsiFile)elements[0]).getName();
+ int index = name.lastIndexOf('.');
+ if (index != -1) {
+ name = name.substring(0, index);
+ }
+ myResultResourceName = "@" + resourceType.getName() + "/" + name;
+ close(OK_EXIT_CODE);
+ }
+ }
+
+ private void extractStyle() {
+ String fileName = AndroidResourceUtil.getDefaultResourceFileName(ResourceType.STYLE);
+
+ VirtualFile[] dirs = {AndroidRootUtil.getResourceDir(AndroidFacet.getInstance(myModule))};
+ List subDirs = AndroidResourceUtil.getResourceSubdirs(ResourceFolderType.VALUES.getName(), dirs);
+ List dirNames = new ArrayList();
+ for (VirtualFile dir : subDirs) {
+ dirNames.add(dir.getName());
+ }
+
+ ExtractStyleDialog dialog = new ExtractStyleDialog(myModule, fileName, dirNames, myComponent.getTag());
+ dialog.show();
+
+ if (!dialog.isOK()) {
+ return;
+ }
+
+ final List attributes = dialog.getStyledAttributes();
+
+ StringBuilder value = new StringBuilder();
+ for (XmlAttribute attribute : attributes) {
+ value.append("- ").append(attribute.getValue()).append("
\n");
+ }
+
+ String resName = dialog.getStyleName();
+ if (!AndroidResourceUtil.createValueResource(myModule, resName, ResourceType.STYLE, fileName, dirNames, value.toString())) {
+ return;
+ }
+
+ PsiDocumentManager.getInstance(myModule.getProject()).commitAllDocuments();
+
+ ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ @Override
+ public void run() {
+ for (XmlAttribute attribute : attributes) {
+ attribute.delete();
+ }
+ }
+ });
+
+ myResultResourceName = "@style/" + resName;
+ close(OK_EXIT_CODE);
}
@Override
@@ -144,7 +300,7 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
@Override
protected Action[] createLeftSideActions() {
- return super.createLeftSideActions();//new Action[]{myNewResourceAction};
+ return new Action[]{myNewResourceAction};
}
@Override
@@ -164,26 +320,35 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
super.doOKAction();
}
+ @Nullable
+ private static T getSelectedElement(AbstractTreeBuilder treeBuilder, Class elementClass) {
+ Set elements = treeBuilder.getSelectedElements(elementClass);
+ return elements.isEmpty() ? null : elements.iterator().next();
+ }
+
@Override
public void valueChanged(@Nullable TreeSelectionEvent e) {
Component selectedComponent = myContentPanel.getSelectedComponent();
if (selectedComponent == myColorPicker) {
Color color = myColorPicker.getColor();
- getOKAction().setEnabled(color != null);
+ setOKActionEnabled(color != null);
+ myNewResourceAction.setEnabled(false);
myResultResourceName = color == null ? null : "#" + toHex(color.getRed()) + toHex(color.getGreen()) + toHex(color.getBlue());
}
else {
- ResourcePanel panel = selectedComponent == myProjectPanel.myComponent ? myProjectPanel : mySystemPanel;
- Set elements = panel.myTreeBuilder.getSelectedElements(ResourceItem.class);
- getOKAction().setEnabled(!elements.isEmpty());
+ boolean isProjectPanel = selectedComponent == myProjectPanel.myComponent;
+ ResourcePanel panel = isProjectPanel ? myProjectPanel : mySystemPanel;
+ ResourceItem element = getSelectedElement(panel.myTreeBuilder, ResourceItem.class);
+ setOKActionEnabled(element != null);
+ myNewResourceAction.setEnabled(isProjectPanel && !panel.myTreeBuilder.getSelectedElements().isEmpty());
- if (elements.isEmpty()) {
+ if (element == null) {
myResultResourceName = null;
}
else {
String prefix = panel == myProjectPanel ? "@" : ANDROID;
- myResultResourceName = prefix + elements.iterator().next().getName();
+ myResultResourceName = prefix + element.getName();
}
}
}
@@ -316,6 +481,10 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
});
}
+ public ResourceType getType() {
+ return myType;
+ }
+
public String getName() {
return myType.getName();
}
diff --git a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java
index 0f08b55dad2b..575519304e52 100644
--- a/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java
+++ b/plugins/android-designer/src/com/intellij/android/designer/propertyTable/editors/ResourceEditor.java
@@ -17,6 +17,7 @@ package com.intellij.android.designer.propertyTable.editors;
import com.android.resources.ResourceType;
import com.intellij.android.designer.model.ModelParser;
+import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.ModuleProvider;
import com.intellij.designer.model.RadComponent;
import com.intellij.designer.propertyTable.InplaceContext;
@@ -26,7 +27,6 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ComboboxWithBrowseButton;
@@ -50,6 +50,7 @@ public class ResourceEditor extends PropertyEditor {
private final ResourceType[] myTypes;
private ComponentWithBrowseButton myEditor;
protected RadComponent myRootComponent;
+ private RadComponent myComponent;
private JCheckBox myCheckBox;
private final Border myCheckBoxBorder = new JTextField().getBorder();
private boolean myIgnoreCheckBoxValue;
@@ -207,6 +208,7 @@ public class ResourceEditor extends PropertyEditor {
Object object,
@Nullable InplaceContext inplaceContext) {
myRootComponent = rootComponent;
+ myComponent = component;
String value = (String)object;
JTextField text = getComboText();
@@ -270,10 +272,10 @@ public class ResourceEditor extends PropertyEditor {
protected void showDialog() {
ModuleProvider moduleProvider = myRootComponent.getClientProperty(ModelParser.MODULE_KEY);
- ResourceDialog dialog = new ResourceDialog(moduleProvider.getModule(), myTypes, (String)getValue());
+ ResourceDialog dialog = new ResourceDialog(moduleProvider.getModule(), myTypes, (String)getValue(), (RadViewComponent)myComponent);
dialog.show();
- if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ if (dialog.isOK()) {
setValue(dialog.getResourceName());
}
else if (myBooleanResourceValue != null) {
diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java b/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java
index 13ca21a45c5d..b6c2a0650fb0 100644
--- a/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java
+++ b/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java
@@ -94,7 +94,7 @@ public class CreateResourceFileAction extends CreateElementActionBase {
@NotNull
public static PsiElement[] createFileResource(@NotNull AndroidFacet facet,
@NotNull final ResourceType resType,
- @NotNull String resName,
+ @Nullable String resName,
boolean chooseResName) {
final CreateResourceFileAction action = getInstance();
diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java b/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java
index c40f66ff5189..de177fd26377 100644
--- a/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java
+++ b/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java
@@ -344,7 +344,7 @@ public class CreateXmlResourceDialog extends DialogWrapper {
}
@Nullable
- private static ValidationInfo checkIfResourceAlreadyExists(@NotNull Module selectedModule,
+ public static ValidationInfo checkIfResourceAlreadyExists(@NotNull Module selectedModule,
@NotNull String resourceName,
@NotNull ResourceType resourceType,
@NotNull List dirNames,
diff --git a/plugins/android/testSrc/org/jetbrains/android/AndroidRenameTest.java b/plugins/android/testSrc/org/jetbrains/android/AndroidRenameTest.java
index 0cf268f4b7a5..e51b34026cfb 100644
--- a/plugins/android/testSrc/org/jetbrains/android/AndroidRenameTest.java
+++ b/plugins/android/testSrc/org/jetbrains/android/AndroidRenameTest.java
@@ -27,7 +27,7 @@ import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageFacadeImpl;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.actions.RenameElementAction;
@@ -106,7 +106,7 @@ public class AndroidRenameTest extends AndroidTestCase {
protected void run() throws Throwable {
Editor editor = myFixture.getEditor();
PsiFile file = myFixture.getFile();
- Editor completionEditor = InjectedLanguageFacadeImpl.getEditorForInjectedLanguageNoCommit(editor, file);
+ Editor completionEditor = InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, file);
PsiElement element = TargetElementUtilBase.findTargetElement(completionEditor, TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED |
TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
assert element != null;
diff --git a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java
index 44a430482516..7a137a175f05 100644
--- a/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java
+++ b/plugins/git4idea/src/git4idea/merge/GitMergeProvider.java
@@ -323,7 +323,8 @@ public class GitMergeProvider implements MergeProvider2 {
for (VirtualFile f : files) {
String path = VcsFileUtil.relativePath(root, f);
Conflict c = cs.get(path);
- assert c != null : "The conflict not found for the file: " + f.getPath() + "(" + path + ")";
+ log.assertTrue(c != null, String.format("The conflict not found for the file: %s(%s)%nFull ls-files output: %n%s",
+ f.getPath(), path, output));
c.myFile = f;
if (c.myStatusTheirs == null) {
c.myStatusTheirs = Conflict.Status.DELETED;
diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/after.groovy.template
new file mode 100644
index 000000000000..d39ed06ecad8
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/after.groovy.template
@@ -0,0 +1,2 @@
+print '''first
+ second'''
\ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/before.groovy.template
new file mode 100644
index 000000000000..588872062d48
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/before.groovy.template
@@ -0,0 +1 @@
+print 'first\n second'
\ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/description.html
new file mode 100644
index 000000000000..5bc803413371
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/ConvertStringToMultilineIntention/description.html
@@ -0,0 +1,5 @@
+
+
+This intention converts singleline string literal to multiline literal.
+
+
\ No newline at end of file
diff --git a/plugins/groovy/rt/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java b/plugins/groovy/rt/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
index 10c1efcbf01b..093e7182181f 100644
--- a/plugins/groovy/rt/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
+++ b/plugins/groovy/rt/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
@@ -1,6 +1,7 @@
package org.jetbrains.jps.incremental.groovy;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ArrayUtil;
@@ -29,6 +30,7 @@ import java.util.*;
* Date: 10/25/11
*/
public class GroovyBuilder extends ModuleLevelBuilder {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.groovy.GroovyBuilder");
public static final String BUILDER_NAME = "groovy";
private static final Key CHUNK_REBUILD_ORDERED = Key.create("CHUNK_REBUILD_ORDERED");
private final boolean myForStubs;
@@ -47,6 +49,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
public ModuleLevelBuilder.ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
try {
final List toCompile = collectChangedFiles(context, chunk);
+ LOG.info((myForStubs ? "stubs" : "groovyc") + ", toCompile=" + toCompile);
if (toCompile.isEmpty()) {
return ExitCode.NOTHING_DONE;
}
@@ -92,6 +95,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
CHUNK_REBUILD_ORDERED.set(context, null);
} else {
CHUNK_REBUILD_ORDERED.set(context, Boolean.TRUE);
+ LOG.info("Order chunk rebuild");
return ExitCode.CHUNK_REBUILD_REQUIRED;
}
}
@@ -104,12 +108,14 @@ public class GroovyBuilder extends ModuleLevelBuilder {
}
for (CompilerMessage message : handler.getCompilerMessages()) {
+ LOG.info(message.toString());
context.processMessage(message);
}
List compiled = new ArrayList();
for (GroovycOSProcessHandler.OutputItem item : handler.getSuccessfullyCompiled()) {
+ LOG.info("Compiled " + item);
compiled.add(ensureCorrectOutput(context, chunk, item, generationOutputs, compilerOutput));
}
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 65d5a32f4603..84ec2b08e529 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -1106,6 +1106,11 @@
intention.category.groovy/intention.category.conversions
org.jetbrains.plugins.groovy.intentions.conversions.ConvertMethodToClosureIntention
+
+ org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle
+ intention.category.groovy/intention.category.conversions
+ org.jetbrains.plugins.groovy.intentions.conversions.ConvertStringToMultilineIntention
+
org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle
intention.category.groovy/intention.category.conversions
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
index 21fc4b593aaa..440dd72eb7aa 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties
@@ -124,6 +124,7 @@ import.class=Import Class
create.class.family.name=Create Class
create.class.text=Create Class {0}
create.interface.text=Create Interface {0}
+create.annotation.text=Create Annotation {0}
static.declaration.in.inner.class=Inner classes cannot have static declarations
constructors.are.not.allowed.in.anonymous.class=Constructors are not allowed in anonymous class
no.such.property=Property ''{0}'' does not exist
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
index 8de676cd4da2..5ae9c3c6b8ae 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
import com.intellij.codeInsight.daemon.impl.quickfix.AddMethodBodyFix;
+import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind;
import com.intellij.codeInsight.daemon.impl.quickfix.CreateConstructorMatchingSuperFix;
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
@@ -165,8 +166,8 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
annotation.setTextAttributes(DefaultHighlighter.METHOD_DECLARATION);
}
}
- else if (parent instanceof PsiField) {
- final boolean isStatic = ((PsiField)parent).hasModifierProperty(PsiModifier.STATIC);
+ else if (parent instanceof PsiField || parent instanceof GrVariable && ResolveUtil.isScriptField((GrVariable)parent)) {
+ final boolean isStatic = ((PsiVariable)parent).hasModifierProperty(PsiModifier.STATIC);
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setTextAttributes(isStatic ? DefaultHighlighter.STATIC_FIELD : DefaultHighlighter.INSTANCE_FIELD);
}
@@ -185,8 +186,8 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
private static void highlightResolved(AnnotationHolder holder, GrReferenceElement refElement, PsiElement resolved) {
final PsiElement refNameElement = getElementToHighlight(refElement);
- if (resolved instanceof PsiField) {
- boolean isStatic = ((PsiField)resolved).hasModifierProperty(PsiModifier.STATIC);
+ if (resolved instanceof PsiField || resolved instanceof GrVariable && ResolveUtil.isScriptField((GrVariable)resolved)) {
+ boolean isStatic = ((PsiVariable)resolved).hasModifierProperty(PsiModifier.STATIC);
Annotation annotation = holder.createInfoAnnotation(refNameElement, null);
annotation.setTextAttributes(isStatic ? DefaultHighlighter.STATIC_FIELD : DefaultHighlighter.INSTANCE_FIELD);
}
@@ -1981,21 +1982,29 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
else {
if (shouldBeInterface(refElement)) {
- annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassActionBase.Type.INTERFACE));
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.INTERFACE));
}
else if (shouldBeClass(refElement)) {
- annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassActionBase.Type.CLASS));
- annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassActionBase.Type.ENUM));
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.CLASS));
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.ENUM));
+ }
+ else if (shouldBeAnnotation(refElement)) {
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.ANNOTATION));
}
else {
- annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassActionBase.Type.CLASS));
- annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassActionBase.Type.INTERFACE));
- annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassActionBase.Type.ENUM));
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.CLASS));
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.INTERFACE));
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.ENUM));
+ annotation.registerFix(CreateClassFix.createClassFixAction(refElement, CreateClassKind.ANNOTATION));
}
}
}
}
+ private static boolean shouldBeAnnotation(GrReferenceElement element) {
+ return element.getParent() instanceof GrAnnotation;
+ }
+
private static boolean shouldBeInterface(GrReferenceElement myRefElement) {
PsiElement parent = myRefElement.getParent();
return parent instanceof GrImplementsClause || parent instanceof GrExtendsClause && parent.getParent() instanceof GrInterfaceDefinition;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java
index 600c86638322..9ee5fbf48d10 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/KeywordHighlighter.java
@@ -81,14 +81,13 @@ public class KeywordHighlighter extends TextEditorHighlightingPass {
return; //don't highlight foo.def
}
- result.add(HighlightInfo.createHighlightInfo(HighlightInfoType.INFORMATION, element, null, DefaultHighlighter.KEYWORD_ATTRIBUTES));
+ result.add(HighlightInfo.createHighlightInfo(HighlightInfoType.INFORMATION, element, null, DefaultHighlighter.KEYWORD));
}
@Override
public void doApplyInformationToEditor() {
if (toHighlight == null) return;
- UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, 0, myFile.getTextLength(), toHighlight, getColorsScheme(),
- getId());
+ UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument, 0, myFile.getTextLength(), toHighlight, getColorsScheme(), getId());
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassActionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassActionBase.java
index 07822de94efb..0c341df41ece 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassActionBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassActionBase.java
@@ -16,7 +16,9 @@
package org.jetbrains.plugins.groovy.annotator.intentions;
+ import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind;
import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.impl.CreateClassDialog;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
@@ -24,7 +26,9 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -40,12 +44,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
* @author ilyas
*/
public abstract class CreateClassActionBase implements IntentionAction {
- private Type myType;
+ private CreateClassKind myType;
protected final GrReferenceElement myRefElement;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.annotator.intentions.CreateClassActionBase");
- public CreateClassActionBase(Type type, GrReferenceElement refElement) {
+ public CreateClassActionBase(CreateClassKind type, GrReferenceElement refElement) {
myType = type;
myRefElement = refElement;
}
@@ -60,6 +64,8 @@ public abstract class CreateClassActionBase implements IntentionAction {
return GroovyBundle.message("create.class.text", referenceName);
case INTERFACE:
return GroovyBundle.message("create.interface.text", referenceName);
+ case ANNOTATION:
+ return GroovyBundle.message("create.annotation.text", referenceName);
default:
return "";
}
@@ -75,11 +81,11 @@ public abstract class CreateClassActionBase implements IntentionAction {
}
public boolean startInWriteAction() {
- return true;
+ return false;
}
- protected Type getType() {
+ protected CreateClassKind getType() {
return myType;
}
@@ -145,7 +151,17 @@ public abstract class CreateClassActionBase implements IntentionAction {
}
}
- public static enum Type {
- ENUM, CLASS, INTERFACE
+ @Nullable
+ protected PsiDirectory getTargetDirectory(Project project, String qualifier, String name, Module module, String title) {
+ CreateClassDialog dialog = new CreateClassDialog(project, title, name, qualifier, getType(), false, module) {
+ @Override
+ protected boolean reportBaseInSourceSelectionInTest() {
+ return true;
+ }
+ };
+ dialog.show();
+ if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) return null;
+
+ return dialog.getTargetDirectory();
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java
index c7a44098fe4b..e8ee8f9e0a2e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateClassFix.java
@@ -16,12 +16,15 @@
package org.jetbrains.plugins.groovy.annotator.intentions;
+import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind;
import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
@@ -34,7 +37,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
@@ -49,58 +51,91 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
public abstract class CreateClassFix {
public static IntentionAction createClassFromNewAction(final GrNewExpression expression) {
- return new CreateClassActionBase(CreateClassActionBase.Type.CLASS, expression.getReferenceElement()) {
+ return new CreateClassActionBase(CreateClassKind.CLASS, expression.getReferenceElement()) {
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!(file instanceof GroovyFileBase)) return;
- GroovyFileBase groovyFile = (GroovyFileBase) file;
- final String qualifier = groovyFile instanceof GroovyFile ? groovyFile.getPackageName() : "";
+ GroovyFileBase groovyFile = (GroovyFileBase)file;
final PsiManager manager = myRefElement.getManager();
- final String name = myRefElement.getReferenceName();
- assert name != null;
- final Module module = ModuleUtil.findModuleForPsiElement(file);
+
+ final String qualifier;
+ final String name;
+ final Module module;
+ final AccessToken accessToken = ReadAction.start();
+ try {
+ qualifier = groovyFile instanceof GroovyFile ? groovyFile.getPackageName() : "";
+ name = myRefElement.getReferenceName();
+ assert name != null;
+ module = ModuleUtil.findModuleForPsiElement(file);
+ }
+ finally {
+ accessToken.finish();
+ }
+
PsiDirectory targetDirectory = getTargetDirectory(project, qualifier, name, module, getText());
if (targetDirectory == null) return;
GrTypeDefinition targetClass = createClassByType(targetDirectory, name, manager, myRefElement, NewGroovyClassAction.GROOVY_CLASS);
+ if (targetClass == null) return;
- GrArgumentList argList = expression.getArgumentList();
- if (argList != null && argList.getNamedArguments().length + argList.getExpressionArguments().length > 0 && targetClass != null) {
-
- PsiType[] argTypes = PsiUtil.getArgumentTypes(myRefElement, false);
- assert argTypes != null;
-
- ChooseTypeExpression[] paramTypesExpressions = new ChooseTypeExpression[argTypes.length];
- String[] paramTypes = new String[argTypes.length];
- String[] paramNames = new String[argTypes.length];
-
- for (int i = 0; i < argTypes.length; i++) {
- PsiType argType = argTypes[i];
- if (argType == null) argType = TypesUtil.getJavaLangObject(myRefElement);
- paramTypes[i] = "Object";
- paramNames[i] = "o" + i;
- paramTypesExpressions[i] = new ChooseTypeExpression(new TypeConstraint[]{SupertypeConstraint.create(argType)}, myRefElement.getManager());
- }
-
- GrMethod method = GroovyPsiElementFactory.getInstance(project).createConstructorFromText(name, paramTypes, paramNames, "{\n}");
- method = targetClass.addMemberDeclaration(method, null);
- final PsiNameIdentifierOwner context = PsiTreeUtil.getParentOfType(myRefElement, PsiMethod.class, PsiClass.class);
- IntentionUtils.createTemplateForMethod(argTypes, paramTypesExpressions, method, targetClass, new TypeConstraint[0], true, context);
- } else {
+ PsiType[] argTypes = getArgTypes(myRefElement);
+ if (argTypes != null) {
+ generateConstructor(myRefElement, name, argTypes, targetClass, project);
+ }
+ else {
putCursor(project, targetClass.getContainingFile(), targetClass);
}
addImportForClass(groovyFile, qualifier, targetClass);
}
-
};
}
- public static IntentionAction createClassFixAction(final GrReferenceElement refElement, CreateClassActionBase.Type type) {
- return new CreateClassActionBase(type, refElement) {
+ @Nullable
+ private static PsiType[] getArgTypes(GrReferenceElement refElement) {
+ final AccessToken accessToken = ReadAction.start();
+ try {
+ return PsiUtil.getArgumentTypes(refElement, false);
+ }
+ finally {
+ accessToken.finish();
+ }
+ }
+ private static void generateConstructor(@NotNull PsiElement refElement,
+ @NotNull String name,
+ @NotNull PsiType[] argTypes,
+ @NotNull GrTypeDefinition targetClass,
+ @NotNull Project project) {
+ final AccessToken writeLock = WriteAction.start();
+ try {
+ ChooseTypeExpression[] paramTypesExpressions = new ChooseTypeExpression[argTypes.length];
+ String[] paramTypes = new String[argTypes.length];
+ String[] paramNames = new String[argTypes.length];
+
+ for (int i = 0; i < argTypes.length; i++) {
+ PsiType argType = argTypes[i];
+ if (argType == null) argType = TypesUtil.getJavaLangObject(refElement);
+ paramTypes[i] = "Object";
+ paramNames[i] = "o" + i;
+ paramTypesExpressions[i] = new ChooseTypeExpression(new TypeConstraint[]{SupertypeConstraint.create(argType)}, refElement.getManager());
+ }
+
+ GrMethod method = GroovyPsiElementFactory.getInstance(project).createConstructorFromText(name, paramTypes, paramNames, "{\n}");
+
+ method = targetClass.addMemberDeclaration(method, null);
+ final PsiNameIdentifierOwner context = PsiTreeUtil.getParentOfType(refElement, PsiMethod.class, PsiClass.class);
+ IntentionUtils.createTemplateForMethod(argTypes, paramTypesExpressions, method, targetClass, new TypeConstraint[0], true, context);
+ }
+ finally {
+ writeLock.finish();
+ }
+ }
+
+ public static IntentionAction createClassFixAction(final GrReferenceElement refElement, CreateClassKind type) {
+ return new CreateClassActionBase(type, refElement) {
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!(file instanceof GroovyFileBase)) return;
- GroovyFileBase groovyFile = (GroovyFileBase) file;
+ GroovyFileBase groovyFile = (GroovyFileBase)file;
final String qualifier = groovyFile instanceof GroovyFile ? groovyFile.getPackageName() : "";
final PsiManager manager = PsiManager.getInstance(project);
final String name = myRefElement.getReferenceName();
@@ -109,18 +144,7 @@ public abstract class CreateClassFix {
if (targetDirectory == null) return;
- String templateName = null;
- switch (getType()) {
- case ENUM:
- templateName = NewGroovyClassAction.GROOVY_ENUM;
- break;
- case CLASS:
- templateName = NewGroovyClassAction.GROOVY_CLASS;
- break;
- case INTERFACE:
- templateName = NewGroovyClassAction.GROOVY_INTERFACE;
- break;
- }
+ String templateName = getTemplateName(getType());
assert name != null;
PsiClass targetClass = createClassByType(targetDirectory, name, manager, myRefElement, templateName);
if (targetClass != null) {
@@ -128,29 +152,39 @@ public abstract class CreateClassFix {
putCursor(project, targetClass.getContainingFile(), targetClass);
}
}
-
};
}
- @Nullable
- private static PsiDirectory getTargetDirectory(Project project, String qualifier, String name, Module module, String title) {
- GroovyCreateClassDialog dialog = new GroovyCreateClassDialog(project, title, name, qualifier, module);
- dialog.show();
- if (dialog.getExitCode() != DialogWrapper.OK_EXIT_CODE) return null;
- return dialog.getTargetDirectory();
+ private static String getTemplateName(CreateClassKind createClassKind) {
+ switch (createClassKind) {
+ case ENUM:
+ return NewGroovyClassAction.GROOVY_ENUM;
+ case CLASS:
+ return NewGroovyClassAction.GROOVY_CLASS;
+ case INTERFACE:
+ return NewGroovyClassAction.GROOVY_INTERFACE;
+ case ANNOTATION:
+ return NewGroovyClassAction.GROOVY_ANNOTATION;
+ default:
+ return null;
+ }
}
- protected static void addImportForClass(GroovyFileBase groovyFile, String qualifier, PsiClass targetClass) throws IncorrectOperationException {
- if (targetClass != null) {
- // add import for created class
- String qualifiedName = targetClass.getQualifiedName();
- if (qualifiedName != null && qualifiedName.contains(".")) {
- String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
- if (!packageName.equals(qualifier)) {
+ protected static void addImportForClass(@NotNull GroovyFileBase groovyFile, @NotNull String qualifier, @NotNull PsiClass targetClass)
+ throws IncorrectOperationException {
+ // add import for created class
+ String qualifiedName = targetClass.getQualifiedName();
+ if (qualifiedName != null && qualifiedName.contains(".")) {
+ String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
+ if (!packageName.equals(qualifier)) {
+ final AccessToken accessToken = WriteAction.start();
+ try {
groovyFile.addImportForClass(targetClass);
}
+ finally {
+ accessToken.finish();
+ }
}
}
}
-
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/UnnecessaryQualifiedReferenceInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/UnnecessaryQualifiedReferenceInspection.java
index 0fd40f40a421..39629d585163 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/UnnecessaryQualifiedReferenceInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/UnnecessaryQualifiedReferenceInspection.java
@@ -119,8 +119,8 @@ public class UnnecessaryQualifiedReferenceInspection extends BaseInspection {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement startElement = descriptor.getStartElement();
- LOG.assertTrue(startElement instanceof GrReferenceElement);
- GrReferenceAdjuster.shortenReference((GrQualifiedReference)startElement);
+ LOG.assertTrue(startElement instanceof GrReferenceElement>);
+ GrReferenceAdjuster.shortenReference((GrQualifiedReference>)startElement);
}
@NotNull
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
index 41a0e471bd6c..6bcd52cb3ec8 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
@@ -81,6 +81,8 @@ convert.closure.to.method.intention.name=Convert to method
convert.closure.to.method.intention.family.name=Convert property to method
convert.method.to.closure.intention.name=Convert to property
convert.method.to.closure.intention.family.name=Convert method to property of closure type
+convert.string.to.multiline.intention.name=Convert to Multiline
+convert.string.to.multiline.intention.family.name=Convert literal to multiline literal
convert.junit.assertion.to.assert.statement.intention.name=Convert JUnit assertion to assert statement
convert.junit.assertion.to.assert.statement.intention.family.name=Convert JUnit assertion to assert statement
###########################################################################################################
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertStringToMultilineIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertStringToMultilineIntention.java
new file mode 100644
index 000000000000..62b5b8d43e03
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/ConvertStringToMultilineIntention.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.intentions.conversions;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.intentions.base.Intention;
+import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
+import org.jetbrains.plugins.groovy.lang.editor.actions.GroovyEditorActionUtil;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl;
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrStringImpl;
+import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
+
+/**
+ * @author Max Medvedev
+ */
+public class ConvertStringToMultilineIntention extends Intention {
+ private static final Logger LOG = Logger.getInstance(ConvertStringToMultilineIntention.class);
+
+ public static final String hint = "Convert to Multiline";
+
+ @Override
+ protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
+ String quote = element.getText().startsWith("'") ? "'''" : "\"\"\"";
+
+ StringBuilder buffer = new StringBuilder();
+ buffer.append(quote);
+
+ GrExpression old;
+
+ if (element instanceof GrLiteralImpl) {
+ appendSimpleStringValue(element, buffer, quote);
+ old = (GrExpression)element;
+ }
+ else {
+ final GrStringImpl gstring = PsiTreeUtil.getParentOfType(element, GrStringImpl.class);
+ for (ASTNode child = gstring.getNode().getFirstChildNode(); child != null; child = child.getTreeNext()) {
+ if (child.getElementType() == GroovyTokenTypes.mGSTRING_CONTENT) {
+ appendGStringContent(child, buffer);
+ }
+ else if (child.getElementType() == GroovyElementTypes.GSTRING_INJECTION) {
+ buffer.append(child.getText());
+ }
+ }
+ old = gstring;
+ }
+
+ buffer.append(quote);
+ try {
+ final GrExpression newLiteral = GroovyPsiElementFactory.getInstance(project).createExpressionFromText(buffer.toString());
+ old.replaceWithExpression(newLiteral, true);
+ }
+ catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
+ }
+
+ private static void appendGStringContent(ASTNode child, StringBuilder buffer) {
+ final String text = child.getText();
+ final StringBuilder parsed = new StringBuilder();
+ if (GrStringUtil.parseStringCharacters(text, parsed, null)) {
+ buffer.append(parsed);
+ }
+ else {
+ buffer.append(text);
+ }
+ }
+
+ private static void appendSimpleStringValue(PsiElement element, StringBuilder buffer, String quote) {
+ final Object value = ((GrLiteralImpl)element).getValue();
+ if (value instanceof String) {
+ if ("'''".equals(quote)) {
+ GrStringUtil.escapeStringCharacters(((String)value).length(), (String)value, "", false, true, buffer);
+ }
+ else {
+ GrStringUtil.escapeSymbolsForGString((CharSequence)value, false, false, buffer);
+ }
+ }
+ else {
+ buffer.append(GrStringUtil.removeQuotes(element.getText()));
+ }
+ }
+
+ @NotNull
+ @Override
+ protected PsiElementPredicate getElementPredicate() {
+ return new PsiElementPredicate() {
+ @Override
+ public boolean satisfiedBy(PsiElement element) {
+ if (element instanceof GrLiteralImpl) {
+ final ASTNode node = element.getFirstChild().getNode();
+ final IElementType type = node.getElementType();
+ if (type == GroovyTokenTypes.mSTRING_LITERAL) {
+ return GroovyEditorActionUtil.isPlainStringLiteral(node);
+ }
+ if (type == GroovyTokenTypes.mGSTRING_LITERAL) {
+ return GroovyEditorActionUtil.isPlainGString(node);
+ }
+ }
+ else {
+ final GrStringImpl gstring = PsiTreeUtil.getParentOfType(element, GrStringImpl.class, false, GrMember.class, GroovyFile.class);
+ if (gstring == null) return false;
+ return gstring.isPlainString();
+ }
+ return false;
+ }
+ };
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportOnDemandIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportOnDemandIntention.java
index 320b1b6d0918..d52f269a2fee 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportOnDemandIntention.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportOnDemandIntention.java
@@ -15,7 +15,6 @@
*/
package org.jetbrains.plugins.groovy.intentions.style;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
@@ -39,8 +38,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatem
* @author Maxim.Medvedev
*/
public class ImportOnDemandIntention extends Intention {
- private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.intentions.style.ImportOnDemandIntention");
-
@Override
protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
@@ -62,8 +59,8 @@ public class ImportOnDemandIntention extends Intention {
final PsiElement refElement = reference.getElement();
if (refElement == null) continue;
final PsiElement parent = refElement.getParent();
- if (parent instanceof GrQualifiedReference) {
- GrReferenceAdjuster.shortenReference((GrQualifiedReference)parent);
+ if (parent instanceof GrQualifiedReference>) {
+ GrReferenceAdjuster.shortenReference((GrQualifiedReference>)parent);
}
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportStaticIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportStaticIntention.java
index 36ceb3948420..733fcd1c1758 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportStaticIntention.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ImportStaticIntention.java
@@ -15,7 +15,6 @@
*/
package org.jetbrains.plugins.groovy.intentions.style;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
@@ -31,31 +30,39 @@ import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
/**
* @author Maxim.Medvedev
*/
public class ImportStaticIntention extends Intention {
- private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.intentions.style.ImportStaticIntention");
private static final Key TEMP_REFERENT_USER_DATA = new Key("TEMP_REFERENT_USER_DATA");
@Override
- protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
+ protected void processIntention(@NotNull PsiElement element, final Project project, final Editor editor)
+ throws IncorrectOperationException {
+ final PsiElement resolved;
+ final String name;
+ final GroovyFile file;
+ final GrImportStatement importStatement;
+ boolean isAnythingShortened;
if (!(element instanceof GrReferenceExpression)) return;
final GrReferenceExpression ref = (GrReferenceExpression)element;
- final PsiElement resolved = ref.resolve();
+ resolved = ref.resolve();
if (!(resolved instanceof PsiMember)) return;
final PsiClass containingClass = ((PsiMember)resolved).getContainingClass();
if (containingClass == null) return;
final String qname = containingClass.getQualifiedName();
- final String name = ((PsiMember)resolved).getName();
+ name = ((PsiMember)resolved).getName();
+ if (name == null) return;
final PsiFile containingFile = element.getContainingFile();
if (!(containingFile instanceof GroovyFile)) return;
- final GroovyFile file = (GroovyFile)containingFile;
+ file = (GroovyFile)containingFile;
file.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitReferenceExpression(GrReferenceExpression expression) {
@@ -69,27 +76,30 @@ public class ImportStaticIntention extends Intention {
}
});
- final GrImportStatement importStatement =
- GroovyPsiElementFactory.getInstance(project).createImportStatementFromText(qname + "." + name, true, false, null);
-
-
- file.addImport(importStatement);
+ final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
+ final GrImportStatement tempImport = factory.createImportStatementFromText(qname + "." + name, true, false, null);
+ importStatement = file.addImport(tempImport);
+ isAnythingShortened = false;
for (PsiReference reference : ReferencesSearch.search(resolved, new LocalSearchScope(containingFile))) {
final PsiElement refElement = reference.getElement();
- if (refElement instanceof GrQualifiedReference) {
- GrReferenceAdjuster.shortenReference((GrQualifiedReference)refElement);
+ if (refElement instanceof GrQualifiedReference>) {
+ isAnythingShortened |= GrReferenceAdjuster.shortenReference((GrQualifiedReference>)refElement);
}
}
+ if (!isAnythingShortened) {
+ importStatement.delete();
+ return;
+ }
file.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitReferenceExpression(GrReferenceExpression expression) {
super.visitReferenceExpression(expression);
- if (expression.getTypeArgumentList() != null &&
- expression.getTypeArgumentList().getFirstChild() != null) {
+ GrTypeArgumentList typeArgumentList = expression.getTypeArgumentList();
+ if (typeArgumentList != null && typeArgumentList.getFirstChild() != null) {
expression.putUserData(TEMP_REFERENT_USER_DATA, null);
return;
@@ -97,8 +107,9 @@ public class ImportStaticIntention extends Intention {
if (name.equals(expression.getReferenceName())) {
if (expression.isQualified()) {
- if (expression.getQualifierExpression() instanceof GrReferenceExpression) {
- PsiElement aClass = ((GrReferenceExpression)expression.getQualifierExpression()).resolve();
+ GrExpression qualifier = expression.getQualifierExpression();
+ if (qualifier instanceof GrReferenceExpression) {
+ PsiElement aClass = ((GrReferenceExpression)qualifier).resolve();
if (aClass == ((PsiMember)resolved).getContainingClass()) {
GrReferenceAdjuster.shortenReference(expression);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java
index 495a74b09476..c47b09bc1261 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java
@@ -41,38 +41,40 @@ public class GrReferenceAdjuster {
}
- public static void shortenReferences(PsiElement element) {
+ public static boolean shortenReferences(PsiElement element) {
final TextRange range = element.getTextRange();
- shortenReferences(element, range.getStartOffset(), range.getEndOffset(), true, false);
+ return shortenReferences(element, range.getStartOffset(), range.getEndOffset(), true, false);
}
- public static void shortenReferences(PsiElement element, int start, int end, boolean addImports, boolean incomplete) {
- process(element, start, end, addImports, incomplete);
+ public static boolean shortenReferences(PsiElement element, int start, int end, boolean addImports, boolean incomplete) {
+ return process(element, start, end, addImports, incomplete);
}
- public static void shortenReference(GrQualifiedReference ref) {
- shortenReferenceInner(ref, true, false);
+ public static boolean shortenReference(GrQualifiedReference ref) {
+ boolean result = shortenReferenceInner(ref, true, false);
final TextRange range = ref.getTextRange();
- process(ref, range.getStartOffset(), range.getEndOffset(), true, false);
+ result |= process(ref, range.getStartOffset(), range.getEndOffset(), true, false);
+ return result;
}
- private static void process(PsiElement element, int start, int end, boolean addImports, boolean incomplete) {
- if (element instanceof GrQualifiedReference && ((GrQualifiedReference)element).resolve() instanceof PsiClass) {
- shortenReferenceInner((GrQualifiedReference)element, addImports, incomplete);
+ private static boolean process(PsiElement element, int start, int end, boolean addImports, boolean incomplete) {
+ boolean result = false;
+ if (element instanceof GrQualifiedReference> && ((GrQualifiedReference)element).resolve() instanceof PsiClass) {
+ result = shortenReferenceInner((GrQualifiedReference>)element, addImports, incomplete);
}
-
else if (element instanceof GrReferenceExpression && ((GrReferenceExpression)element).getQualifier() instanceof GrThisSuperReferenceExpression) {
- shortenReferenceInner((GrReferenceExpression)element, addImports, incomplete);
+ result = shortenReferenceInner((GrReferenceExpression)element, addImports, incomplete);
}
PsiElement child = element.getFirstChild();
while (child != null) {
final TextRange range = child.getTextRange();
if (start < range.getEndOffset() && range.getStartOffset() < end) {
- process(child, start, end, addImports, incomplete);
+ result |= process(child, start, end, addImports, incomplete);
}
child = child.getNextSibling();
}
+ return result;
}
private static boolean shortenReferenceInner(GrQualifiedReference ref, boolean addImports, boolean incomplete) {
@@ -141,6 +143,7 @@ public class GrReferenceAdjuster {
}
+ @SuppressWarnings("unchecked")
private static GrQualifiedReference