summaryrefslogtreecommitdiff
path: root/java/java-impl/src
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2014-01-06 10:22:20 -0800
committerTor Norbye <tnorbye@google.com>2014-01-06 10:22:24 -0800
commitf2f7178ad6915927d918481b911e57a49785e4c4 (patch)
treec2b0f8906d38f5f1e2f5da853c67e09205816bf6 /java/java-impl/src
parent8668e1be0891658129cbc8f0965380f702c26755 (diff)
downloadidea-f2f7178ad6915927d918481b911e57a49785e4c4.tar.gz
Snapshot c11f3ac9bbde3f85d1f837ec3eb48a395ed7dd10 from idea/133.471 of git://git.jetbrains.org/idea/community.git
c11f3ac: faster xml properties indexing: don't process if no required namespace string present (cherry picked from commit 0845f9e) [r=Dmitry.Avdeev] 0be6c40: to get version sort copy of ClsStubBuilderFactory implementation array (cherry picked from commit c34b260) [r=Alexander.Podkhalusin] 8ed9df6: IDEA-116087 Warning when using new wrapper.gradleVersion construction (cherry picked from commit d3a81f0) d33b33a: Gradle: fix check for gradle-related files (cherry picked from commit 140b618) e8c50fa: Gradle: fix creation/sync of gradle wrapper files on project import 3fcf435: IDEA-99036 Changing breakpoint suspend policy from popup does not actually change the policy 033cdba: IDEA-116636 Android-Gradle facet is created when Gradle synchronization. related bug IDEA-116887 Gradle web artifacts do not contain compiled classes and JSP files (cherry picked from commit 64e7f51) 1f4d754: EA-52867 (null check) 3e2b5c5: proper processing of dom indices, 2 (cherry picked from commit e9d6759) 7061e85: proper processing of dom indices (cherry picked from commit e5401d6) e04883d: proper implementation and usage of indices for DOMStubs 5fa6cf9: do not load/try to index inner classes content / delegate to ClsStubBuilder for inner class identification (cherry picked from commit a085c19) [r=Alexander.Podkhalusin] 3a8fd3f: - use all BinaryStubBuilders versions in stable order to calculate stub version - introduce version for ClassStubBuilderFactory and use all class stub builder factories in stable order to calculate version of ClassFileStubBuilder [r=Eugene.Zhuravlev, Alexander.Podkhalusin] 57e7213: IDEA-118436 Resource Bundle Editor converts UTF8 characters to ASCII even in UTF8 file 1dc12b4: IDEA-112730 PhpStorm goes crazy with collapsed comments and soft wraps until crash eee52a9: IDEA-112730 PhpStorm goes crazy with collapsed comments and soft wraps until crash c187921: IDEA-112730 PhpStorm goes crazy with collapsed comments and soft wraps until crash 2119489: ActionTestCase extracted from CoffeeScript and Puppet (cherry picked from commit be905df) 12e8b76: Overriding language in VariableInplaceRenamer. (CoffeeScript) (cherry picked from commit b459118) c9069d1: IDEA-118587 IDEA may not exit with black window (cherry picked from commit a622b21) 6733c9e: WEB-9566 Debugger: optionally ignore certificate errors (cherry picked from commit af49f19) da588bc: move CertificatesManager to platform (cherry picked from commit 6dc50e6) f11ceb2: WEB-8262 Comment with line/block comment STILL doesn't work on HTML in ASP file (cherry picked from commit a83731c) [r=Rustam.Vyshnyakov] 8cfe207: WEB-849 "Comment with line comment" on empty line in <script> block generates HTML instead of JS comment (cherry picked from commit 73a14ec) [r=Rustam.Vyshnyakov] 36cf71c: WEB-6700 TODOs not recognized on multiple level language template (cherry picked from commit 9d00810) [r=Alexey.Gopachenko] 146d0c3: IDEA-118701 Multimodule project imported into IDEA via opening project file gets incorrect project name (cherry picked from commit 0912313) 25e5150: Bug fix: check not-null (cherry picked from commit 6b54183) 80932f6: IDEA-118601 New Module: Maven: click on "Create from archetype" reverts typed coordinates (cherry picked from commit d94c9a1) a419509: IDEA-116593 improve choosing of Android and Java SDKs when creating new android-gradle project/module: choose only Android SDK location (if we don't know it) on first step, not build target; choose Java SDK (if there is no any) separately, set it as project sdk and as internal jdk for newly created android sdk entities (cherry picked from commit 2bf19b4) e889183: Fixed IDEA-116006 Eclipse code style import: import the same xml does not pick up changes until manual synchronization (cherry picked from commit f6e9d9d) fd2b92e: licenses missing licenses for libraries used by android b5b25e5: Fixed IDEA-117788 Eclipse code style import: continuation indent is imported not multiplied to tab size (cherry picked from commit a9768ee) 074876e: remove all indexed state upon invalidateIndicesForFile (r=Eugene.Zhuravlev) caa4032: EA-35422 - IOOBE: EditorImpl.offsetToLogicalLine (from debugger) (cherry picked from commit c21cd02) [r=Peter.Gromov] b47b369: attach messages to root node if no running node found (cherry picked from commit 5c66005) 02cf0b4: [log] Flush & Close persistent enumerator on dispose() f84ff13: better way to instantiate PersistentHashMap 36d590f: [git] Wrap the VcsException not to loose the cause 339dede: [log] IDEA-115407 Disable graph-only-actions if there is no graph 3773e2c: [log] IDEA-115568 Don't crash if the log is empty cafe1a8: [log] IDEA-115901 Keep selection between refreshes and filtering 8169bbe: [log] rename type parameter to a more descriptive name 0548151: [log] remove pointless code 29f0909: [log] Don't use setFont(), instead supply value in getFont() 82f67f7: [log] IDEA-117816 small optimization in graph cell drawing 1acba78: IDEA-102942 Wrap always Chained methods calls over-format simple operations (cherry picked from commit 835ed38) 8ef13e9: IDEA-118613: catch all possible exceptions, that may be caused by corrupted storages 0654f14: IDEA-96131 Java: Braces placements don't work as expected for `Next Line` [CR-IC-3694] (cherry picked from commit 975cfe8) ee689af: WEB-10387 Mocha console log statements are not correctly aligned to their encasing tests (cherry picked from commit 6018640) b6b35e2: WEB-9517 Npm: Error loading package list (cherry picked from commit aa82d2a) 07d7344: test fix: explicit encoding is required 257ac80: cleanup 9b46832: IDEA-93034 SQL: MySQL: erasing the first backtick could erase the pair 6da1645: in case when some output and source roots intersect: do not stop rebuild if caches version is advanced (IDEA-118613) 631aea6: separate checks if compiler is enabled and compiler api is supported by compiler implementation 4ecc2a5: external build: added method to register output directory in source-to-output mapping instead of registering individual files to reduce occupied disk space (ZD-16651) [rev by Jeka] f344db7: don't copy ui-designer runtime classes to output if only NetBeans *.form files are found (ZD-14954) [rev by Jeka] 88de860: standalone JPS build: propagate 'forceBuild' option to dependencies implicitly included into compile scope [rev by Jeka] cbec9d7: [^Peter] EA-50899 - ISE: GrRegexImpl.createLiteralTextEscaper 3013e02: [^Peter] IDEA-117828 Groovy console: execute groovy code shortcut changed back 6ad8dbf: [^Peter] IDEA-117292 Groovy: checks for @Immutable class 8d2c8cf: EA-52292 fix (PHP template inside HTML comment case) (cherry picked from commit 41ccbd2) 1fc4a80: IDEA-118595 0f7f3a1: cleanup imports 09b3d12: style efdd1aa: OutputSuppressed option added for HgCommandExecutor, style changed, unnecessary parameters removed (cherry picked from commit 4d55fdd) 12789c5: cosmetics: revision hash template changed to long. (cherry picked from commit f1c78e1) 57c3348: Parents revision hash template changed to long. (cherry picked from commit 32ab1db) b70b45e: IDEA-118266 time measurements for all Mercurial commands added and log command debug output suppressed. (cherry picked from commit 75ec80e) f44f8d8: [^maxmedvedev] gdsl: be prepared to multithreaded scripts (cherry picked from commit a240a44) 6121316: + "trie" (cherry picked from commit 669ae41) 3c8884d: IDEA-118552 Generated ANT scripts do not honour cross-compile settings Change-Id: I18c031b09527bf8c7de6a529b546e66950a816d3
Diffstat (limited to 'java/java-impl/src')
-rw-r--r--java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java175
-rw-r--r--java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java35
2 files changed, 128 insertions, 82 deletions
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
index d392d7a7a481..d98165f3e7a8 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java
@@ -712,67 +712,8 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
@NotNull
private Block createMethodCallExpressionBlock(@NotNull final ASTNode node, final Wrap blockWrap, final Alignment alignment) {
final ArrayList<ASTNode> nodes = new ArrayList<ASTNode>();
- final ArrayList<Block> subBlocks = new ArrayList<Block>();
collectNodes(nodes, node);
-
- final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.METHOD_CALL_CHAIN_WRAP), false);
-
- // We use this alignment object to align chained method calls to the first method invocation place if necessary (see IDEA-30369)
- Alignment chainedCallsAlignment = createAlignment(mySettings.ALIGN_MULTILINE_CHAINED_METHODS, null);
-
- // We want to align chained method calls only if method target is explicitly specified, i.e. we don't want to align methods
- // chain like 'recursive().recursive().recursive()' but want to align calls like 'foo.recursive().recursive().recursive()'
- boolean callPointDefined = false;
- List<ASTNode> lookAheadNodes = null;
- boolean afterIdentifier = false;
-
- while (!nodes.isEmpty() || lookAheadNodes != null) {
- final List<ASTNode> subNodes;
- if (lookAheadNodes == null) {
- subNodes = readToNextDot(nodes);
- }
- else {
- subNodes = new ArrayList<ASTNode>(lookAheadNodes);
- lookAheadNodes = null;
- }
- Alignment alignmentToUseForSubBlock = null;
-
- // Just create a no-aligned sub-block if we don't need to bother with it's alignment (either due to end-user
- // setup or sub-block state).
- if (chainedCallsAlignment == null || subNodes.isEmpty()) {
- subBlocks.add(createSyntheticBlock(subNodes, wrap, alignmentToUseForSubBlock));
- continue;
- }
-
- IElementType lastNodeType = subNodes.get(subNodes.size() - 1).getElementType();
- boolean currentSubBlockIsMethodCall = lastNodeType == JavaElementType.EXPRESSION_LIST;
-
- // Update information about chained method alignment point if necessary. I.e. we want to align only continuous method calls
- // like 'foo.bar().bar().bar()' but not 'foo.bar().foo.bar()'
- if (callPointDefined && !currentSubBlockIsMethodCall) {
- chainedCallsAlignment = createAlignment(mySettings.ALIGN_MULTILINE_CHAINED_METHODS, null);
- }
- callPointDefined |= !currentSubBlockIsMethodCall;
-
- // We want to align method call only if call target is defined for the first chained method and current block is a method call.
- if (callPointDefined && currentSubBlockIsMethodCall) {
- alignmentToUseForSubBlock = chainedCallsAlignment;
- }
- else if (afterIdentifier && lastNodeType == JavaTokenType.IDENTIFIER) {
- // Align method call to the last field access. Example:
- // MyClass.staticField
- // .foo();
- lookAheadNodes = readToNextDot(nodes);
- if (!lookAheadNodes.isEmpty() && lookAheadNodes.get(lookAheadNodes.size() - 1).getElementType() == JavaElementType.EXPRESSION_LIST) {
- alignmentToUseForSubBlock = chainedCallsAlignment;
- }
- }
- afterIdentifier = lastNodeType == JavaTokenType.IDENTIFIER;
- subBlocks.add(createSyntheticBlock(subNodes, wrap, alignmentToUseForSubBlock));
- }
-
- return new SyntheticCodeBlock(subBlocks, alignment, mySettings,
- Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS), blockWrap);
+ return new ChainMethodCallsBlockBuilder(alignment, blockWrap).build(nodes);
}
@NotNull
@@ -802,19 +743,6 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
return result;
}
- @NotNull
- private static List<ASTNode> readToNextDot(@NotNull List<ASTNode> nodes) {
- final ArrayList<ASTNode> result = new ArrayList<ASTNode>();
- result.add(nodes.remove(0));
- for (Iterator<ASTNode> iterator = nodes.iterator(); iterator.hasNext();) {
- ASTNode node = iterator.next();
- if (node.getElementType() == JavaTokenType.DOT) break;
- result.add(node);
- iterator.remove();
- }
- return result;
- }
-
private static void collectNodes(@NotNull List<ASTNode> nodes, @NotNull ASTNode node) {
ASTNode child = node.getFirstChildNode();
while (child != null) {
@@ -1504,4 +1432,105 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
result.setChildAttributes(new ChildAttributes(getCodeBlockInternalIndent(childrenIndent), null));
return result;
}
+
+ private class ChainMethodCallsBlockBuilder {
+ private Wrap blockWrap;
+ private Alignment blockAlignment;
+
+ private Wrap myWrap;
+ private Alignment myChainedCallsAlignment;
+
+ public ChainMethodCallsBlockBuilder(Alignment alignment, Wrap wrap) {
+ blockWrap = wrap;
+ blockAlignment = alignment;
+ }
+
+ public Block build(List<ASTNode> nodes) {
+ myWrap = getNewWrap();
+ myChainedCallsAlignment = getNewAlignment();
+
+ List<Block> blocks = buildBlocksFrom(nodes);
+ Indent indent = Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS);
+
+ return new SyntheticCodeBlock(blocks, blockAlignment, mySettings, indent, blockWrap);
+ }
+
+ private List<Block> buildBlocksFrom(List<ASTNode> nodes) {
+ List<ChainedCallChunk> methodCall = splitMethodCallOnChunksByDots(nodes);
+ Wrap wrapToUse = null;
+ Alignment alignmentToUse = null;
+
+ List<Block> blocks = new ArrayList<Block>();
+
+ for (ChainedCallChunk currentCallChunk : methodCall) {
+ if (isMethodCall(currentCallChunk)) {
+ wrapToUse = myWrap;
+ alignmentToUse = shouldAlignMethod(currentCallChunk, methodCall) ? myChainedCallsAlignment : null;
+ }
+ else if (wrapToUse != null) {
+ wrapToUse = null;
+ alignmentToUse = null;
+
+ myChainedCallsAlignment = getNewAlignment();
+ myWrap = getNewWrap();
+ }
+
+ blocks.add(createSyntheticBlock(currentCallChunk.nodes, wrapToUse, alignmentToUse));
+ }
+
+ return blocks;
+ }
+
+ private boolean shouldAlignMethod(ChainedCallChunk currentMethodChunk, List<ChainedCallChunk> methodCall) {
+ return mySettings.ALIGN_MULTILINE_CHAINED_METHODS
+ && !currentMethodChunk.isEmpty()
+ && !chunkIsFirstInChainMethodCall(currentMethodChunk, methodCall);
+ }
+
+ private boolean chunkIsFirstInChainMethodCall(@NotNull ChainedCallChunk callChunk, @NotNull List<ChainedCallChunk> methodCall) {
+ return !methodCall.isEmpty() && callChunk == methodCall.get(0);
+ }
+
+ @NotNull
+ private List<ChainedCallChunk> splitMethodCallOnChunksByDots(@NotNull List<ASTNode> nodes) {
+ List<ChainedCallChunk> result = new ArrayList<ChainedCallChunk>();
+
+ List<ASTNode> current = new ArrayList<ASTNode>();
+ for (ASTNode node : nodes) {
+ if (node.getElementType() == JavaTokenType.DOT) {
+ result.add(new ChainedCallChunk(current));
+ current = new ArrayList<ASTNode>();
+ }
+ current.add(node);
+ }
+
+ result.add(new ChainedCallChunk(current));
+ return result;
+ }
+
+ private Alignment getNewAlignment() {
+ return createAlignment(mySettings.ALIGN_MULTILINE_CHAINED_METHODS, null);
+ }
+
+ private Wrap getNewWrap() {
+ return Wrap.createWrap(getWrapType(mySettings.METHOD_CALL_CHAIN_WRAP), false);
+ }
+
+ private boolean isMethodCall(@NotNull ChainedCallChunk callChunk) {
+ List<ASTNode> nodes = callChunk.nodes;
+ return !nodes.isEmpty() && nodes.get(nodes.size() - 1).getElementType() == JavaElementType.EXPRESSION_LIST;
+ }
+ }
+
+ private static class ChainedCallChunk {
+ @NotNull final List<ASTNode> nodes;
+
+ ChainedCallChunk(@NotNull List<ASTNode> nodes) {
+ this.nodes = nodes;
+ }
+
+ boolean isEmpty() {
+ return nodes.isEmpty();
+ }
+ }
}
diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
index 8f090b072d16..eed6d597e476 100644
--- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
+++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java
@@ -840,8 +840,14 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
else {
if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT || myChild2.getElementType() == JavaElementType.CODE_BLOCK) {
- myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_ELSE_LBRACE, mySettings.BRACE_STYLE, null,
- mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
+ PsiElement branch = statement.getElseBranch();
+ boolean shouldKeepInOneLine = mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE
+ && branch != null
+ && !branch.textContains('\n');
+
+ myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_ELSE_LBRACE,
+ mySettings.BRACE_STYLE,
+ null, shouldKeepInOneLine, true);
}
else {
createSpacingBeforeElementInsideControlStatement();
@@ -849,10 +855,19 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
}
else if (myChild2.getElementType() == JavaElementType.BLOCK_STATEMENT || myChild2.getElementType() == JavaElementType.CODE_BLOCK) {
- boolean space = myRole2 == ChildRole.ELSE_BRANCH ? mySettings.SPACE_BEFORE_ELSE_LBRACE : mySettings.SPACE_BEFORE_IF_LBRACE;
+ boolean space = myRole2 == ChildRole.ELSE_BRANCH ? mySettings.SPACE_BEFORE_ELSE_LBRACE
+ : mySettings.SPACE_BEFORE_IF_LBRACE;
+
+ PsiElement branch = myRole2 == ChildRole.ELSE_BRANCH ? statement.getElseBranch()
+ : statement.getThenBranch();
+
+ boolean shouldKeepInOneLine = mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE
+ && branch != null
+ && !branch.textContains('\n');
+
myResult = getSpaceBeforeLBrace(space, mySettings.BRACE_STYLE,
new TextRange(myParent.getTextRange().getStartOffset(), myChild1.getTextRange().getEndOffset()),
- mySettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE, true);
+ shouldKeepInOneLine, true);
}
else if (myRole2 == ChildRole.LPARENTH) {
createSpaceInCode(mySettings.SPACE_BEFORE_IF_PARENTHESES);
@@ -909,7 +924,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
else if (braceStyle == CommonCodeStyleSettings.END_OF_LINE || braceStyle == CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED) {
return createNonLFSpace(space, null, false);
}
- else if (braceStyle == CommonCodeStyleSettings.NEXT_LINE && !mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE) {
+ else if (braceStyle == CommonCodeStyleSettings.NEXT_LINE) {
space = (keepOneLine && spaceBeforeLbrace) ? 1 : 0;
return Spacing.createSpacing(space, 0, keepOneLine ? 0 : 1, false, mySettings.KEEP_BLANK_LINES_IN_CODE);
}
@@ -917,9 +932,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
TextRange dependencyRangeToUse = dependantRange == null || useParentBlockAsDependencyAllTheTime
? myParent.getTextRange() : dependantRange;
- return Spacing.createDependentLFSpacing(
- space, space, dependencyRangeToUse, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE
- );
+ return Spacing.createDependentLFSpacing(space, space, dependencyRangeToUse, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
}
else {
return Spacing.createSpacing(0, 0, 1, false, mySettings.KEEP_BLANK_LINES_IN_CODE);
@@ -1043,8 +1056,12 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
ASTNode dependencyEndAnchor = mySettings.METHOD_BRACE_STYLE == CommonCodeStyleSettings.NEXT_LINE ? myChild2 : myChild1;
int dependencyEnd = dependencyEndAnchor.getTextRange().getEndOffset();
+ boolean keepInOneLine = mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE
+ && method.getBody() != null
+ && !method.getBody().textContains('\n');
+
myResult = getSpaceBeforeLBrace(mySettings.SPACE_BEFORE_METHOD_LBRACE, mySettings.METHOD_BRACE_STYLE,
- new TextRange(dependencyStart, dependencyEnd), mySettings.KEEP_SIMPLE_METHODS_IN_ONE_LINE,
+ new TextRange(dependencyStart, dependencyEnd), keepInOneLine,
useParentBlockAsDependencyAllTheTime);
}
else if (myRole1 == ChildRole.MODIFIER_LIST) {