mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -31,6 +31,7 @@ class IdeaCommunityProperties extends BaseIdeaProperties {
|
||||
additionalIDEPropertiesFilePaths = ["$home/build/conf/ideaCE.properties".toString()]
|
||||
toolsJarRequired = true
|
||||
buildCrossPlatformDistribution = true
|
||||
customJreFileName = "jbrex8u112b736.21_x64.tar.gz"
|
||||
|
||||
productLayout.platformApiModules = CommunityRepositoryModules.PLATFORM_API_MODULES + JAVA_API_MODULES
|
||||
productLayout.platformImplementationModules = CommunityRepositoryModules.PLATFORM_IMPLEMENTATION_MODULES + JAVA_IMPLEMENTATION_MODULES +
|
||||
|
||||
@@ -203,6 +203,7 @@ public abstract class QuickFixFactory {
|
||||
@NotNull public abstract IntentionAction createCreateGetterSetterPropertyFromUsageFix(@NotNull PsiMethodCallExpression call);
|
||||
|
||||
@NotNull public abstract IntentionAction createStaticImportMethodFix(@NotNull PsiMethodCallExpression call);
|
||||
@NotNull public abstract IntentionAction createQualifyStaticMethodCallFix(@NotNull PsiMethodCallExpression call);
|
||||
|
||||
@NotNull public abstract IntentionAction createReplaceAddAllArrayToCollectionFix(@NotNull PsiMethodCallExpression call);
|
||||
|
||||
|
||||
+3
@@ -461,6 +461,8 @@ public class HighlightMethodUtil {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createCreateAbstractMethodFromUsageFix(methodCall));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createCreatePropertyFromUsageFix(methodCall));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createStaticImportMethodFix(methodCall));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.createQualifyStaticMethodCallFix(methodCall));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, QUICK_FIX_FACTORY.addMethodQualifierFix(methodCall));
|
||||
if (resolved instanceof PsiVariable && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
PsiMethod method = LambdaUtil.getFunctionalInterfaceMethod(((PsiVariable)resolved).getType());
|
||||
if (method != null) {
|
||||
@@ -854,6 +856,7 @@ public class HighlightMethodUtil {
|
||||
registerChangeParameterClassFix(methodCall, list, highlightInfo);
|
||||
if (methodCandidates.length == 0) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.createStaticImportMethodFix(methodCall));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.createQualifyStaticMethodCallFix(methodCall));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, QUICK_FIX_FACTORY.addMethodQualifierFix(methodCall));
|
||||
}
|
||||
for (IntentionAction action : QUICK_FIX_FACTORY.getVariableTypeFromCallFixes(methodCall, list)) {
|
||||
|
||||
+6
@@ -455,6 +455,12 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createQualifyStaticMethodCallFix(@NotNull PsiMethodCallExpression call) {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createReplaceAddAllArrayToCollectionFix(@NotNull PsiMethodCallExpression psiMethodCallExpression) {
|
||||
|
||||
+1
@@ -44,6 +44,7 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider
|
||||
|
||||
registrar.register(new ImportClassFix(ref));
|
||||
registrar.register(new StaticImportConstantFix(ref));
|
||||
registrar.register(new QualifyStaticConstantFix(ref));
|
||||
registrar.register(QuickFixFactory.getInstance().createSetupJDKFix());
|
||||
|
||||
OrderEntryFix.registerFixes(registrar, ref);
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class QualifyStaticConstantFix extends StaticImportConstantFix {
|
||||
public QualifyStaticConstantFix(@NotNull PsiJavaCodeReferenceElement referenceElement) {
|
||||
super(referenceElement);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getBaseText() {
|
||||
return "Qualify static constant access";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected StaticImportMethodQuestionAction<PsiField> createQuestionAction(List<PsiField> fieldsToImport,
|
||||
@NotNull Project project,
|
||||
Editor editor) {
|
||||
return new StaticImportMethodQuestionAction<PsiField>(project, editor, fieldsToImport, myRef) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getPopupTitle() {
|
||||
return QuickFixBundle.message("field.to.import.chooser.title");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doImport(PsiField toImport) {
|
||||
PsiJavaCodeReferenceElement element = myRef.getElement();
|
||||
if (!(element instanceof PsiReferenceExpression)) return;
|
||||
QualifyStaticMethodCallFix.qualifyStatically(toImport, project, (PsiReferenceExpression)element);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class QualifyStaticMethodCallFix extends StaticImportMethodFix {
|
||||
public QualifyStaticMethodCallFix(@NotNull PsiMethodCallExpression methodCallExpression) {
|
||||
super(methodCallExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getBaseText() {
|
||||
return "Qualify static call";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected StaticImportMethodQuestionAction<PsiMethod> createQuestionAction(List<PsiMethod> methodsToImport,
|
||||
@NotNull Project project,
|
||||
Editor editor) {
|
||||
return new StaticImportMethodQuestionAction<PsiMethod>(project, editor, methodsToImport, myMethodCall) {
|
||||
@Override
|
||||
protected void doImport(PsiMethod toImport) {
|
||||
PsiMethodCallExpression element = myMethodCall.getElement();
|
||||
if (element == null) return;
|
||||
qualifyStatically(toImport, project, element.getMethodExpression());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void qualifyStatically(PsiMember toImport,
|
||||
Project project,
|
||||
PsiReferenceExpression qualifiedExpression) {
|
||||
PsiClass containingClass = toImport.getContainingClass();
|
||||
if (containingClass == null) return;
|
||||
PsiReferenceExpression qualifier = JavaPsiFacade.getElementFactory(project).createReferenceExpression(containingClass);
|
||||
WriteCommandAction.runWriteCommandAction(project, "Qualify Static Access", null, () -> {
|
||||
qualifiedExpression.setQualifierExpression(qualifier);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(qualifiedExpression);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -31,7 +31,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class StaticImportConstantFix extends StaticImportMemberFix<PsiField> {
|
||||
private final SmartPsiElementPointer<PsiJavaCodeReferenceElement> myRef;
|
||||
protected final SmartPsiElementPointer<PsiJavaCodeReferenceElement> myRef;
|
||||
|
||||
public StaticImportConstantFix(@NotNull PsiJavaCodeReferenceElement referenceElement) {
|
||||
myRef = SmartPointerManager.getInstance(referenceElement.getProject()).createSmartPsiElementPointer(referenceElement);
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class StaticImportMethodFix extends StaticImportMemberFix<PsiMethod> {
|
||||
private final SmartPsiElementPointer<PsiMethodCallExpression> myMethodCall;
|
||||
protected final SmartPsiElementPointer<PsiMethodCallExpression> myMethodCall;
|
||||
|
||||
public StaticImportMethodFix(@NotNull PsiMethodCallExpression methodCallExpression) {
|
||||
myMethodCall = SmartPointerManager.getInstance(methodCallExpression.getProject()).createSmartPsiElementPointer(methodCallExpression);
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ public class StaticImportMethodQuestionAction<T extends PsiMember> implements Qu
|
||||
return true;
|
||||
}
|
||||
|
||||
private void doImport(final T toImport) {
|
||||
protected void doImport(final T toImport) {
|
||||
final Project project = toImport.getProject();
|
||||
final PsiElement element = myRef.getElement();
|
||||
if (element == null) return;
|
||||
|
||||
+6
@@ -535,6 +535,12 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
return new StaticImportMethodFix(call);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createQualifyStaticMethodCallFix(@NotNull PsiMethodCallExpression call) {
|
||||
return new QualifyStaticMethodCallFix(call);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createReplaceAddAllArrayToCollectionFix(@NotNull PsiMethodCallExpression call) {
|
||||
|
||||
+11
-1
@@ -18,6 +18,8 @@ package com.intellij.refactoring.inlineSuperClass;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiDocCommentOwner;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.inline.InlineOptionsDialog;
|
||||
@@ -70,8 +72,16 @@ public class InlineSuperClassRefactoringDialog extends InlineOptionsDialog {
|
||||
final GridBagConstraints gc =
|
||||
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
|
||||
JBUI.emptyInsets(), 0, 0);
|
||||
panel.add(myDocPanel, gc);
|
||||
panel.add(super.createCenterPanel(), gc);
|
||||
panel.add(myDocPanel, gc);
|
||||
if (mySuperClass.getDocComment() == null) {
|
||||
boolean hasJavadoc =
|
||||
InlineSuperClassRefactoringProcessor.getClassMembersToPush(mySuperClass).stream().anyMatch(memberInfo -> {
|
||||
PsiMember member = memberInfo.getMember();
|
||||
return member instanceof PsiDocCommentOwner && ((PsiDocCommentOwner)member).getDocComment() != null;
|
||||
});
|
||||
myDocPanel.setVisible(hasJavadoc);
|
||||
}
|
||||
gc.weighty = 1;
|
||||
gc.fill = GridBagConstraints.BOTH;
|
||||
panel.add(Box.createVerticalGlue(), gc);
|
||||
|
||||
+10
-7
@@ -40,7 +40,6 @@ import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
@@ -63,18 +62,22 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori
|
||||
myCurrentInheritor = currentInheritor;
|
||||
mySuperClass = superClass;
|
||||
myPolicy = policy;
|
||||
MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySuperClass, new MemberInfo.Filter<PsiMember>() {
|
||||
public boolean includeMember(PsiMember element) {
|
||||
return !(element instanceof PsiClass) || PsiTreeUtil.isAncestor(mySuperClass, element, true);
|
||||
}
|
||||
});
|
||||
List<MemberInfo> members = memberInfoStorage.getClassMemberInfos(mySuperClass);
|
||||
List<MemberInfo> members = getClassMembersToPush(mySuperClass);
|
||||
for (MemberInfo member : members) {
|
||||
member.setChecked(true);
|
||||
}
|
||||
myMemberInfos = members.toArray(new MemberInfo[members.size()]);
|
||||
}
|
||||
|
||||
public static List<MemberInfo> getClassMembersToPush(PsiClass superClass) {
|
||||
MemberInfoStorage memberInfoStorage = new MemberInfoStorage(superClass, new MemberInfo.Filter<PsiMember>() {
|
||||
public boolean includeMember(PsiMember element) {
|
||||
return !(element instanceof PsiClass) || PsiTreeUtil.isAncestor(superClass, element, true);
|
||||
}
|
||||
});
|
||||
return memberInfoStorage.getClassMemberInfos(superClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected UsageViewDescriptor createUsageViewDescriptor(@NotNull final UsageInfo[] usages) {
|
||||
return new InlineSuperClassUsageViewDescriptor(mySuperClass);
|
||||
|
||||
+3
-1
@@ -19,6 +19,7 @@ import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.SkipSlowTestLocally;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import slowCheck.*;
|
||||
@@ -27,6 +28,7 @@ import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@SkipSlowTestLocally
|
||||
public class ApplyRandomIntentionsTest extends AbstractApplyAndRevertTestCase {
|
||||
|
||||
@Override
|
||||
@@ -134,7 +136,7 @@ public class ApplyRandomIntentionsTest extends AbstractApplyAndRevertTestCase {
|
||||
CheckerSettings settings = CheckerSettings.DEFAULT_SETTINGS.withIterationCount(30);
|
||||
Generator<InvokeIntention> genIntention =
|
||||
Generator.from(data -> InvokeIntention.generate(psiManager.findFile(javaFiles().generateValue(data)), data));
|
||||
|
||||
|
||||
PropertyChecker.forAll(settings, Generator.listsOf(genIntention.noShrink()), list -> {
|
||||
long startModCount = tracker.getModificationCount();
|
||||
if (rebuildStamp.getAndSet(startModCount) != startModCount) {
|
||||
|
||||
+6
-4
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.SkipSlowTestLocally;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -41,8 +42,9 @@ import java.util.List;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@SkipSlowTestLocally
|
||||
public class CompletionConsistencyTest extends AbstractApplyAndRevertTestCase {
|
||||
|
||||
|
||||
static class CompletionInvocation extends ActionOnRange {
|
||||
final int itemIndexRaw;
|
||||
LookupElement selectedItem;
|
||||
@@ -91,7 +93,7 @@ public class CompletionConsistencyTest extends AbstractApplyAndRevertTestCase {
|
||||
if (offset < 0) continue;
|
||||
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
|
||||
|
||||
PsiElement leaf = psiFile.findElementAt(offset);
|
||||
|
||||
try {
|
||||
@@ -138,8 +140,8 @@ public class CompletionConsistencyTest extends AbstractApplyAndRevertTestCase {
|
||||
|
||||
private static boolean isInnermostReferenceQualifier(PsiElement leaf) {
|
||||
PsiElement parent = leaf.getParent();
|
||||
return parent instanceof PsiJavaCodeReferenceElement &&
|
||||
!((PsiJavaCodeReferenceElement)parent).isQualified() &&
|
||||
return parent instanceof PsiJavaCodeReferenceElement &&
|
||||
!((PsiJavaCodeReferenceElement)parent).isQualified() &&
|
||||
parent.getParent() instanceof PsiJavaCodeReferenceElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,13 @@ abstract class ProductProperties {
|
||||
*/
|
||||
String customJvmMemoryOptionsX64 = null
|
||||
|
||||
/**
|
||||
* Include jre for OS X from 171.3 release.
|
||||
* https://youtrack.jetbrains.com/issue/JRE-401
|
||||
* As soon as the issue will be fixed the change should be reverted.
|
||||
*/
|
||||
String customJreFileName = "jbre8u112b736.21_x64.tar.gz"
|
||||
|
||||
/**
|
||||
* An identifier which will be used to form names for directories where configuration and caches will be stored, usually a product name
|
||||
* without spaces with added version ('IntelliJIdea2016.1' for IntelliJ IDEA 2016.1)
|
||||
|
||||
+9
-2
@@ -51,9 +51,16 @@ class MacDmgBuilder {
|
||||
|
||||
static void signAndBuildDmg(BuildContext buildContext, MacDistributionCustomizer customizer, MacHostProperties macHostProperties, String macZipPath) {
|
||||
MacDmgBuilder dmgBuilder = createInstance(buildContext, customizer, macHostProperties)
|
||||
def jreArchivePath = buildContext.bundledJreManager.findMacJreArchive()
|
||||
def jreDir = new File(buildContext.paths.projectHome, 'build/jdk')
|
||||
def jreArchivePath = new File(jreDir, buildContext.productProperties.customJreFileName)
|
||||
if (!jreArchivePath.exists()) {
|
||||
buildContext.bundledJreManager.findMacJreArchive()
|
||||
}
|
||||
|
||||
if (jreArchivePath != null) {
|
||||
dmgBuilder.doSignAndBuildDmg(macZipPath, jreArchivePath)
|
||||
String jreArchive = jreArchivePath.absolutePath
|
||||
buildContext.messages.info("jreArchive: $jreArchive")
|
||||
dmgBuilder.doSignAndBuildDmg(macZipPath, jreArchive)
|
||||
}
|
||||
else {
|
||||
buildContext.messages.info("Skipping building Mac OS distribution with bundled JRE because JRE archive is missing")
|
||||
|
||||
+1
-1
@@ -168,8 +168,8 @@ public class MethodCallUtils {
|
||||
|
||||
public static boolean isCallToMethod(@NotNull PsiMethodCallExpression expression, @NonNls @Nullable String calledOnClassName,
|
||||
@Nullable PsiType returnType, @NonNls @Nullable String methodName, @Nullable PsiType... parameterTypes) {
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
if (methodName != null) {
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final String referenceName = methodExpression.getReferenceName();
|
||||
if (!methodName.equals(referenceName)) {
|
||||
return false;
|
||||
|
||||
@@ -367,6 +367,11 @@
|
||||
<bundleName>com.siyeh.IntentionPowerPackBundle</bundleName>
|
||||
<categoryKey>intention.category.strings</categoryKey>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.siyeh.ipp.concatenation.ReplaceFormatStringWithConcatenationIntention</className>
|
||||
<bundleName>com.siyeh.IntentionPowerPackBundle</bundleName>
|
||||
<categoryKey>intention.category.strings</categoryKey>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.siyeh.ipp.concatenation.CopyConcatenatedStringToClipboardIntention</className>
|
||||
<bundleName>com.siyeh.IntentionPowerPackBundle</bundleName>
|
||||
|
||||
@@ -117,6 +117,8 @@ extract.while.loop.condition.to.if.statement.intention.name=Extract condition to
|
||||
extract.while.loop.condition.to.if.statement.intention.family.name=Extract While Loop Condition to Internal If Statement
|
||||
replace.concatenation.with.format.string.intention.name=Replace '+' with 'String.format()'
|
||||
replace.concatenation.with.format.string.intention.family.name=Replace String Concatenation with String.format()
|
||||
replace.format.string.with.concatenation.intention.name=Replace 'String.format()' with concatenation
|
||||
replace.format.string.with.concatenation.intention.family.name=Replace String.format() with Concatenation
|
||||
copy.concatenated.string.to.clipboard.intention.name=Copy String concatenation text to the clipboard
|
||||
copy.concatenated.string.to.clipboard.intention.family.name=Copy String Concatenation Text to the Clipboard
|
||||
flip.expression.intention.family.name=Flip Binary Expression
|
||||
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.siyeh.ipp.concatenation;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.MethodCallUtils;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class ReplaceFormatStringWithConcatenationIntention extends Intention {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected PsiElementPredicate getElementPredicate() {
|
||||
return element -> {
|
||||
if (!(element instanceof PsiMethodCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element;
|
||||
if (!MethodCallUtils.isCallToMethod(methodCallExpression, CommonClassNames.JAVA_LANG_STRING, TypeUtils.getStringType(element),
|
||||
"format", (PsiType[])null)) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
|
||||
return arguments.length > 1 && getPercentSCount(arguments[0]) == arguments.length - 1 ||
|
||||
arguments.length > 2 && getPercentSCount(arguments[1]) == arguments.length - 2;
|
||||
};
|
||||
}
|
||||
|
||||
static int getPercentSCount(PsiExpression expression) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiLiteralExpression || expression instanceof PsiPolyadicExpression)
|
||||
|| !ExpressionUtils.hasStringType(expression)) {
|
||||
return -1;
|
||||
}
|
||||
final Object value = ExpressionUtils.computeConstantExpression(expression);
|
||||
if (!(value instanceof String)) {
|
||||
return -1;
|
||||
}
|
||||
final String string = (String)value;
|
||||
int index = string.indexOf('%');
|
||||
final int length = string.length();
|
||||
int count = 0;
|
||||
while (index >= 0) {
|
||||
final char c = string.charAt(index + 1);
|
||||
if (length > index + 1) {
|
||||
if (c == 's') {
|
||||
count++;
|
||||
}
|
||||
else if (c != '%') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
index = string.indexOf('%', index + 1);
|
||||
}
|
||||
if (count == 0) {
|
||||
return -1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processIntention(@NotNull PsiElement element) {
|
||||
if (!(element instanceof PsiMethodCallExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element;
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
final String replacementExpression;
|
||||
if (ExpressionUtils.hasStringType(arguments[0])) {
|
||||
replacementExpression = buildReplacementExpression(arguments, 0);
|
||||
}
|
||||
else {
|
||||
replacementExpression = buildReplacementExpression(arguments, 1);
|
||||
}
|
||||
PsiReplacementUtil.replaceExpression(methodCallExpression, replacementExpression);
|
||||
}
|
||||
|
||||
public String buildReplacementExpression(PsiExpression[] arguments, int indexOfFormatString) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
String value = (String)ExpressionUtils.computeConstantExpression(arguments[indexOfFormatString]);
|
||||
assert value != null;
|
||||
value = value.replace("%%", "%");
|
||||
int start = 0;
|
||||
int end = value.indexOf("%s");
|
||||
int count = 0;
|
||||
while (end >= 0) {
|
||||
if (end > start) {
|
||||
if (builder.length() > 0) {
|
||||
builder.append('+');
|
||||
}
|
||||
builder.append('"').append(value.substring(start, end)).append("\"+");
|
||||
}
|
||||
count++;
|
||||
final PsiExpression argument = arguments[indexOfFormatString + count];
|
||||
if (builder.length() == 0 && !ExpressionUtils.hasStringType(argument)) {
|
||||
builder.append("String.valueOf(").append(argument.getText()).append(')');
|
||||
}
|
||||
else {
|
||||
builder.append(argument.getText());
|
||||
}
|
||||
start = end + 2;
|
||||
end = value.indexOf("%s", start);
|
||||
}
|
||||
if (start < value.length() - 1) {
|
||||
if (builder.length() > 0) {
|
||||
builder.append('+');
|
||||
}
|
||||
builder.append('"').append(value.substring(start)).append('"');
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class X {
|
||||
|
||||
public String message(String actual, String expected) {
|
||||
return "Expected to get a '" + expected + "', got a '" + actual + "' instead";
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class X {
|
||||
|
||||
public String message(String actual, String expected) {
|
||||
return <spot>String.format("Expected to get a '%s', got a '%s' instead", expected, actual)</spot>;
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>Replaces a simple call to <b>String.format()</b> with a <b>String</b> concatenation.</p>
|
||||
</body>
|
||||
</html>
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.siyeh.ipp.concatenation;
|
||||
|
||||
import com.siyeh.ipp.IPPTestCase;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class ReplaceFormatStringWithConcatenationIntentionTest extends IPPTestCase {
|
||||
|
||||
public void testNotSupported() {
|
||||
doTestIntentionNotAvailable("class C {" +
|
||||
" String m() {" +
|
||||
" return /*_Replace 'String.format()' with concatenation*/String.format(\"%d\", 1);" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testSimple() {
|
||||
doTest("class C {" +
|
||||
" String m() {" +
|
||||
" return /*_Replace 'String.format()' with concatenation*/String.format(\"%s\", 1);" +
|
||||
" }" +
|
||||
"}",
|
||||
|
||||
"class C {" +
|
||||
" String m() {" +
|
||||
" return String.valueOf(1);" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testMultiple() {
|
||||
doTest("class C {" +
|
||||
" String m(String expected, String actual) {" +
|
||||
" return String./*_Replace 'String.format()' with concatenation*/format(\"Expected to get a '%s', got a '%s' instead\", expected, actual);" +
|
||||
" }" +
|
||||
"}",
|
||||
|
||||
"class C {" +
|
||||
" String m(String expected, String actual) {" +
|
||||
" return \"Expected to get a '\" + expected + \"', got a '\" + actual + \"' instead\";" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user