IDEA-203683 Refactor GroovyTypeCheckVisitor, extract highlighting and fixes logic to own hierarchy

GitOrigin-RevId: fd60d700a90766311fbeec35d983c4e19e205d38
This commit is contained in:
alexey.afanasiev
2019-04-28 15:17:11 +03:00
committed by intellij-monorepo-bot
parent 6484b4ed62
commit 8a03bfbb6f
18 changed files with 326 additions and 178 deletions
@@ -265,6 +265,7 @@ invoke.completion.second.time.to.show.skipped.methods=Invoke completion second t
groovy.file.extension.is.not.mapped.to.groovy.file.type=*.groovy files are mapped to ''{0}''.\nYou can map them to Groovy in Settings | File types
class.is.not.annotation=''{0}'' is not an annotation
method.call.is.ambiguous=Method call is ambiguous
operator.call.is.ambiguous=Operator call is ambiguous
duplicated.named.parameter=Duplicated named parameter ''{0}'' found
no.super.classes.found=No super classes found
no.super.method.found=No super methods found
@@ -15,6 +15,10 @@ import org.jetbrains.plugins.groovy.annotator.GrHighlightUtil;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle;
import org.jetbrains.plugins.groovy.codeInspection.assignment.*;
import org.jetbrains.plugins.groovy.codeInspection.type.highlighting.BinaryExpressionHighlighter;
import org.jetbrains.plugins.groovy.codeInspection.type.highlighting.GrConstructorInvocationHighlighter;
import org.jetbrains.plugins.groovy.codeInspection.type.highlighting.GrEnumConstantHighlighter;
import org.jetbrains.plugins.groovy.codeInspection.type.highlighting.GrNewExpressionHighlighter;
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider;
import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor;
@@ -64,7 +68,6 @@ import java.util.Objects;
import static com.intellij.psi.util.PsiUtil.extractIterableTypeParameter;
import static org.jetbrains.plugins.groovy.codeInspection.type.GroovyTypeCheckVisitorHelper.*;
import static org.jetbrains.plugins.groovy.codeInspection.type.ImplKt.processConstructor;
import static org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils.isImplicitReturnStatement;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyExpressionUtil.isFake;
@@ -389,7 +392,10 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
}
private void checkNamedArgumentsType(@NotNull CallInfo<?> info) {
GroovyPsiElement rawCall = info.getCall();
checkNamedArgumentsType(info.getCall());
}
private void checkNamedArgumentsType(@NotNull GroovyPsiElement rawCall) {
if (!(rawCall instanceof GrCall)) return;
GrCall call = (GrCall)rawCall;
@@ -432,32 +438,6 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
}
}
private void checkOperator(@NotNull CallInfo<? extends GrBinaryExpression> info) {
if (hasErrorElements(info.getCall())) return;
GroovyResolveResult[] results = info.multiResolve();
GroovyResolveResult resolveResult = info.advancedResolve();
if (isOperatorWithSimpleTypes(info.getCall(), resolveResult)) return;
if (!checkCannotInferArgumentTypes(info)) return;
if (resolveResult.getElement() != null) {
checkMethodApplicability(resolveResult, true, info);
}
else if (results.length > 0) {
for (GroovyResolveResult result : results) {
if (!checkMethodApplicability(result, false, info)) return;
}
registerError(
info.getElementToHighlight(),
ProblemHighlightType.GENERIC_ERROR,
GroovyBundle.message("method.call.is.ambiguous")
);
}
}
private void highlightInapplicableMethodUsage(@NotNull GroovyResolveResult methodResolveResult,
@NotNull CallInfo info,
@NotNull PsiMethod method) {
@@ -719,13 +699,11 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
final GroovyCallReference reference = newExpression.getConstructorReference();
if (reference == null) return;
final GrNewExpressionInfo info = new GrNewExpressionInfo(newExpression);
if (processConstructor(reference, newExpression.getArgumentList(), info.getElementToHighlight(), myHighlightSink)) {
if (new GrNewExpressionHighlighter(newExpression, reference, myHighlightSink).highlight()) {
return;
}
checkNamedArgumentsType(info);
checkNamedArgumentsType(newExpression);
}
@Override
@@ -733,13 +711,11 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
super.visitEnumConstant(enumConstant);
if (hasErrorElements(enumConstant) || hasErrorElements(enumConstant.getArgumentList())) return;
final GrEnumConstantInfo info = new GrEnumConstantInfo(enumConstant);
final GroovyCallReference reference = enumConstant.getConstructorReference();
if (processConstructor(reference, enumConstant.getArgumentList(), info.getElementToHighlight(), myHighlightSink)) {
if (new GrEnumConstantHighlighter(enumConstant, myHighlightSink).highlight()) {
return;
}
checkNamedArgumentsType(info);
checkNamedArgumentsType(enumConstant);
}
@Override
@@ -747,12 +723,10 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
super.visitConstructorInvocation(invocation);
if (hasErrorElements(invocation) || hasErrorElements(invocation.getArgumentList())) return;
final GrConstructorInvocationInfo info = new GrConstructorInvocationInfo(invocation);
final GroovyCallReference reference = invocation.getConstructorReference();
if (processConstructor(reference, invocation.getArgumentList(), info.getElementToHighlight(), myHighlightSink)) {
if (new GrConstructorInvocationHighlighter(invocation, myHighlightSink).highlight()) {
return;
}
checkNamedArgumentsType(info);
checkNamedArgumentsType(invocation);
}
@Override
@@ -794,8 +768,9 @@ public class GroovyTypeCheckVisitor extends BaseInspectionVisitor {
@Override
public void visitBinaryExpression(@NotNull GrBinaryExpression binary) {
super.visitBinaryExpression(binary);
if (isFake(binary)) return;
checkOperator(new GrBinaryExprInfo(binary));
GroovyCallReference reference = binary.getReference();
if (reference == null) return;
new BinaryExpressionHighlighter(binary, reference, myHighlightSink).highlight();
}
@Override
@@ -1,74 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import com.intellij.util.containers.toArray
import org.jetbrains.plugins.groovy.GroovyBundle.message
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil.createSignature
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.DefaultConstructor
import org.jetbrains.plugins.groovy.lang.resolve.api.Argument
import org.jetbrains.plugins.groovy.lang.resolve.api.Arguments
fun HighlightSink.highlightUnknownArgs(highlightElement: PsiElement) {
registerProblem(highlightElement, ProblemHighlightType.WEAK_WARNING, message("cannot.infer.argument.types"))
}
fun HighlightSink.highlightCannotApplyError(invokedText: String, typesString: String, highlightElement: PsiElement) {
registerError(highlightElement, message("cannot.apply.method.or.closure", invokedText, typesString))
}
fun HighlightSink.highlightAmbiguousMethod(highlightElement: PsiElement) {
registerError(highlightElement, message("constructor.call.is.ambiguous"))
}
fun HighlightSink.highlightInapplicableMethod(result: GroovyMethodResult,
arguments: List<Argument>,
argumentList: GrArgumentList?,
highlightElement: PsiElement) {
val method = result.element
val containingClass = if (method is GrGdkMethod) method.staticMethod.containingClass else method.containingClass
val argumentString = argumentsString(arguments)
val methodName = method.name
if (containingClass == null) {
highlightCannotApplyError(methodName, argumentString, highlightElement)
return
}
val message: String
if (method is DefaultConstructor) {
message = message("cannot.apply.default.constructor", methodName)
}
else {
val factory = JavaPsiFacade.getElementFactory(method.project)
val containingType = factory.createType(containingClass, result.substitutor)
val canonicalText = containingType.internalCanonicalText
if (method.isConstructor) {
message = message("cannot.apply.constructor", methodName, canonicalText, argumentString)
}
else {
message = message("cannot.apply.method1", methodName, canonicalText, argumentString)
}
}
val fixes = generateCastFixes(result, arguments, argumentList)
registerProblem(highlightElement, ProblemHighlightType.GENERIC_ERROR, message, *fixes)
}
private fun argumentsString(arguments: List<Argument>): String {
return arguments.joinToString(", ", "(", ")") {
it.type?.internalCanonicalText ?: "?"
}
}
private fun generateCastFixes(result: GroovyMethodResult, arguments: Arguments, argumentList: GrArgumentList?): Array<out LocalQuickFix> {
val signature = createSignature(result.element, result.substitutor)
return GroovyTypeCheckVisitorHelper.genCastFixes(signature, arguments.map(Argument::type).toArray(PsiType.EMPTY_ARRAY), argumentList)
}
@@ -0,0 +1,54 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type.highlighting
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import org.jetbrains.plugins.groovy.GroovyBundle
import org.jetbrains.plugins.groovy.codeInspection.assignment.GrCastFix
import org.jetbrains.plugins.groovy.codeInspection.type.GroovyTypeCheckVisitorHelper.hasErrorElements
import org.jetbrains.plugins.groovy.codeInspection.type.GroovyTypeCheckVisitorHelper.isOperatorWithSimpleTypes
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression
import org.jetbrains.plugins.groovy.lang.psi.util.isFake
import org.jetbrains.plugins.groovy.lang.resolve.api.*
class BinaryExpressionHighlighter(val expression: GrBinaryExpression,
reference: GroovyCallReference,
sink: HighlightSink) : CallReferenceHighlighter(reference, sink) {
override val unknownArgsMessage: String
get() = GroovyBundle.message("cannot.infer.argument.types")
override val ambiguousMethodMessage: String
get() = GroovyBundle.message("operator.call.is.ambiguous")
override fun getInapplicableMethodMessage(result: GroovyMethodResult, containingType: PsiType, arguments: Arguments): String {
val typeText = containingType.internalCanonicalText
val argumentsString = argumentsString(arguments)
return GroovyBundle.message("cannot.apply.method1", result.element.name, typeText, argumentsString)
}
override fun getHighlightElement(): PsiElement = expression.operationToken
override fun buildFix(argument: Argument, applicabilityData: ApplicabilityData): GrCastFix? {
if (argument !is ExpressionArgument || applicabilityData.applicability != Applicability.inapplicable) return null
val arguments = reference.arguments ?: return null
if (argument !in arguments) return null
val type = applicabilityData.type ?: return null
val name = "Cast operand to " + type.presentableText
return GrCastFix(type, argument.expression, true, name)
}
fun highlight() {
if (expression.isFake()) return
if (hasErrorElements(expression)) return
val reference = expression.reference ?: return
val resolveResult = reference.advancedResolve()
if (isOperatorWithSimpleTypes(expression, resolveResult)) return
highlightMethod()
}
}
@@ -0,0 +1,105 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type.highlighting
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import org.jetbrains.plugins.groovy.GroovyBundle
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod
import org.jetbrains.plugins.groovy.lang.resolve.api.*
abstract class CallReferenceHighlighter(val reference: GroovyCallReference, val sink: HighlightSink) {
abstract val unknownArgsMessage: String
abstract val ambiguousMethodMessage: String
abstract fun getInapplicableMethodMessage(result: GroovyMethodResult, containingType: PsiType, arguments: Arguments): String
abstract fun getHighlightElement(): PsiElement
abstract fun buildFix(argument: Argument, applicabilityData: ApplicabilityData): LocalQuickFix?
fun highlightCannotApplyError(invokedText: String, typesString: String) {
sink.registerError(getHighlightElement(), GroovyBundle.message("cannot.apply.method.or.closure", invokedText, typesString))
}
fun highlightUnknownArgs() {
sink.registerProblem(getHighlightElement(), ProblemHighlightType.WEAK_WARNING, unknownArgsMessage)
}
fun highlightAmbiguousMethod() {
sink.registerError(getHighlightElement(), ambiguousMethodMessage)
}
fun highlightInapplicableMethod(result: GroovyMethodResult, arguments: Arguments) {
val method = result.element
val containingClass = if (method is GrGdkMethod) method.staticMethod.containingClass else method.containingClass
val methodName = method.name
val highlightElement = getHighlightElement()
val argumentsString = argumentsString(arguments)
if (containingClass == null) {
highlightCannotApplyError(methodName, argumentsString)
return
}
val factory = JavaPsiFacade.getElementFactory(method.project)
val containingType = factory.createType(containingClass, result.substitutor)
val fixes = generateFixes(result)
val message = getInapplicableMethodMessage(result, containingType, arguments)
sink.registerProblem(highlightElement, ProblemHighlightType.GENERIC_ERROR, message, *fixes)
}
fun highlightMethod(): Boolean {
val userArguments = reference.arguments ?: run {
highlightUnknownArgs()
return true
}
val results = reference.resolve(false)
var hasUnknownResults = false
for (result in results) {
if (result !is GroovyMethodResult) continue
val candidate = result.candidate ?: continue
val mapping = candidate.argumentMapping
if (mapping == null) {
highlightInapplicableMethod(result, userArguments)
return true
}
val applicability = mapping.applicability(result.substitutor, false)
when (applicability) {
Applicability.inapplicable -> {
highlightInapplicableMethod(result, userArguments)
return true
}
Applicability.canBeApplicable -> hasUnknownResults = true
else -> Unit
}
}
if (results.size > 1) {
if (hasUnknownResults) {
highlightUnknownArgs()
return true
}
else {
highlightAmbiguousMethod()
return true
}
}
return false
}
fun generateFixes(result: GroovyMethodResult): Array<LocalQuickFix> {
val applicabilities = result.candidate?.argumentMapping?.highlightApplicabilities(result.substitutor)
?: return emptyArray()
return applicabilities.entries
.mapNotNull { (argument, applicabilities) -> buildFix(argument, applicabilities) }
.toTypedArray()
}
}
@@ -0,0 +1,48 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type.highlighting
import com.intellij.psi.PsiType
import org.jetbrains.plugins.groovy.GroovyBundle
import org.jetbrains.plugins.groovy.codeInspection.assignment.ParameterCastFix
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.DefaultConstructor
import org.jetbrains.plugins.groovy.lang.resolve.api.*
abstract class ConstructorCallHighlighter(reference: GroovyCallReference,
sink: HighlightSink) : CallReferenceHighlighter(reference, sink) {
abstract fun getArgumentList(): GrArgumentList?
override val unknownArgsMessage: String
get() = GroovyBundle.message("cannot.infer.argument.types")
override val ambiguousMethodMessage: String
get() = GroovyBundle.message("method.call.is.ambiguous")
override fun getInapplicableMethodMessage(result: GroovyMethodResult, containingType: PsiType, arguments: Arguments): String {
val method = result.element
val methodName = method.name
if (method is DefaultConstructor) {
return GroovyBundle.message("cannot.apply.default.constructor", methodName)
}
else {
val canonicalText = containingType.internalCanonicalText
return GroovyBundle.message("cannot.apply.constructor", methodName, canonicalText,
argumentsString(arguments))
}
}
override fun buildFix(argument: Argument, applicabilityData: ApplicabilityData): ParameterCastFix? {
if (argument !is ExpressionArgument || applicabilityData.applicability != Applicability.inapplicable) return null
val arguments = reference.arguments ?: return null
val list = getArgumentList() ?: return null
if (argument !in arguments) return null
val type = applicabilityData.type ?: return null
val position = list.getExpressionArgumentIndex(argument.expression)
return ParameterCastFix(position, type)
}
fun highlight(): Boolean = highlightMethod()
}
@@ -0,0 +1,15 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type.highlighting
import com.intellij.psi.PsiElement
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
class GrConstructorInvocationHighlighter(val invocation: GrConstructorInvocation,
sink: HighlightSink) : ConstructorCallHighlighter(invocation.constructorReference, sink) {
override fun getArgumentList(): GrArgumentList = invocation.argumentList
override fun getHighlightElement(): PsiElement = getArgumentList()
}
@@ -0,0 +1,15 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type.highlighting
import com.intellij.psi.PsiElement
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant
class GrEnumConstantHighlighter(val enumConstant: GrEnumConstant,
sink: HighlightSink) : ConstructorCallHighlighter(enumConstant.constructorReference, sink) {
override fun getArgumentList(): GrArgumentList? = enumConstant.argumentList
override fun getHighlightElement(): PsiElement = getArgumentList() ?: enumConstant.nameIdentifierGroovy
}
@@ -0,0 +1,22 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type.highlighting
import com.intellij.psi.PsiElement
import com.intellij.util.IncorrectOperationException
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression
import org.jetbrains.plugins.groovy.lang.resolve.api.GroovyCallReference
class GrNewExpressionHighlighter(val newExpression: GrNewExpression,
reference: GroovyCallReference,
sink: HighlightSink) : ConstructorCallHighlighter(reference, sink) {
override fun getArgumentList(): GrArgumentList? = newExpression.argumentList
override fun getHighlightElement(): PsiElement {
val element = getArgumentList() ?: newExpression.referenceElement
if (element != null) return element
throw IncorrectOperationException("reference of new expression should exist if it is a constructor call")
}
}
@@ -0,0 +1,10 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type.highlighting
import org.jetbrains.plugins.groovy.lang.resolve.api.Arguments
fun argumentsString(arguments: Arguments): String {
return arguments.joinToString(", ", "(", ")") {
it.type?.internalCanonicalText ?: "?"
}
}
@@ -1,52 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.codeInspection.type
import com.intellij.psi.PsiElement
import org.jetbrains.plugins.groovy.highlighting.HighlightSink
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
import org.jetbrains.plugins.groovy.lang.resolve.api.Applicability
import org.jetbrains.plugins.groovy.lang.resolve.api.GroovyCallReference
fun processConstructor(reference: GroovyCallReference,
argumentList: GrArgumentList?,
highlightElement: PsiElement,
sink: HighlightSink): Boolean {
val userArguments = reference.arguments ?: run {
sink.highlightUnknownArgs(highlightElement)
return true
}
val results = reference.resolve(false)
var hasUnknownResults = false
for (result in results) {
if (result !is GroovyMethodResult) continue
val candidate = result.candidate ?: continue
val mapping = candidate.argumentMapping
if (mapping == null) {
sink.highlightInapplicableMethod(result, userArguments, argumentList, highlightElement)
return true
}
val applicability = mapping.applicability(result.substitutor, false)
when (applicability) {
Applicability.inapplicable -> {
sink.highlightInapplicableMethod(result, mapping.arguments, argumentList, highlightElement)
return true
}
Applicability.canBeApplicable -> hasUnknownResults = true
else -> Unit
}
}
if (results.size > 1) {
if (hasUnknownResults) {
sink.highlightUnknownArgs(highlightElement)
return true
}
else {
sink.highlightAmbiguousMethod(highlightElement)
return true
}
}
return false
}
@@ -7,4 +7,4 @@ typealias Arguments = List<Argument>
typealias Applicabilities = Map<Argument, ApplicabilityData>
data class ApplicabilityData(val psiType: PsiType?, val applicability: Applicability)
data class ApplicabilityData(val type: PsiType?, val applicability: Applicability)
@@ -17,14 +17,19 @@ package org.jetbrains.plugins.groovy.inspections
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
import org.jetbrains.plugins.groovy.LightGroovyTestCase
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
import org.jetbrains.plugins.groovy.util.TestUtils
/**
* @author Maxim.Medvedev
*/
class CastToTypeTest extends LightCodeInsightFixtureTestCase {
class CastToTypeTest extends LightGroovyTestCase {
final LightProjectDescriptor projectDescriptor = GroovyLightProjectDescriptor.GROOVY_LATEST
@Override
protected String getBasePath() {
return TestUtils.testDataPath + 'groovy/inspections/castToType'
@@ -42,4 +47,6 @@ class CastToTypeTest extends LightCodeInsightFixtureTestCase {
void testSimple() {doTest('Cast to List<? extends Abc>')}
void testInReturnType() {doTest('Cast to int')}
void testInForCycle() {doTest('Cast to List<Integer>')}
void testInBinaryExpression() {doTest('Cast operand to String')}
}
@@ -0,0 +1,11 @@
import groovy.transform.CompileStatic
class C {
def plus(String s) {
}
}
@CompileStatic
def foo() {
new C() +<caret> 1
}
@@ -0,0 +1,11 @@
import groovy.transform.CompileStatic
class C {
def plus(String s) {
}
}
@CompileStatic
def foo() {
new C() + (1 as String)
}
@@ -3,13 +3,13 @@ class A {
Inner() {}
def foo() {
new Inner() // correct
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A, A)'">(new A())</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A)'">(new A())</warning> // incorrect
}
}
def foo() {
new Inner() //correct
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A, A)'">(new A())</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A)'">(new A())</warning> // incorrect
}
static def bar() {
@@ -4,10 +4,10 @@ class A {
}
def foo() {
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A)'">()</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A, A)'">(new A())</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '()'">()</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A)'">(new A())</warning> // incorrect
new Inner("") // correct
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A, A, java.lang.String)'">(new A(), "")</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A, java.lang.String)'">(new A(), "")</warning> // incorrect
}
static def bar() {
@@ -4,9 +4,9 @@ class A {
}
def foo() {
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A)'">()</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '()'">()</warning> // incorrect
new Inner(new A()) // correct
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A, A, A)'">(new A(), new A())</warning> // incorrect
new Inner<warning descr="Constructor 'Inner' in 'A.Inner' cannot be applied to '(A, A)'">(new A(), new A())</warning> // incorrect
}
static def bar() {