Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2017-06-27 13:35:04 +03:00
25 changed files with 415 additions and 19 deletions
@@ -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);
@@ -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)) {
@@ -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) {
@@ -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);
@@ -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);
}
};
}
}
@@ -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);
}
);
}
}
@@ -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);
@@ -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);
@@ -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;
@@ -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) {
@@ -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);
@@ -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);
@@ -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) {
@@ -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)
@@ -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")
@@ -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
@@ -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();
}
}
@@ -0,0 +1,6 @@
class X {
public String message(String actual, String expected) {
return "Expected to get a '" + expected + "', got a '" + actual + "' instead";
}
}
@@ -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>;
}
}
@@ -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>
@@ -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\";" +
" }" +
"}");
}
}