mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports method calls that can be replaced with operators.
|
||||
</body>
|
||||
</html>
|
||||
+4
-2
@@ -46,7 +46,9 @@ parameter.can.be.final.tooltip=Parameter ''{0}'' can be final
|
||||
groovy.probable.bugs=Probable bugs
|
||||
equals.between.inconvertible.types='equals()' between objects of inconvertible types
|
||||
equals.between.inconvertible.types.tooltip=<code>{0}</code> between objects of inconvertible types ''{1}'' and ''{2}''
|
||||
|
||||
convert.to.operator=Change to operator
|
||||
convert.to.operator.double.negation.option=Use double negation (i.e. !!)
|
||||
convert.to.operator.compareto.equality.option=Change compareTo equality to equals (i.e. ==)
|
||||
unassigned.access=Variable Not Assigned
|
||||
unassigned.access.short.name=VariableNotAssigned
|
||||
unassigned.access.tooltip=Variable ''{0}'' might not be assigned
|
||||
@@ -61,7 +63,7 @@ no.type.specified=No type specified
|
||||
dynamic.element=Dynamic Element
|
||||
|
||||
########################################################################################################################
|
||||
# InpectorGroovy properties
|
||||
# InspectorGroovy properties
|
||||
########################################################################################################################
|
||||
pointless.boolean.problem.descriptor=#ref can be simplified to ''{0}'' #loc
|
||||
pointless.arithmetic.error.message=#ref can be replaced with ''{0}'' #loc
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.ReplacementData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations.Transformation;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations.Transformations;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.codeInspection.ProblemHighlightType.WEAK_WARNING;
|
||||
import static org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle.message;
|
||||
|
||||
public class ChangeToOperatorInspection extends BaseInspection {
|
||||
private static final Map<String, Transformation> TRANSFORMATIONS = Transformations.get();
|
||||
|
||||
public boolean useDoubleNegation = true;
|
||||
public boolean shouldChangeCompareToEqualityToEquals = true;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected BaseInspectionVisitor buildVisitor() {
|
||||
return new BaseInspectionVisitor() {
|
||||
@Override
|
||||
public void visitMethodCallExpression(GrMethodCallExpression methodCallExpression) {
|
||||
super.visitMethodCallExpression(methodCallExpression);
|
||||
processMethodCall(methodCallExpression);
|
||||
}
|
||||
|
||||
private void processMethodCall(GrMethodCallExpression methodCallExpression) {
|
||||
PsiMethod method = methodCallExpression.resolveMethod();
|
||||
if (!isValid(method)) return;
|
||||
|
||||
String methodName = method.getName();
|
||||
Transformation transformation = TRANSFORMATIONS.get(methodName);
|
||||
if (transformation == null) return;
|
||||
|
||||
// TODO apply transformation recursively
|
||||
ReplacementData replacement = transformation.transform(methodCallExpression,
|
||||
new OptionsData(useDoubleNegation, shouldChangeCompareToEqualityToEquals));
|
||||
registerFixIfValid(replacement);
|
||||
}
|
||||
|
||||
private boolean isValid(PsiModifierListOwner method) {
|
||||
return ((method != null) && !method.hasModifierProperty(PsiModifier.STATIC));
|
||||
}
|
||||
|
||||
private void registerFixIfValid(@Nullable ReplacementData replacement) {
|
||||
if (replacement == null) return;
|
||||
|
||||
String message = getMessage();
|
||||
LocalQuickFix[] quickFixes = {getFix(message, replacement.getReplacement())};
|
||||
registerError(replacement.getExpression(), message, quickFixes, WEAK_WARNING);
|
||||
}
|
||||
|
||||
private GroovyFix getFix(@NotNull final String message, final String replacement) {
|
||||
return new GroovyFix() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
replaceExpression((GrExpression)descriptor.getPsiElement(), replacement);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message("convert.to.operator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this);
|
||||
optionsPanel.addCheckbox(message("convert.to.operator.double.negation.option"), "useDoubleNegation");
|
||||
optionsPanel.addCheckbox(message("convert.to.operator.compareto.equality.option"), "shouldChangeCompareToEqualityToEquals");
|
||||
return optionsPanel;
|
||||
}
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.utils.ParenthesesUtils;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.utils.BoolUtils.isNegation;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.utils.ComparisonUtils.isComparison;
|
||||
|
||||
public final class MethodCallData {
|
||||
private final PsiElement backingElement;
|
||||
|
||||
private boolean isNegated;
|
||||
private GrExpression base;
|
||||
private GrExpression[] arguments;
|
||||
private IElementType comparison;
|
||||
|
||||
@Nullable
|
||||
public static MethodCallData create(@NotNull PsiElement backingElement) {
|
||||
return Builder.build(backingElement);
|
||||
}
|
||||
|
||||
private MethodCallData(@NotNull PsiElement backingElement) {
|
||||
this.backingElement = backingElement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement getBackingElement() {
|
||||
return backingElement;
|
||||
}
|
||||
|
||||
public boolean isNegated() {
|
||||
return isNegated;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getBase() {
|
||||
return base.getText();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getArgument(int i) {
|
||||
return (i >= arguments.length) ? null
|
||||
: arguments[i].getText();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IElementType getComparison() {
|
||||
return comparison;
|
||||
}
|
||||
|
||||
private static final class Builder {
|
||||
@Nullable
|
||||
public static MethodCallData build(@NotNull PsiElement backingElement) {
|
||||
MethodCallData result = new MethodCallData(backingElement);
|
||||
|
||||
PsiElement element = backingElement;
|
||||
element = handleNegation(result, element);
|
||||
element = handleComparison(result, element);
|
||||
element = handleMethodCall(result, element);
|
||||
return (element == null) ? null
|
||||
: result;
|
||||
}
|
||||
|
||||
private static PsiElement handleNegation(MethodCallData result, @Nullable PsiElement element) {
|
||||
if (element == null) return null;
|
||||
|
||||
result.isNegated = isNegation(element);
|
||||
|
||||
if (result.isNegated) element = ((GrUnaryExpression)element).getOperand();
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
private static PsiElement handleComparison(MethodCallData result, @Nullable PsiElement element) {
|
||||
if (element == null) return null;
|
||||
|
||||
if (isComparison(element)) {
|
||||
GrBinaryExpression relationalExpression = (GrBinaryExpression)element;
|
||||
|
||||
element = relationalExpression.getLeftOperand();
|
||||
result.comparison = relationalExpression.getOperationTokenType();
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement handleMethodCall(MethodCallData result, PsiElement element) {
|
||||
if (!(element instanceof GrMethodCall)) return null;
|
||||
|
||||
GrMethodCall methodCall = (GrMethodCall)element;
|
||||
|
||||
GrReferenceExpression invokedExpression = (GrReferenceExpression)methodCall.getInvokedExpression();
|
||||
GrExpression qualifierExpression = invokedExpression.getQualifierExpression();
|
||||
if (qualifierExpression == null) return null;
|
||||
|
||||
result.base = addParenthesesIfNeeded(qualifierExpression);
|
||||
result.arguments = addParenthesesIfNeeded(methodCall.getExpressionArguments());
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
private static GrExpression addParenthesesIfNeeded(@NotNull GrExpression expression) {
|
||||
return needsParentheses(expression) ? createParenthesizedExpr(expression)
|
||||
: expression;
|
||||
}
|
||||
|
||||
private static boolean needsParentheses(@NotNull GrExpression expression) {
|
||||
return ParenthesesUtils.getPrecedence(expression) >= ParenthesesUtils.TYPE_CAST_PRECEDENCE;
|
||||
}
|
||||
|
||||
private static GrExpression[] addParenthesesIfNeeded(GrExpression[] expressions) {
|
||||
GrExpression[] results = new GrExpression[expressions.length];
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
results[i] = addParenthesesIfNeeded(expressions[i]);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static GrExpression createParenthesizedExpr(@NotNull GrExpression expression) {
|
||||
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(expression.getProject());
|
||||
return factory.createParenthesizedExpr(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data;
|
||||
|
||||
public final class OptionsData {
|
||||
private final boolean useDoubleNegation;
|
||||
private final boolean shouldChangeCompareToEqualityToEquals;
|
||||
|
||||
public OptionsData(boolean useDoubleNegation, boolean shouldChangeCompareToEqualityToEquals) {
|
||||
this.useDoubleNegation = useDoubleNegation;
|
||||
this.shouldChangeCompareToEqualityToEquals = shouldChangeCompareToEqualityToEquals;
|
||||
}
|
||||
|
||||
public boolean useDoubleNegation() {
|
||||
return useDoubleNegation;
|
||||
}
|
||||
|
||||
public boolean shouldChangeCompareToEqualityToEquals() {
|
||||
return shouldChangeCompareToEqualityToEquals;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
|
||||
public final class ReplacementData {
|
||||
private final GrExpression element;
|
||||
private final String replacement;
|
||||
|
||||
public ReplacementData(@NotNull GrExpression element, @NotNull String replacement) {
|
||||
this.element = element;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
public GrExpression getExpression() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public String getExpressionText() {
|
||||
return element.getText();
|
||||
}
|
||||
|
||||
public String getReplacement() {
|
||||
return replacement;
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mLNOT;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.utils.BoolUtils.isNegation;
|
||||
|
||||
class AsBooleanTransformation extends UnaryTransformation {
|
||||
public static final String NEGATION = mLNOT.toString();
|
||||
public static final String DOUBLE_NEGATION = NEGATION + NEGATION;
|
||||
|
||||
public AsBooleanTransformation() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrExpression getExpandedElement(GrMethodCallExpression callExpression) {
|
||||
PsiElement parent = callExpression.getParent();
|
||||
if (isNegation(parent)) {
|
||||
return (GrExpression)parent;
|
||||
}
|
||||
else {
|
||||
return super.getExpandedElement(callExpression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String getPrefix(MethodCallData methodInfo, OptionsData optionsData) {
|
||||
if (methodInfo.isNegated()) {
|
||||
return NEGATION;
|
||||
}
|
||||
else if (isImplicitlyBoolean(methodInfo)) {
|
||||
return "";
|
||||
}
|
||||
else if (optionsData.useDoubleNegation()) {
|
||||
return DOUBLE_NEGATION;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isImplicitlyBoolean(MethodCallData methodInfo) {
|
||||
return methodInfo.getBackingElement().getParent() instanceof GrIfStatement;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* e.g.
|
||||
* a.equals(b) → (a == b)
|
||||
* !a.equals(b) → (a != b)
|
||||
*/
|
||||
public class BinaryTransformation extends Transformation {
|
||||
public BinaryTransformation(@Nullable IElementType operator) {
|
||||
super(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getReplacement(MethodCallData methodInfo, OptionsData optionsData) {
|
||||
String lhs = getLhs(methodInfo);
|
||||
IElementType operator = getOperator(methodInfo, optionsData);
|
||||
String rhs = getRhs(methodInfo);
|
||||
if (lhs == null || operator == null || rhs == null) return null;
|
||||
|
||||
return format("%s %s %s", lhs, operator, rhs);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getLhs(MethodCallData methodInfo) {
|
||||
return methodInfo.getBase();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected IElementType getOperator(MethodCallData methodInfo, OptionsData optionsData) {
|
||||
return operator;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getRhs(MethodCallData methodInfo) {
|
||||
return methodInfo.getArgument(0);
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mLPAREN;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mRPAREN;
|
||||
|
||||
class CallTransformation extends UnaryTransformation {
|
||||
public static final String EMPTY_PARENS = mLPAREN.toString() + mRPAREN;
|
||||
|
||||
public CallTransformation() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReplacement(MethodCallData call, OptionsData options) {
|
||||
return super.getReplacement(call, options) + EMPTY_PARENS;
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
|
||||
import static com.google.common.base.Objects.firstNonNull;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.utils.ComparisonUtils.isComparison;
|
||||
|
||||
class CompareToTransformation extends BinaryTransformation {
|
||||
public CompareToTransformation() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrExpression getExpandedElement(GrMethodCallExpression callExpression) {
|
||||
PsiElement parent = callExpression.getParent();
|
||||
return isComparison(parent) ? (GrExpression)parent
|
||||
: super.getExpandedElement(callExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IElementType getOperator(MethodCallData methodInfo, OptionsData optionsData) {
|
||||
IElementType comparison = methodInfo.getComparison();
|
||||
if (shouldChangeCompareToEqualityToEquals(optionsData, comparison)) {
|
||||
return firstNonNull(comparison, mCOMPARE_TO);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldChangeCompareToEqualityToEquals(OptionsData optionsData, IElementType comparison) {
|
||||
return !isEquality(comparison) || optionsData.shouldChangeCompareToEqualityToEquals();
|
||||
}
|
||||
|
||||
private static boolean isEquality(IElementType comparison) {
|
||||
return (comparison == mNOT_EQUAL) || (comparison == mEQUAL);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mEQUAL;
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mNOT_EQUAL;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.utils.BoolUtils.isNegation;
|
||||
|
||||
class EqualsTransformation extends BinaryTransformation {
|
||||
public EqualsTransformation() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrExpression getExpandedElement(GrMethodCallExpression callExpression) {
|
||||
PsiElement parent = callExpression.getParent();
|
||||
return isNegation(parent) ? (GrExpression)parent
|
||||
: super.getExpandedElement(callExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected IElementType getOperator(MethodCallData methodInfo, OptionsData optionsData) {
|
||||
return methodInfo.isNegated() ? mNOT_EQUAL
|
||||
: mEQUAL;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
class GetAtTransformation extends Transformation {
|
||||
public GetAtTransformation() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getReplacement(MethodCallData methodInfo, OptionsData optionsData) {
|
||||
String argument = methodInfo.getArgument(0);
|
||||
if (argument == null) return null;
|
||||
|
||||
return format("%s[%s]",
|
||||
methodInfo.getBase(), argument);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
|
||||
class IsCaseTransformation extends BinaryTransformation {
|
||||
public IsCaseTransformation() {
|
||||
super(GroovyTokenTypes.kIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String getLhs(MethodCallData methodInfo) {
|
||||
return super.getRhs(methodInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String getRhs(MethodCallData methodInfo) {
|
||||
return super.getLhs(methodInfo);
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
class PutAtTransformation extends Transformation {
|
||||
private final Transformation getAtTransformation;
|
||||
|
||||
public PutAtTransformation(Transformation getAtTransformation) {
|
||||
super(null);
|
||||
this.getAtTransformation = getAtTransformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getReplacement(MethodCallData methodInfo, OptionsData optionsData) {
|
||||
String argument = methodInfo.getArgument(1);
|
||||
if (argument == null) return null;
|
||||
|
||||
return format("%s = %s",
|
||||
getAtTransformation.getReplacement(methodInfo, optionsData), argument);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.ReplacementData;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
|
||||
public abstract class Transformation {
|
||||
@Nullable
|
||||
protected final IElementType operator;
|
||||
|
||||
public Transformation(@Nullable IElementType operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ReplacementData transform(GrMethodCallExpression callExpression, OptionsData optionsData) {
|
||||
GrExpression element = getExpandedElement(callExpression);
|
||||
MethodCallData methodInfo = MethodCallData.create(element);
|
||||
if (methodInfo == null) return null;
|
||||
|
||||
String replacement = getReplacement(methodInfo, optionsData);
|
||||
if (replacement == null) return null;
|
||||
|
||||
return new ReplacementData(element, replacement);
|
||||
}
|
||||
|
||||
protected GrExpression getExpandedElement(GrMethodCallExpression callExpression) {
|
||||
return callExpression;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract String getReplacement(MethodCallData methodInfo, OptionsData optionsData);
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtil.ImmutableMapBuilder;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.HardcodedGroovyMethodConstants.*;
|
||||
|
||||
public class Transformations {
|
||||
private final ImmutableMapBuilder<String, Transformation> result = ContainerUtil.immutableMapBuilder();
|
||||
|
||||
public static Map<String, Transformation> get() {
|
||||
Transformations builder = new Transformations();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Transformations() {
|
||||
addUnary();
|
||||
addBinary();
|
||||
addCustom();
|
||||
}
|
||||
|
||||
private void addUnary() {
|
||||
result.put(BITWISE_NEGATE, new UnaryTransformation(mBNOT));
|
||||
result.put(NEGATIVE, new UnaryTransformation(mMINUS));
|
||||
result.put(POSITIVE, new UnaryTransformation(mPLUS));
|
||||
result.put(NEXT, new UnaryTransformation(mINC));
|
||||
result.put(PREVIOUS, new UnaryTransformation(mDEC));
|
||||
|
||||
result.put(AS_BOOLEAN, new AsBooleanTransformation());
|
||||
result.put(CALL, new CallTransformation());
|
||||
}
|
||||
|
||||
private void addBinary() {
|
||||
result.put(PLUS, new BinaryTransformation(mPLUS));
|
||||
result.put(MINUS, new BinaryTransformation(mMINUS));
|
||||
result.put(MULTIPLY, new BinaryTransformation(mSTAR));
|
||||
result.put(POWER, new BinaryTransformation(mSTAR_STAR));
|
||||
result.put(DIV, new BinaryTransformation(mDIV));
|
||||
result.put(MOD, new BinaryTransformation(mMOD));
|
||||
result.put(OR, new BinaryTransformation(mBOR));
|
||||
result.put(AND, new BinaryTransformation(mBAND));
|
||||
result.put(XOR, new BinaryTransformation(mBXOR));
|
||||
result.put(LEFT_SHIFT, new BinaryTransformation(new GroovyElementType("<<")));
|
||||
result.put(RIGHT_SHIFT, new BinaryTransformation(new GroovyElementType(">>")));
|
||||
result.put(RIGHT_SHIFT_UNSIGNED, new BinaryTransformation(new GroovyElementType(">>>")));
|
||||
|
||||
result.put(AS_TYPE, new BinaryTransformation(kAS));
|
||||
|
||||
result.put(IS_CASE, new IsCaseTransformation());
|
||||
result.put(EQUALS, new EqualsTransformation());
|
||||
result.put(COMPARE_TO, new CompareToTransformation());
|
||||
}
|
||||
|
||||
private void addCustom() {
|
||||
Transformation getAtTransformation = new GetAtTransformation();
|
||||
result.put(GET_AT, getAtTransformation);
|
||||
result.put(PUT_AT, new PutAtTransformation(getAtTransformation));
|
||||
}
|
||||
|
||||
private Map<String, Transformation> build() {
|
||||
return result.build();
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.changeToOperator.transformations;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.MethodCallData;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.data.OptionsData;
|
||||
|
||||
import static com.google.common.base.Objects.firstNonNull;
|
||||
|
||||
/**
|
||||
* e.g.
|
||||
* !a.asBoolean() → !a
|
||||
* a.asBoolean() → !!a
|
||||
* if(a.asBoolean()) → if(a)
|
||||
*/
|
||||
public class UnaryTransformation extends Transformation {
|
||||
public UnaryTransformation(@Nullable IElementType operator) {
|
||||
super(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getReplacement(MethodCallData call, OptionsData options) {
|
||||
String prefix = getPrefix(call, options);
|
||||
String base = call.getBase();
|
||||
if ((prefix == null) || (base == null)) return null;
|
||||
|
||||
return prefix + base;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getPrefix(MethodCallData call, OptionsData optionsData) {
|
||||
return firstNonNull(operator, "").toString();
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions;
|
||||
|
||||
import com.siyeh.HardcodedMethodConstants;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
@NonNls
|
||||
public class HardcodedGroovyMethodConstants {
|
||||
public static final String COMPARE_TO = HardcodedMethodConstants.COMPARE_TO;
|
||||
public static final String EQUALS = HardcodedMethodConstants.EQUALS;
|
||||
public static final String NEXT = HardcodedMethodConstants.NEXT;
|
||||
|
||||
public static final String AND = "and";
|
||||
public static final String AS_BOOLEAN = "asBoolean";
|
||||
public static final String AS_TYPE = "asType";
|
||||
public static final String BITWISE_NEGATE = "bitwiseNegate";
|
||||
public static final String CALL = "call";
|
||||
public static final String DIV = "div";
|
||||
public static final String GET_AT = "getAt";
|
||||
public static final String IS_CASE = "isCase";
|
||||
public static final String LEFT_SHIFT = "leftShift";
|
||||
public static final String MINUS = "minus";
|
||||
public static final String MOD = "mod";
|
||||
public static final String MULTIPLY = "multiply";
|
||||
public static final String NEGATIVE = "negative";
|
||||
public static final String OR = "or";
|
||||
public static final String PLUS = "plus";
|
||||
public static final String POSITIVE = "positive";
|
||||
public static final String POWER = "power";
|
||||
public static final String PREVIOUS = "previous";
|
||||
public static final String PUT_AT = "putAt";
|
||||
public static final String RIGHT_SHIFT = "rightShift";
|
||||
public static final String RIGHT_SHIFT_UNSIGNED = "rightShiftUnsigned";
|
||||
public static final String XOR = "xor";
|
||||
}
|
||||
+29
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -56,6 +56,8 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.HardcodedGroovyMethodConstants.*;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
@@ -134,33 +136,33 @@ public class TypesUtil {
|
||||
private static final Map<IElementType, String> ourUnaryOperationsToOperatorNames = new HashMap<IElementType, String>();
|
||||
|
||||
static {
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mPLUS, "plus");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mMINUS, "minus");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mBAND, "and");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mBOR, "or");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mBXOR, "xor");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mDIV, "div");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mMOD, "mod");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mSTAR, "multiply");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.kAS, "asType");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mCOMPARE_TO, "compareTo");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mGT, "compareTo");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mGE, "compareTo");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mLT, "compareTo");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mLE, "compareTo");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mSTAR_STAR, "power");
|
||||
ourOperationsToOperatorNames.put(GroovyElementTypes.COMPOSITE_LSHIFT_SIGN, "leftShift");
|
||||
ourOperationsToOperatorNames.put(GroovyElementTypes.COMPOSITE_RSHIFT_SIGN, "rightShift");
|
||||
ourOperationsToOperatorNames.put(GroovyElementTypes.COMPOSITE_TRIPLE_SHIFT_SIGN, "rightShiftUnsigned");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mEQUAL, "equals");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mNOT_EQUAL, "equals");
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mPLUS, PLUS);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mMINUS, MINUS);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mBAND, AND);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mBOR, OR);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mBXOR, XOR);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mDIV, DIV);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mMOD, MOD);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mSTAR, MULTIPLY);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.kAS, AS_TYPE);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mCOMPARE_TO, COMPARE_TO);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mGT, COMPARE_TO);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mGE, COMPARE_TO);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mLT, COMPARE_TO);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mLE, COMPARE_TO);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mSTAR_STAR, POWER);
|
||||
ourOperationsToOperatorNames.put(GroovyElementTypes.COMPOSITE_LSHIFT_SIGN, LEFT_SHIFT);
|
||||
ourOperationsToOperatorNames.put(GroovyElementTypes.COMPOSITE_RSHIFT_SIGN, RIGHT_SHIFT);
|
||||
ourOperationsToOperatorNames.put(GroovyElementTypes.COMPOSITE_TRIPLE_SHIFT_SIGN, RIGHT_SHIFT_UNSIGNED);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mEQUAL, EQUALS);
|
||||
ourOperationsToOperatorNames.put(GroovyTokenTypes.mNOT_EQUAL, EQUALS);
|
||||
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mLNOT, "asBoolean");
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mPLUS, "positive");
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mMINUS, "negative");
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mDEC, "previous");
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mINC, "next");
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mBNOT, "bitwiseNegate");
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mLNOT, AS_BOOLEAN);
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mPLUS, POSITIVE);
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mMINUS, NEGATIVE);
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mDEC, PREVIOUS);
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mINC, NEXT);
|
||||
ourUnaryOperationsToOperatorNames.put(GroovyTokenTypes.mBNOT, BITWISE_NEGATE);
|
||||
}
|
||||
|
||||
private static final TObjectIntHashMap<String> TYPE_TO_RANK = new TObjectIntHashMap<String>();
|
||||
|
||||
+2
-1
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.utils;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -64,7 +65,7 @@ public class BoolUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isNegation(GrExpression exp) {
|
||||
public static boolean isNegation(@Nullable PsiElement exp) {
|
||||
if (!(exp instanceof GrUnaryExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-2
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.utils;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -54,7 +54,7 @@ public class ComparisonUtils {
|
||||
s_invertedComparisons.put(GroovyTokenTypes.mLE, ">");
|
||||
}
|
||||
|
||||
public static boolean isComparison(GrExpression exp) {
|
||||
public static boolean isComparison(PsiElement exp) {
|
||||
if (!(exp instanceof GrBinaryExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -799,6 +799,10 @@
|
||||
displayName="Java-style property access"
|
||||
groupName="Style" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.style.JavaStylePropertiesInvocationInspection"/>
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="ChangeToOperator"
|
||||
displayName="Change to operator"
|
||||
groupName="Style" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.changeToOperator.ChangeToOperatorInspection"/>
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="GroovyAccessToStaticFieldLockedOnInstance"
|
||||
displayName="Access to static field locked on instance data"
|
||||
groupName="Threading issues" enabledByDefault="true" level="WARNING"
|
||||
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.inspections
|
||||
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.plugins.groovy.codeInspection.changeToOperator.ChangeToOperatorInspection
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import static org.jetbrains.plugins.groovy.GroovyFileType.GROOVY_FILE_TYPE
|
||||
import static org.jetbrains.plugins.groovy.util.TestUtils.CARET_MARKER
|
||||
|
||||
public class GrChangeToOperatorTest extends LightCodeInsightFixtureTestCase {
|
||||
def inspection = new ChangeToOperatorInspection()
|
||||
|
||||
void testSimpleUnaryExpression() {
|
||||
assertValid(/a.bitwiseNegate()/, /~a/)
|
||||
assertValid(/a.negative()/, /-a/)
|
||||
assertValid(/a.positive()/, /+a/)
|
||||
assertValid(/a.call()/, /a()/)
|
||||
assertValid(/a.next()/, /++a/)
|
||||
assertValid(/a.previous()/, /--a/)
|
||||
}
|
||||
|
||||
void testNegatableUnaryExpression() {
|
||||
assertValid(/a.asBoolean()/, /!!a/)
|
||||
assertValid(/!a.asBoolean()/, /!a/)
|
||||
|
||||
assertValid(/if (${_}a.asBoolean()${_});/, /a/)
|
||||
assertValid(/if (${_}!a.asBoolean()${_});/, /!a/)
|
||||
}
|
||||
|
||||
// TODO
|
||||
void notYetTestable_testComplexNegatableUnaryExpression() {
|
||||
assertValid(/if (${_}'a'.intern().asBoolean()${_});/, /'a'.intern()/)
|
||||
}
|
||||
|
||||
void testNegatedOption() {
|
||||
inspection.useDoubleNegation = false
|
||||
|
||||
assertValid(/a.asBoolean()/)
|
||||
assertValid(/!a.asBoolean()/, /!a/)
|
||||
|
||||
assertValid(/if (${_}a.asBoolean()${_});/, /a/)
|
||||
assertValid(/if (${_}!a.asBoolean()${_});/, /!a/)
|
||||
}
|
||||
|
||||
// TODO
|
||||
void notYetTestable_testComplexNegatedOption() {
|
||||
inspection.useDoubleNegation = false
|
||||
|
||||
assertValid(/if (${_}'a'.intern().asBoolean()${_});/, /'a'.intern()/)
|
||||
}
|
||||
|
||||
void testSimpleBinaryExpression() {
|
||||
assertValid(/a.minus(b)/, /a - b/)
|
||||
assertValid(/a.plus(b)/, /a + b/)
|
||||
assertValid(/a.power(b)/, /a**b/)
|
||||
assertValid(/a.div(b)/, $/a / b/$)
|
||||
assertValid(/a.mod(b)/, /a % b/)
|
||||
assertValid(/a.or(b)/, /a | b/)
|
||||
assertValid(/a.and(b)/, /a & b/)
|
||||
assertValid(/a.xor(b)/, /a ^ b/)
|
||||
assertValid(/a.leftShift(b)/, /a << b/)
|
||||
assertValid(/a.rightShift(b)/, /a >> b/)
|
||||
assertValid(/a.rightShiftUnsigned(b)/, /a >>> b/)
|
||||
|
||||
assertValid(/a.asType(String)/, /a as String/)
|
||||
assertValid(/a.multiply(b)/, /a * b/)
|
||||
|
||||
assertValid(/(a.toString() as Operators).minus(b.hashCode())/, /(a.toString() as Operators) - b.hashCode()/)
|
||||
|
||||
assertValid(/!${_}a.asType(String)${_}/, /(a as String)/)
|
||||
|
||||
assertValid(/${_}a.xor((a.b+1) == b)${_} == a/, /(a ^ ((a.b + 1) == b))/)
|
||||
}
|
||||
|
||||
// TODO
|
||||
void notYetTestable_testComplexBinaryExpression() {
|
||||
assertValid(/b.isCase(a)/, /a in b/)
|
||||
assertValid(/if (${_}[1,2,3].isCase(2-1)${_});/, /(2 - 1) in [1,2,3]/)
|
||||
assertValid(/def x = ${_}"1".plus(1)${_}/, /"1" + 1/)
|
||||
assertValid(/("1" + 1).plus(1)/, /("1" + 1) + 1/)
|
||||
assertValid(/!a.toString().asBoolean()/, /!a.toString()/)
|
||||
}
|
||||
|
||||
void testNegatableBinaryExpression() {
|
||||
assertValid(/a.equals(b)/, /a == b/)
|
||||
assertValid(/!a.equals(b)/, /a != b/)
|
||||
}
|
||||
|
||||
// TODO
|
||||
void notYetTestable_testComplexNegatableBinaryExpression() {
|
||||
assertValid(/!(1.toString().replace('1', '2')+"").equals(2.toString())/, /(1.toString().replace('1', '2') + "") != 2.toString()/)
|
||||
}
|
||||
|
||||
void testCompareTo() {
|
||||
assertValid(/a.compareTo(b)/, /a <=> b/)
|
||||
assertValid(/a.compareTo(b) < 0/, /a < b/)
|
||||
assertValid(/a.compareTo(b) <= 0/, /a <= b/)
|
||||
assertValid(/a.compareTo(b) == 0/, /a == b/)
|
||||
assertValid(/a.compareTo(b) != 0/, /a != b/)
|
||||
assertValid(/a.compareTo(b) >= 0/, /a >= b/)
|
||||
assertValid(/a.compareTo(b) > 0/, /a > b/)
|
||||
|
||||
assertValid(/if (${_}(2-1).compareTo(b) > 0${_});/, /(2 - 1) > b/)
|
||||
}
|
||||
|
||||
void testCompareToOption() {
|
||||
inspection.shouldChangeCompareToEqualityToEquals = false
|
||||
assertValid(/a.compareTo(b) == 0/)
|
||||
assertValid(/a.compareTo(b) != 0/)
|
||||
}
|
||||
|
||||
void testGetAndPut() {
|
||||
assertValid(/a.getAt(b)/, /a[b]/)
|
||||
assertValid(/a.putAt(b, 'c')/, /a[b] = 'c'/)
|
||||
|
||||
assertValid(/a.putAt(b, 'c'*2)/, /a[b] = ('c' * 2)/)
|
||||
}
|
||||
|
||||
final _ = '/*placeholder*/'
|
||||
@Language('Groovy') final DECLARATIONS = '''
|
||||
@SuppressWarnings("GrMethodMayBeStatic")
|
||||
class Operators {
|
||||
def bitwiseNegate() { null }
|
||||
def negative() { null }
|
||||
def positive() { null }
|
||||
def call() { null }
|
||||
def next() { null }
|
||||
def previous() { null }
|
||||
def plus(b) { null }
|
||||
def minus(b) { null }
|
||||
def multiply(b) { null }
|
||||
def power(b) { null }
|
||||
def div(b) { null }
|
||||
def mod(b) { null }
|
||||
def or(b) { null }
|
||||
def and(b) { null }
|
||||
def xor(b) { null }
|
||||
def leftShift(b) { null }
|
||||
def rightShift(b) { null }
|
||||
def rightShiftUnsigned(b) { null }
|
||||
def asType(b) { null }
|
||||
def getAt(b) { null }
|
||||
def putAt(b, c) { null }
|
||||
|
||||
boolean asBoolean() { true }
|
||||
boolean isCase(b) { true }
|
||||
boolean equals(b) { true }
|
||||
int compareTo(b) { 0 }
|
||||
}
|
||||
|
||||
def (Operators a, Operators b) = [null, null]
|
||||
'''
|
||||
|
||||
private void assertValid(@Language('Groovy') String text, @Language('Groovy') String methodReplacement) {
|
||||
def (prefix, method, suffix) = getMessage(text)
|
||||
configure("${prefix}${CARET_MARKER}${method}${suffix}")
|
||||
myFixture.launchAction(myFixture.findSingleIntention(inspection.getMessage()))
|
||||
myFixture.checkResult("${DECLARATIONS} ${prefix}${methodReplacement}${suffix}")
|
||||
}
|
||||
|
||||
private void assertValid(@Language('Groovy') String text) {
|
||||
configure(text)
|
||||
assertEmpty myFixture.getAvailableIntentions()
|
||||
}
|
||||
|
||||
private configure(@Language('Groovy') String text) {
|
||||
myFixture.enableInspections(inspection)
|
||||
myFixture.configureByText(GROOVY_FILE_TYPE, "${DECLARATIONS} ${text}")
|
||||
}
|
||||
|
||||
private getMessage(String text) {
|
||||
def _ = Pattern.quote(_)
|
||||
def (__, prefix, method, suffix) = (text =~ /^(?:(.*?)${_})?(.+?)(?:${_}(.*?))?$/)[0]
|
||||
[prefix ?: '', method, suffix ?: '']
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user