From 27f5689d0bc6bd9705a15feb9936426de7d6fdea Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Wed, 18 Mar 2015 11:27:57 +0300 Subject: [PATCH 01/17] external system: unmodifiable children view list should be transient --- .../intellij/openapi/externalSystem/model/DataNode.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java index 4658f0c7b9f0..edfd3059c0d1 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java @@ -45,7 +45,7 @@ public class DataNode implements Serializable { private static final Logger LOG = Logger.getInstance(DataNode.class); @NotNull private final List> myChildren = ContainerUtilRt.newArrayList(); - @NotNull private final List> myChildrenView = Collections.unmodifiableList(myChildren); + @NotNull private transient List> myChildrenView = Collections.unmodifiableList(myChildren); @NotNull private final Key myKey; private transient T myData; @@ -241,6 +241,12 @@ public class DataNode implements Serializable { out.defaultWriteObject(); } + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + myChildrenView = Collections.unmodifiableList(myChildren); + } + public byte[] getDataBytes() throws IOException { if (myRawData != null) return myRawData; From e12499ab3827393943bbd49a9da93b1c11894b4f Mon Sep 17 00:00:00 2001 From: Alexey Gopachenko Date: Tue, 17 Mar 2015 17:46:29 +0100 Subject: [PATCH 02/17] IDEA-137369 findElementAt behavior has changed in IDEA 14 --- .../src/com/intellij/psi/impl/source/tree/CompositeElement.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java index 36aa2eef4e45..d3c5b2654df0 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java @@ -161,6 +161,7 @@ public class CompositeElement extends TreeElement { @Override public LeafElement findLeafElementAt(int offset) { TreeElement element = this; + if (element.getTreeParent() == null && offset >= element.getTextLength()) return null; startFind: while (true) { TreeElement child = element.getFirstChildNode(); From eb52e035f814c7494f246034a74fdda0c8b82935 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Wed, 18 Mar 2015 12:49:48 +0300 Subject: [PATCH 03/17] Removed useless type-cast as it fails miserably in upsource environment where CorePsiDocumentManager is used --- .../psi/impl/source/tree/injected/MultiHostRegistrarImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 33439da288af..9a0acc0c13b1 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 @@ -204,9 +204,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT addToResults(new Place(shreds), null); return; } - PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject); - //todo restore - //assert !documentManager.getUncommittedDocumentsUnsafe().contains(myHostDocument) : "document is uncommitted: "+myHostDocument; + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject); Place place = new Place(shreds); DocumentWindowImpl documentWindow = new DocumentWindowImpl(myHostDocument, isOneLineEditor, place); From 108c1879aac9ac33860a574c55754220d894db79 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Wed, 18 Mar 2015 10:51:12 +0100 Subject: [PATCH 04/17] WEB-14031 Allow HTML warning supressing comments to be followed by newline --- .../codeInspection/DefaultXmlSuppressionProvider.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java b/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java index c314b3093c39..b41f08661a8a 100644 --- a/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java +++ b/xml/xml-psi-api/src/com/intellij/codeInspection/DefaultXmlSuppressionProvider.java @@ -29,11 +29,13 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.*; -import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashSet; + /** * @author Dmitry Avdeev */ @@ -110,8 +112,8 @@ public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider implem if (id == null) { return true; } - @NonNls final String[] parts = text.split("[ ,]"); - return ArrayUtil.find(parts, id) != -1 || ArrayUtil.find(parts, XmlSuppressableInspectionTool.ALL) != -1; + @NonNls final HashSet parts = ContainerUtil.newHashSet(StringUtil.getWordsIn(text)); + return parts.contains(id) || parts.contains(XmlSuppressableInspectionTool.ALL); } protected void suppress(PsiFile file, final PsiElement suppressionElement, String inspectionId, final int offset) { From b3668aa0c46401ff1055c73d30919336a4160e0c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 18 Mar 2015 11:12:47 +0100 Subject: [PATCH 05/17] debugger tabs labels shouldn't be centered --- .../intellij/execution/ui/layout/impl/GridCellImpl.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java index f57f4a7bf472..a5e133c6afc6 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java @@ -35,6 +35,8 @@ import com.intellij.ui.tabs.TabInfo; import com.intellij.ui.tabs.TabsListener; import com.intellij.ui.tabs.UiDecorator; import com.intellij.ui.tabs.impl.JBEditorTabs; +import com.intellij.ui.tabs.impl.singleRow.CompressibleSingleRowLayout; +import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout; import com.intellij.util.containers.HashSet; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -80,6 +82,11 @@ public class GridCellImpl implements GridCell { return true; } + @Override + protected SingleRowLayout createSingleRowLayout() { + return new CompressibleSingleRowLayout(this); + } + @Override public int tabMSize() { return 12; From 2635d49456bf7cd25cf20c937e89c195c50111d6 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 18 Mar 2015 13:19:23 +0300 Subject: [PATCH 06/17] IDEA-137182 Extend selection for method call expression --- .../wordSelection/MethodCallSelectioner.java | 45 +++++++++++++++++++ resources/src/META-INF/IdeaPlugin.xml | 1 + 2 files changed, 46 insertions(+) create mode 100644 java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java new file mode 100644 index 000000000000..e472d189225f --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/wordSelection/MethodCallSelectioner.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2015 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.codeInsight.editorActions.wordSelection; + +import com.intellij.codeInsight.editorActions.ExtendWordSelectionHandler; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethodCallExpression; + +import java.util.Collections; +import java.util.List; + +public class MethodCallSelectioner implements ExtendWordSelectionHandler { + @Override + public boolean canSelect(PsiElement e) { + return e instanceof PsiMethodCallExpression; + } + + @Override + public List select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) { + PsiMethodCallExpression methodCall = (PsiMethodCallExpression)e; + PsiElement referenceNameElement = methodCall.getMethodExpression().getReferenceNameElement(); + if (referenceNameElement == null) { + return null; + } + else { + return Collections.singletonList(new TextRange(referenceNameElement.getTextRange().getStartOffset(), + methodCall.getTextRange().getEndOffset())); + } + } +} diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index d2111515f42a..73f95eea746e 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1156,6 +1156,7 @@ + From 61085af49caeb40c9e2888cd13990c5bc5cb1f5d Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Wed, 18 Mar 2015 13:58:18 +0300 Subject: [PATCH 07/17] use product name #WEB-15766 fixed --- .../src/messages/VcsBundle.properties | 3 +++ .../vcs/checkin/CodeAnalysisBeforeCheckinHandler.java | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties index b3415ed35026..9757fa024738 100644 --- a/platform/platform-resources-en/src/messages/VcsBundle.properties +++ b/platform/platform-resources-en/src/messages/VcsBundle.properties @@ -229,6 +229,9 @@ update.directories.scope.name=Directories update.project.scope.name=Project dialog.title.changes.browser=Changes Browser code.smells.error.messages.tab.name=Code Analysis +code.smells.error.indexing=Code analysis is not possible right now +code.smells.error.indexing.message=Code analysis can''t be performed while {0} updates the indices in background.\n\ + You can commit the changes without running inspections, or you can wait until indices are built. searching.for.code.smells.processing.file.progress.text=Processing {0} checking.code.smells.progress.title=Performing Code Analysis before.commit.files.contain.code.smells.edit.them.confirm.text=Some files contain problems.\n\ diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java index 00f5970de790..d3630fb638d4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java @@ -19,6 +19,7 @@ package com.intellij.openapi.vcs.checkin; import com.intellij.CommonBundle; import com.intellij.codeInsight.CodeSmellInfo; import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.DumbService; @@ -32,11 +33,13 @@ import com.intellij.openapi.vcs.changes.CommitExecutor; import com.intellij.openapi.vcs.ui.RefreshableOnComponent; import com.intellij.ui.NonFocusableCheckBox; import com.intellij.util.PairConsumer; +import com.intellij.util.PlatformUtils; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; +import java.text.MessageFormat; import java.util.List; /** @@ -126,10 +129,9 @@ public class CodeAnalysisBeforeCheckinHandler extends CheckinHandler { public ReturnResult beforeCheckin(CommitExecutor executor, PairConsumer additionalDataConsumer) { if (getSettings().CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT) { if (DumbService.getInstance(myProject).isDumb()) { - if (Messages.showOkCancelDialog(myProject, - "Code analysis can't be performed while IntelliJ IDEA updates the indices in background.\n" + - "You can commit the changes without running inspections, or you can wait until indices are built.", - "Code analysis is not possible right now", + if (Messages.showOkCancelDialog(myProject, VcsBundle.message("code.smells.error.indexing.message", + ApplicationNamesInfo.getInstance().getProductName()), + VcsBundle.message("code.smells.error.indexing"), "&Wait", "&Commit", null) == Messages.OK) { return ReturnResult.CANCEL; } From 073d506bce8064bd1b4d67276229cf5421453889 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Mar 2015 11:55:08 +0100 Subject: [PATCH 08/17] don't multi-resolve groovy method references when not necessary --- .../GrReferenceExpressionImpl.java | 35 ++++++++++++++++--- .../lang/resolve/ResolveMethodTest.groovy | 12 +++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 34ca61fd7136..b4381a090090 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -18,10 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.NullableComputable; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.RecursionManager; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.ResolveCache; @@ -52,6 +49,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethod import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList; import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper; @@ -395,9 +393,36 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl filtered = ContainerUtil.filter(candidates, new Condition() { + @Override + public boolean value(GroovyResolveResult result) { + PsiElement element = result.getElement(); + return !(element instanceof GrReflectedMethod && hasMoreCompleteOverload((GrReflectedMethod)element)); + } + + private boolean hasMoreCompleteOverload(GrReflectedMethod element) { + final int skipped = element.getSkippedParameters().length; + return ContainerUtil.or(element.getBaseMethod().getReflectedMethods(), new Condition() { + @Override + public boolean value(GrReflectedMethod method) { + return method.getSkippedParameters().length > skipped; + } + }); + } + }); + return filtered.toArray(new GroovyResolveResult[filtered.size()]); + } + private static void assertAllAreValid(@NotNull GroovyResolveResult[] candidates) { for (GroovyResolveResult candidate : candidates) { final PsiElement element = candidate.getElement(); @@ -839,7 +864,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImplr() +''', PsiMethod) + } + + void testMethodReferenceWithDefaultParameters() { + resolveByText(''' +class X { + def foo(def it = null) {print it} + + def bar() { + print this.&foo + } +} ''', PsiMethod) } From d03918c12b04abecd1bd16f6bb302bcebb5934d2 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Mar 2015 12:06:37 +0100 Subject: [PATCH 09/17] more strict control over which unresolved references to report as groovy dynamic usages: take into account closure arguments don't report property access as a method usage don't return usages with a qualifier of a known type --- .../MethodLateBoundReferencesSearcher.java | 39 +++++++++++++------ .../lang/findUsages/FindUsagesTest.groovy | 4 ++ .../DynamicCallExpressionUsages.groovy | 9 +++++ .../dynamicUsages/DynamicUsages.groovy | 8 +++- 4 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 plugins/groovy/testdata/findUsages/dynamicCallExpressionUsages/DynamicCallExpressionUsages.groovy diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java index 9cb674308041..004965dac484 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java @@ -21,12 +21,17 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiReference; import com.intellij.psi.search.*; import com.intellij.psi.search.searches.MethodReferencesSearch; import com.intellij.psi.util.PropertyUtil; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCommandArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; @@ -46,9 +51,8 @@ public class MethodLateBoundReferencesSearcher extends QueryExecutorBase consumer) { final PsiMethod method = queryParameters.getMethod(); - SearchScope searchScope = GroovyScopeUtil.restrictScopeToGroovyFiles(queryParameters.getEffectiveSearchScope()).intersectWith(getUseScope(method)); - PsiClass aClass = method.getContainingClass(); - String className = aClass == null ? null : aClass.getName(); + SearchScope searchScope = GroovyScopeUtil.restrictScopeToGroovyFiles(queryParameters.getEffectiveSearchScope()).intersectWith( + getUseScope(method)); orderSearching(searchScope, method.getName(), method, queryParameters.getOptimizer(), method.getParameterList().getParametersCount()); final String propName = PropertyUtil.getPropertyName(method); @@ -85,16 +89,29 @@ public class MethodLateBoundReferencesSearcher extends QueryExecutorBase= 0 && !ref.hasMemberPointer() && + (!(parent instanceof GrMethodCall) || !argumentsMatch((GrMethodCall)parent, paramCount))) { + return true; + } + + GrExpression qualifier = ref.getQualifierExpression(); + if (qualifier == null || qualifier.getType() != null) { + return true; + } + + if (ref.resolve() != null) { + return true; + } + + if (ResolveUtil.isKeyOfMap(ref)) { return true; } @@ -104,7 +121,7 @@ public class MethodLateBoundReferencesSearcher extends QueryExecutorBaseo(a) { } +} + +def boo(Map args, p) { + p.foo 2 + p.foo { println "hello" } +} + diff --git a/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy b/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy index 84dfaee0d831..c043e1c6f632 100644 --- a/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy +++ b/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy @@ -6,6 +6,12 @@ def boo(Map args, p) { println p.focused println p.isFocused() - println args.focused //not a usage + // not usage candidates + println focused + println isFocused() + println "a".focused + println "a".isFocused() + + println args.focused } From 9a02a05621e62e8c560051e095835ea0d2b16aaa Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 17 Mar 2015 14:52:06 +0100 Subject: [PATCH 10/17] EA-66537 - NPE: TypeSelectorManagerImpl.serialize --- .../refactoring/ui/TypeSelectorManagerImpl.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java index b43a5e7f240c..baa07642e9a7 100644 --- a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java @@ -31,6 +31,7 @@ import com.intellij.refactoring.util.RefactoringHierarchyUtil; import com.intellij.util.ArrayUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -333,19 +334,24 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { typeSelected(type, getDefaultType()); } - public static void typeSelected(final PsiType type, final PsiType defaultType) { + public static void typeSelected(@NotNull final PsiType type, @Nullable final PsiType defaultType) { + if (defaultType == null) return; StatisticsManager.getInstance().incUseCount(new StatisticsInfo(getStatsKey(defaultType), serialize(type))); } private String getStatsKey() { - return getStatsKey(getDefaultType()); + final PsiType defaultType = getDefaultType(); + if (defaultType == null) { + return "IntroduceVariable##"; + } + return getStatsKey(defaultType); } private static String getStatsKey(final PsiType defaultType) { return "IntroduceVariable##" + serialize(defaultType); } - private static String serialize(PsiType type) { + private static String serialize(@NotNull PsiType type) { if (PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter) return type.getCanonicalText(); return TypeConversionUtil.erasure(type).getCanonicalText(); } From 291732bfe376a38aa4c93c0a3e0c2404e8c5dc48 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 17 Mar 2015 17:20:45 +0100 Subject: [PATCH 11/17] junit: workaround unexpected stop --- .../src/com/intellij/execution/junit2/SegmentedInputStream.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java b/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java index 7ebb739a0366..adf24c4f3264 100644 --- a/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java +++ b/java/execution/impl/src/com/intellij/execution/junit2/SegmentedInputStream.java @@ -94,6 +94,7 @@ public class SegmentedInputStream extends InputStream { while (nextRead != ' ' && nextRead != SegmentedStream.SPECIAL_SYMBOL) { buffer.append((char)nextRead); nextRead = readNext(); + if (nextRead == -1) return new char[0]; } return readNext(Integer.valueOf(buffer.toString()).intValue()); } From 176ddc58f4e10ccbf595bf6729fcc0a9dbb6c307 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 18 Mar 2015 12:15:12 +0100 Subject: [PATCH 12/17] junit: ability to run test unit failure (IDEA-77048) --- .../execution/junit/JUnitConfiguration.java | 47 ++++++++++++++- .../intellij/execution/junit/TestObject.java | 9 +++ .../configuration/JUnitConfigurable.form | 32 ++++++++-- .../configuration/JUnitConfigurable.java | 23 +++++++ .../intellij/junit3/JUnit3IdeaTestRunner.java | 2 +- .../intellij/junit4/JUnit4IdeaTestRunner.java | 37 ++++++++++-- .../rt/execution/junit/IdeaTestRunner.java | 2 +- .../execution/junit/JUnitForkedStarter.java | 2 +- .../rt/execution/junit/JUnitStarter.java | 11 +++- .../rt/execution/junit/RepeatCount.java | 60 +++++++++++++++++++ 10 files changed, 209 insertions(+), 16 deletions(-) create mode 100644 plugins/junit_rt/src/com/intellij/rt/execution/junit/RepeatCount.java diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java index 9c9e09286e3f..c318736e28fb 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java @@ -41,6 +41,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.rt.execution.junit.RepeatCount; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -330,6 +331,19 @@ public class JUnitConfiguration extends ModuleBasedConfiguration myPattern = new LinkedHashSet(); //iws/ipr compatibility @@ -463,7 +502,9 @@ public class JUnitConfiguration extends ModuleBasedConfiguration 0 + ? RepeatCount.getCountString(repeatCount) + : repeatMode; + myJavaParameters.getProgramParametersList().add(countString); + } return JUnitProcessHandler.runCommandLine(CommandLineBuilder.createFromJavaParameters(myJavaParameters, myEnvironment.getProject(), true)); } diff --git a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.form b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.form index 1ac9026100d3..7d3357c403c4 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.form +++ b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.form @@ -88,7 +88,7 @@ - + @@ -96,6 +96,20 @@ + + + + + + + + + + + + + + @@ -110,11 +124,21 @@ - + - + + + + - + + + + + + + + diff --git a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java index c05e990aeed5..1a2e151e0abf 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java +++ b/plugins/junit/src/com/intellij/execution/junit2/configuration/JUnitConfigurable.java @@ -47,6 +47,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.rt.execution.junit.RepeatCount; import com.intellij.ui.*; import com.intellij.ui.components.JBLabel; import com.intellij.util.IconUtil; @@ -104,6 +105,8 @@ public class JUnitConfigurable extends SettingsEditor implem private JComboBox myTypeChooser; private JBLabel mySearchForTestsLabel; private JPanel myScopesPanel; + private JComboBox myRepeatCb; + private JTextField myRepeatCountField; private static final String[] FORK_MODE_ALL = {JUnitConfiguration.FORK_NONE, JUnitConfiguration.FORK_METHOD, JUnitConfiguration.FORK_KLASS}; private static final String[] FORK_MODE = {JUnitConfiguration.FORK_NONE, JUnitConfiguration.FORK_METHOD}; private Project myProject; @@ -179,6 +182,15 @@ public class JUnitConfigurable extends SettingsEditor implem myTestLocations[JUnitConfigurationModel.DIR] = myDir; myTestLocations[JUnitConfigurationModel.CATEGORY] = myCategory; + myRepeatCb.setModel(new DefaultComboBoxModel(RepeatCount.REPEAT_TYPES)); + myRepeatCb.setSelectedItem(RepeatCount.ONCE); + myRepeatCb.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + myRepeatCountField.setEnabled(RepeatCount.N.equals(myRepeatCb.getSelectedItem())); + } + }); + final JPanel panel = myPattern.getComponent(); panel.setLayout(new BorderLayout()); myPatternTextField = new TextFieldWithBrowseButton(); @@ -246,6 +258,13 @@ public class JUnitConfigurable extends SettingsEditor implem myCommonJavaParameters.applyTo(configuration); configuration.setForkMode((String)myForkCb.getSelectedItem()); + configuration.setRepeatMode((String)myRepeatCb.getSelectedItem()); + try { + configuration.setRepeatCount(Integer.parseInt(myRepeatCountField.getText())); + } + catch (NumberFormatException e) { + configuration.setRepeatCount(1); + } } public void resetEditorFrom(final JUnitConfiguration configuration) { @@ -264,6 +283,10 @@ public class JUnitConfigurable extends SettingsEditor implem } myAlternativeJREPanel.init(configuration.getAlternativeJrePath(), configuration.isAlternativeJrePathEnabled()); myForkCb.setSelectedItem(configuration.getForkMode()); + final int count = configuration.getRepeatCount(); + myRepeatCountField.setText(String.valueOf(count)); + myRepeatCountField.setEnabled(count > 1); + myRepeatCb.setSelectedItem(configuration.getRepeatMode()); } private void changePanel () { diff --git a/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java index dde361c94bd5..d5fec550859a 100644 --- a/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/junit3/JUnit3IdeaTestRunner.java @@ -37,7 +37,7 @@ public class JUnit3IdeaTestRunner extends TestRunner implements IdeaTestRunner { super(DeafStream.DEAF_PRINT_STREAM); } - public int startRunnerWithArgs(String[] args, ArrayList listeners, String name, boolean sendTree) { + public int startRunnerWithArgs(String[] args, ArrayList listeners, String name, int count, boolean sendTree) { myListeners = listeners; mySendTree = sendTree; if (sendTree) { diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java index dae5c95b0241..f25880bfad36 100644 --- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4IdeaTestRunner.java @@ -34,7 +34,7 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { private RunListener myTestsListener; private OutputObjectRegistry myRegistry; - public int startRunnerWithArgs(String[] args, ArrayList listeners, String name, boolean sendTree) { + public int startRunnerWithArgs(String[] args, ArrayList listeners, String name, int count, boolean sendTree) { final Request request = JUnit4TestRunnerUtil.buildRequest(args, name, sendTree); if (request == null) return -1; @@ -75,11 +75,38 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner { }); } long startTime = System.currentTimeMillis(); - Result result = runner.run(testRunner/*.sortWith(new Comparator() { - public int compare(Object d1, Object d2) { - return ((Description)d1).getDisplayName().compareTo(((Description)d2).getDisplayName()); + Result result; + if (count == 1) { + result = runner.run(testRunner); + } + else { + if (count > 0) { + boolean success = true; + int i = 0; + while (i++ < count) { + result = runner.run(testRunner); + success &= result.wasSuccessful(); + } + long endTime = System.currentTimeMillis(); + long runTime = endTime - startTime; + if (sendTree) new TimeSender(myRegistry).printHeader(runTime); + + return success ? 0 : -1; } - })*/); + else { + boolean success = true; + while (true) { + result = runner.run(testRunner); + success &= result.wasSuccessful(); + if (count == -2 && !success) { + long endTime = System.currentTimeMillis(); + long runTime = endTime - startTime; + if (sendTree) new TimeSender(myRegistry).printHeader(runTime); + return -1; + } + } + } + } long endTime = System.currentTimeMillis(); long runTime = endTime - startTime; if (sendTree) new TimeSender(myRegistry).printHeader(runTime); diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java index 7937ee2492e6..a37c250b20a3 100644 --- a/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/IdeaTestRunner.java @@ -28,7 +28,7 @@ import java.util.List; public interface IdeaTestRunner { - int startRunnerWithArgs(String[] args, ArrayList listeners, String name, boolean sendTree); + int startRunnerWithArgs(String[] args, ArrayList listeners, String name, int count, boolean sendTree); void setStreams(SegmentedOutputStream segmentedOut, SegmentedOutputStream segmentedErr, int lastIdx); Object getTestToStart(String[] args, String name); diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java index 6b58cd009b87..2ab8cd01a73c 100644 --- a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitForkedStarter.java @@ -58,7 +58,7 @@ public class JUnitForkedStarter { IdeaTestRunner testRunner = (IdeaTestRunner)JUnitStarter.getAgentClass(isJUnit4).newInstance(); //noinspection IOResourceOpenedButNotSafelyClosed testRunner.setStreams(new SegmentedOutputStream(out, true), new SegmentedOutputStream(err, true), lastIdx); - System.exit(testRunner.startRunnerWithArgs(childTestDescription, listeners, null, false)); + System.exit(testRunner.startRunnerWithArgs(childTestDescription, listeners, null, 1, false)); } finally { System.setOut(oldOut); diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java index 02287c929dcb..e08656c9d0c1 100644 --- a/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/JUnitStarter.java @@ -18,7 +18,6 @@ package com.intellij.rt.execution.junit; import com.intellij.rt.execution.junit.segments.SegmentedOutputStream; import java.io.*; -import java.net.Inet4Address; import java.net.InetAddress; import java.net.Socket; import java.util.ArrayList; @@ -38,6 +37,7 @@ public class JUnitStarter { private static String ourForkMode; private static String ourCommandFileName; private static String ourWorkingDirs; + private static int ourCount = 1; public static boolean SM_RUNNER = System.getProperty("idea.junit.sm_runner") != null; public static void main(String[] args) throws IOException { @@ -124,6 +124,13 @@ public class JUnitStarter { continue; } + + final int count = RepeatCount.getCount(arg); + if (count != 0) { + ourCount = count; + continue; + } + result.addElement(arg); } } @@ -209,7 +216,7 @@ public class JUnitStarter { } IdeaTestRunner testRunner = (IdeaTestRunner)getAgentClass(isJUnit4).newInstance(); testRunner.setStreams(out, err, 0); - return testRunner.startRunnerWithArgs(args, listeners, name, !SM_RUNNER); + return testRunner.startRunnerWithArgs(args, listeners, name, ourCount, !SM_RUNNER); } catch (Exception e) { e.printStackTrace(System.err); diff --git a/plugins/junit_rt/src/com/intellij/rt/execution/junit/RepeatCount.java b/plugins/junit_rt/src/com/intellij/rt/execution/junit/RepeatCount.java new file mode 100644 index 000000000000..e61f2653178c --- /dev/null +++ b/plugins/junit_rt/src/com/intellij/rt/execution/junit/RepeatCount.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2015 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.rt.execution.junit; + +public abstract class RepeatCount { + public static final String ONCE = "Once"; + public static final String N = "N Times"; + public static final String UNTIL_FAILURE = "Until Failure"; + public static final String UNLIMITED = "Until Stopped"; + public static final String[] REPEAT_TYPES = new String[]{ONCE, N, UNTIL_FAILURE, UNLIMITED}; + + public static String getCountString(int count) { + if (count > 1) { + return "@" + N + count; + } + if (count == -1) { + return UNLIMITED; + } + if (count == -2) { + return UNTIL_FAILURE; + } + return ONCE; + } + + public static int getCount(String countString) { + if (countString.equals(ONCE)) { + return 1; + } + + if (countString.equals(UNLIMITED)) { + return -1; + } + + if (countString.equals(UNTIL_FAILURE)) { + return -2; + } + + if (countString.startsWith("@" + N)) { + try { + return Integer.parseInt(countString.substring(2)); + } + catch (NumberFormatException ignore) {} + } + + return 0; + } +} From ed73894272f0ad33c074aa308a21cb8875eda63b Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Mar 2015 12:29:01 +0100 Subject: [PATCH 13/17] restore substitutor tolerating lambda parameter types (EA-66528 - assert: PsiTypeMapper.visitType) --- .../src/com/intellij/psi/impl/PsiSubstitutorImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java index de1399133dc5..96a4a29fb45f 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -140,6 +140,11 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { return visitWildcardType(type.getWildcard()); } + @Override + public PsiType visitType(PsiType type) { + return null; + } + @Override public PsiType visitWildcardType(PsiWildcardType wildcardType) { final PsiType bound = wildcardType.getBound(); From 801fef38dc04bb91c249f0a2133a8f3324c8b2f3 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Mar 2015 12:32:55 +0100 Subject: [PATCH 14/17] remove unnecessary module dependency --- plugins/groovy/groovy-psi/groovy-psi.iml | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/groovy/groovy-psi/groovy-psi.iml b/plugins/groovy/groovy-psi/groovy-psi.iml index 4c2241dbc00c..f1f297e58bc2 100644 --- a/plugins/groovy/groovy-psi/groovy-psi.iml +++ b/plugins/groovy/groovy-psi/groovy-psi.iml @@ -9,7 +9,6 @@ - From b45ead31512c206226f7e92c33ee40d39f41e611 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 18 Mar 2015 14:40:39 +0300 Subject: [PATCH 15/17] EA-65896 - assert: FileManagerImpl.findDirectory --- .../intellij/debugger/ui/impl/FrameVariablesTree.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java index 379fcf0dcc18..c4c6201f0ee6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -396,11 +396,10 @@ public class FrameVariablesTree extends DebuggerTree { private static TextRange calculateLimitRange(final PsiFile file, final Document doc, final int line) { final int offset = doc.getLineStartOffset(line); if (offset > 0) { - for (PsiElement elem = file.findElementAt(offset); elem != null; elem = elem.getParent()) { - if (elem instanceof PsiMethod) { - final TextRange elemRange = elem.getTextRange(); - return new TextRange(doc.getLineNumber(elemRange.getStartOffset()), doc.getLineNumber(elemRange.getEndOffset())); - } + PsiMethod method = PsiTreeUtil.getParentOfType(file.findElementAt(offset), PsiMethod.class, false); + if (method != null) { + final TextRange elemRange = method.getTextRange(); + return new TextRange(doc.getLineNumber(elemRange.getStartOffset()), doc.getLineNumber(elemRange.getEndOffset())); } } return new TextRange(0, doc.getLineCount() - 1); From cd21b63b1f85ab69e7f436411132b814569bf606 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Mar 2015 13:15:39 +0100 Subject: [PATCH 16/17] don't waste memory in Native2AsciiCharsetDecoder buffer after it was used --- .../lang/properties/charset/Native2AsciiCharsetDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/boot/src/com/intellij/lang/properties/charset/Native2AsciiCharsetDecoder.java b/platform/boot/src/com/intellij/lang/properties/charset/Native2AsciiCharsetDecoder.java index 0481894602c4..f4a2b411daf8 100644 --- a/platform/boot/src/com/intellij/lang/properties/charset/Native2AsciiCharsetDecoder.java +++ b/platform/boot/src/com/intellij/lang/properties/charset/Native2AsciiCharsetDecoder.java @@ -29,7 +29,7 @@ import java.nio.charset.CoderResult; class Native2AsciiCharsetDecoder extends CharsetDecoder { private static final char INVALID_CHAR = (char)-1; - private final StringBuilder myOutBuffer = new StringBuilder(); + private StringBuilder myOutBuffer = new StringBuilder(); private final Charset myBaseCharset; Native2AsciiCharsetDecoder(final Native2AsciiCharset charset) { @@ -40,7 +40,7 @@ class Native2AsciiCharsetDecoder extends CharsetDecoder { @Override protected void implReset() { super.implReset(); - myOutBuffer.setLength(0); + myOutBuffer = new StringBuilder(); } @Override From 542fee7b3fbb33a58588c3c96e43d706d23f92a4 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 18 Mar 2015 15:21:12 +0300 Subject: [PATCH 17/17] IDEA-137257 Enter action after block comment --- .../com/intellij/codeInsight/editorActions/EnterHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java index 2dec8bd95b47..1c51f79beab5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EnterHandler.java @@ -424,7 +424,7 @@ public class EnterHandler extends BaseEnterHandler { myOffset = codeStyleManager.adjustLineIndent(myFile, myOffset); psiDocumentManager.commitAllDocuments(); - if (!StringUtil.isEmpty(indentInsideJavadoc) && myOffset < myDocument.getTextLength()) { + if (commentContext.docAsterisk && !StringUtil.isEmpty(indentInsideJavadoc) && myOffset < myDocument.getTextLength()) { myDocument.insertString(myOffset + 1, indentInsideJavadoc); myOffset += indentInsideJavadoc.length(); docIndentApplied = true;