mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] IDEA-242412 support generic type inference for method references
GitOrigin-RevId: 938c5511189a2b3a78497fd1fe207fd3898f2850
This commit is contained in:
committed by
intellij-monorepo-bot
parent
51ada9381a
commit
1a1a2b05a6
+7
-5
@@ -1,12 +1,13 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.lang.psi.typeEnhancers;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.ConversionResult;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.inference.GrConstraintFormula;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -42,9 +43,10 @@ public class GrStringConverter extends GrTypeConverter {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Collection<GrConstraintFormula> reduceTypeConstraint(@NotNull PsiType leftType,
|
||||
@NotNull PsiType rightType,
|
||||
@NotNull Position position) {
|
||||
public Collection<ConstraintFormula> reduceTypeConstraint(@NotNull PsiType leftType,
|
||||
@NotNull PsiType rightType,
|
||||
@NotNull Position position,
|
||||
@NotNull PsiElement context) {
|
||||
if (position == Position.METHOD_PARAMETER &&
|
||||
isClassType(leftType, JAVA_LANG_STRING) &&
|
||||
isClassType(rightType, GROOVY_LANG_GSTRING)) {
|
||||
|
||||
+8
-5
@@ -1,8 +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.
|
||||
// Copyright 2000-2020 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.lang.psi.typeEnhancers;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
@@ -13,7 +15,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrTypeCastExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.ConversionResult;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.inference.GrConstraintFormula;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -59,12 +60,14 @@ public abstract class GrTypeConverter {
|
||||
@NotNull GroovyPsiElement context);
|
||||
|
||||
@Nullable
|
||||
public Collection<GrConstraintFormula> reduceTypeConstraint(@NotNull PsiType leftType,
|
||||
@NotNull PsiType rightType,
|
||||
@NotNull Position position) {
|
||||
public Collection<ConstraintFormula> reduceTypeConstraint(@NotNull PsiType leftType,
|
||||
@NotNull PsiType rightType,
|
||||
@NotNull Position position,
|
||||
@NotNull PsiElement context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public enum Position {
|
||||
EXPLICIT_CAST,
|
||||
ASSIGNMENT,
|
||||
|
||||
+5
-90
@@ -1,20 +1,13 @@
|
||||
// Copyright 2000-2020 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.lang.resolve.processors.inference
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.PsiClassType.ClassResolveResult
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil.getNonWildcardParameterization
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GrFunctionalExpression
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrTypeConverter.Position.METHOD_PARAMETER
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.api.Applicability
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.api.ExplicitRuntimeTypeArgument
|
||||
import org.jetbrains.plugins.groovy.lang.sam.findSingleAbstractMethod
|
||||
import org.jetbrains.plugins.groovy.lang.sam.isSamConversionAllowed
|
||||
import org.jetbrains.plugins.groovy.lang.sam.processSAMConversion
|
||||
import org.jetbrains.plugins.groovy.lang.typing.GroovyClosureType
|
||||
|
||||
class FunctionalExpressionConstraint(private val expression: GrFunctionalExpression,
|
||||
@@ -34,87 +27,9 @@ class FunctionalExpressionConstraint(private val expression: GrFunctionalExpress
|
||||
constraints.add(TypeConstraint(parameters[0], returnType, expression))
|
||||
}
|
||||
else {
|
||||
processSAMConversion(constraints)
|
||||
val closureType = expression.type as? GroovyClosureType ?: return true
|
||||
constraints += processSAMConversion(leftType, closureType, expression)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun processSAMConversion(constraints: MutableList<in ConstraintFormula>) {
|
||||
val pair = getSingleAbstractMethod()
|
||||
if (pair == null) {
|
||||
constraints.add(TypeConstraint(leftType, TypesUtil.createTypeByFQClassName(GROOVY_LANG_CLOSURE, expression), expression))
|
||||
return
|
||||
}
|
||||
val (sam, classResolveResult) = pair
|
||||
|
||||
val groundClass = classResolveResult.element ?: return
|
||||
val groundType = groundTypeForExplicitlyTypedClosure(sam, groundClass)
|
||||
|
||||
if (groundType != null) {
|
||||
constraints.add(TypeConstraint(leftType, groundType, expression))
|
||||
}
|
||||
|
||||
val samReturnType = classResolveResult.substitutor.substitute(sam.returnType)
|
||||
if (samReturnType == null || samReturnType == PsiType.VOID) {
|
||||
return
|
||||
}
|
||||
val returnType = expression.returnType
|
||||
if (returnType == null) {
|
||||
return
|
||||
}
|
||||
|
||||
constraints.add(TypeConstraint(samReturnType, returnType, expression))
|
||||
}
|
||||
|
||||
private fun getSingleAbstractMethod(): Pair<PsiMethod, ClassResolveResult>? {
|
||||
if (!isSamConversionAllowed(expression)) return null
|
||||
val groundType = (leftType as? PsiClassType)?.let { getNonWildcardParameterization(it) } ?: return null
|
||||
val resolveResult = (groundType as PsiClassType).resolveGenerics()
|
||||
|
||||
val samClass = resolveResult.element ?: return null
|
||||
|
||||
val sam = findSingleAbstractMethod(samClass) ?: return null
|
||||
return sam to resolveResult
|
||||
}
|
||||
|
||||
/**
|
||||
* JLS 18.5.3
|
||||
* com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil.getFunctionalTypeExplicit
|
||||
*/
|
||||
private fun groundTypeForExplicitlyTypedClosure(sam: PsiMethod, groundClass: PsiClass): PsiClassType? {
|
||||
if (!Registry.`is`("groovy.use.explicitly.typed.closure.in.inference", true)) return null
|
||||
val closureType = expression.type as? GroovyClosureType ?: return null
|
||||
val parameters = expression.parameters
|
||||
val types = parameters.map { it.declaredType }
|
||||
if (types.filterNotNull().isEmpty()) return null // implicitly typed Closure
|
||||
|
||||
val typeParameters = groundClass.typeParameters ?: return null
|
||||
if (typeParameters.isEmpty()) return null
|
||||
|
||||
val samContainingClass = sam.containingClass ?: return null
|
||||
val groundClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(samContainingClass, groundClass, PsiSubstitutor.EMPTY)
|
||||
|
||||
// erase all ground class parameters to null, otherwise explicit closure signature will be inapplicable
|
||||
val erasingSubstitutor = PsiSubstitutor.createSubstitutor(typeParameters.associate { it to PsiType.NULL })
|
||||
val samParameterTypes = sam.parameterList.parameters.map { it.type }
|
||||
val arguments = samParameterTypes.map {
|
||||
val withInheritance = groundClassSubstitutor.substitute(it)
|
||||
ExplicitRuntimeTypeArgument(withInheritance, TypeConversionUtil.erasure(erasingSubstitutor.substitute(withInheritance)))
|
||||
}
|
||||
|
||||
val argumentMapping = closureType.applyTo(arguments).find { it.applicability() == Applicability.applicable } ?: return null
|
||||
|
||||
val samSession = GroovyInferenceSession(typeParameters, PsiSubstitutor.EMPTY, expression)
|
||||
argumentMapping.expectedTypes.forEach { (expectedType, argument) ->
|
||||
val leftType = samSession.substituteWithInferenceVariables(groundClassSubstitutor.substitute(expectedType))
|
||||
samSession.addConstraint(TypePositionConstraint(ExpectedType(leftType, METHOD_PARAMETER), argument.type, expression))
|
||||
}
|
||||
if (!samSession.repeatInferencePhases()) {
|
||||
return null
|
||||
}
|
||||
val resultSubstitutor = samSession.result()
|
||||
|
||||
val elementFactory = JavaPsiFacade.getElementFactory(expression.project)
|
||||
return elementFactory.createType(groundClass, resultSubstitutor)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2020 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.lang.resolve.processors.inference
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -18,7 +18,7 @@ class TypePositionConstraint(
|
||||
if (!extension.isApplicableTo(expectedType.position)) {
|
||||
continue
|
||||
}
|
||||
val reduced = extension.reduceTypeConstraint(expectedType.type, rightType, expectedType.position)
|
||||
val reduced = extension.reduceTypeConstraint(expectedType.type, rightType, expectedType.position, context)
|
||||
if (reduced != null) {
|
||||
constraints += reduced
|
||||
return true
|
||||
|
||||
+10
@@ -2,7 +2,9 @@
|
||||
package org.jetbrains.plugins.groovy.lang.sam
|
||||
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.ConversionResult
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
|
||||
@@ -35,4 +37,12 @@ class ClosureToSamConverter : GrTypeConverter() {
|
||||
findSingleAbstractSignature(targetClass) ?: return null
|
||||
return ConversionResult.OK
|
||||
}
|
||||
|
||||
override fun reduceTypeConstraint(leftType: PsiType,
|
||||
rightType: PsiType,
|
||||
position: Position,
|
||||
context: PsiElement): List<ConstraintFormula>? {
|
||||
if (rightType !is GroovyClosureType) return null
|
||||
return processSAMConversion(leftType, rightType, context)
|
||||
}
|
||||
}
|
||||
|
||||
+99
-15
@@ -1,33 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// Copyright 2000-2020 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.lang.sam
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.MethodSignature
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import org.jetbrains.plugins.groovy.config.GroovyConfigUtils
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrTypeConverter
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil.isTrait
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.api.Applicability
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.api.ExplicitRuntimeTypeArgument
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.inference.*
|
||||
import org.jetbrains.plugins.groovy.lang.typing.GroovyClosureType
|
||||
|
||||
fun findSingleAbstractMethod(clazz: PsiClass): PsiMethod? = findSingleAbstractSignatureCached(clazz)?.method
|
||||
|
||||
fun findSingleAbstractSignature(clazz: PsiClass): MethodSignature? = findSingleAbstractSignatureCached(clazz)
|
||||
|
||||
private fun findSingleAbstractMethodAndClass(type: PsiType): Pair<PsiMethod, PsiClassType.ClassResolveResult>? {
|
||||
val groundType = (type as? PsiClassType)?.let { FunctionalInterfaceParameterizationUtil.getNonWildcardParameterization(it) }
|
||||
?: return null
|
||||
val resolveResult = (groundType as PsiClassType).resolveGenerics()
|
||||
|
||||
val samClass = resolveResult.element ?: return null
|
||||
|
||||
val sam = findSingleAbstractMethod(samClass) ?: return null
|
||||
return sam to resolveResult
|
||||
}
|
||||
|
||||
private fun findSingleAbstractSignatureCached(clazz: PsiClass): HierarchicalMethodSignature? {
|
||||
return CachedValuesManager.getCachedValue(clazz) {
|
||||
CachedValueProvider.Result.create(doFindSingleAbstractSignature(clazz), clazz)
|
||||
@@ -68,3 +76,79 @@ private fun isImplementedTraitMethod(method: PsiMethod): Boolean {
|
||||
fun isSamConversionAllowed(context: PsiElement): Boolean {
|
||||
return GroovyConfigUtils.getInstance().isVersionAtLeast(context, GroovyConfigUtils.GROOVY2_2)
|
||||
}
|
||||
|
||||
internal fun processSAMConversion(targetType: PsiType,
|
||||
closureType: GroovyClosureType,
|
||||
context: PsiElement): List<ConstraintFormula> {
|
||||
val constraints = mutableListOf<ConstraintFormula>()
|
||||
val pair = findSingleAbstractMethodAndClass(targetType)
|
||||
if (pair == null) {
|
||||
constraints.add(
|
||||
TypeConstraint(targetType, TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, context), context))
|
||||
return constraints
|
||||
}
|
||||
val (sam, classResolveResult) = pair
|
||||
|
||||
val groundClass = classResolveResult.element ?: return constraints
|
||||
val groundType = groundTypeForClosure(sam, groundClass, closureType, context)
|
||||
|
||||
if (groundType != null) {
|
||||
constraints.add(TypeConstraint(targetType, groundType, context))
|
||||
}
|
||||
return constraints
|
||||
}
|
||||
|
||||
private fun returnTypeConstraint(samReturnType: PsiType?,
|
||||
returnType: PsiType?,
|
||||
context: PsiElement): ConstraintFormula? {
|
||||
if (returnType == null || samReturnType == null || samReturnType == PsiType.VOID) {
|
||||
return null
|
||||
}
|
||||
|
||||
return TypeConstraint(samReturnType, returnType, context)
|
||||
}
|
||||
|
||||
/**
|
||||
* JLS 18.5.3
|
||||
* com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil.getFunctionalTypeExplicit
|
||||
*/
|
||||
private fun groundTypeForClosure(sam: PsiMethod,
|
||||
groundClass: PsiClass,
|
||||
closureType: GroovyClosureType,
|
||||
context: PsiElement): PsiClassType? {
|
||||
if (!Registry.`is`("groovy.use.explicitly.typed.closure.in.inference", true)) return null
|
||||
|
||||
val typeParameters = groundClass.typeParameters ?: return null
|
||||
if (typeParameters.isEmpty()) return null
|
||||
|
||||
val samContainingClass = sam.containingClass ?: return null
|
||||
val groundClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(samContainingClass, groundClass, PsiSubstitutor.EMPTY)
|
||||
|
||||
// erase all ground class parameters to null, otherwise explicit closure signature will be inapplicable
|
||||
val erasingSubstitutor = PsiSubstitutor.createSubstitutor(typeParameters.associate { it to PsiType.NULL })
|
||||
val samParameterTypes = sam.parameterList.parameters.map { it.type }
|
||||
val arguments = samParameterTypes.map {
|
||||
val withInheritance = groundClassSubstitutor.substitute(it)
|
||||
ExplicitRuntimeTypeArgument(withInheritance, TypeConversionUtil.erasure(erasingSubstitutor.substitute(withInheritance)))
|
||||
}
|
||||
|
||||
val argumentMapping = closureType.applyTo(arguments).find { it.applicability() == Applicability.applicable } ?: return null
|
||||
|
||||
val samSession = GroovyInferenceSession(typeParameters, PsiSubstitutor.EMPTY, context, false)
|
||||
argumentMapping.expectedTypes.forEach { (expectedType, argument) ->
|
||||
val leftType = samSession.substituteWithInferenceVariables(groundClassSubstitutor.substitute(expectedType))
|
||||
samSession.addConstraint(
|
||||
TypePositionConstraint(ExpectedType(leftType, GrTypeConverter.Position.METHOD_PARAMETER), argument.type, context))
|
||||
}
|
||||
|
||||
val returnTypeConstraint = returnTypeConstraint(sam.returnType, closureType.returnType(arguments), context)
|
||||
if (returnTypeConstraint != null) samSession.addConstraint(returnTypeConstraint)
|
||||
|
||||
if (!samSession.repeatInferencePhases()) {
|
||||
return null
|
||||
}
|
||||
val resultSubstitutor = samSession.result()
|
||||
|
||||
val elementFactory = JavaPsiFacade.getElementFactory(context.project)
|
||||
return elementFactory.createType(groundClass, resultSubstitutor)
|
||||
}
|
||||
|
||||
+63
-1
@@ -1,9 +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.
|
||||
// Copyright 2000-2020 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.lang.highlighting
|
||||
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.plugins.groovy.GroovyProjectDescriptors
|
||||
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection
|
||||
import org.jetbrains.plugins.groovy.lang.GroovyVersionBasedTest
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
@@ -65,6 +66,58 @@ I i = {3}
|
||||
'''
|
||||
}
|
||||
|
||||
void 'test method reference to SAM conversion'() {
|
||||
highlightingTest '''
|
||||
|
||||
class A {
|
||||
def String m(){
|
||||
|
||||
}
|
||||
}
|
||||
List<A> list = []
|
||||
|
||||
list.sort(Comparator.comparing(A::m))
|
||||
''', GroovyAssignabilityCheckInspection
|
||||
}
|
||||
|
||||
void 'test method reference to SAM conversion 2'() {
|
||||
highlightingTest '''
|
||||
|
||||
class A {
|
||||
def String m(){
|
||||
|
||||
}
|
||||
}
|
||||
List<A> list = []
|
||||
def c = A::m
|
||||
list.sort(Comparator.comparing(c))
|
||||
''', GroovyAssignabilityCheckInspection
|
||||
}
|
||||
|
||||
void 'test method reference to SAM conversion with overload'() {
|
||||
highlightingTest '''
|
||||
class A {
|
||||
String m(Integer i){
|
||||
return null
|
||||
}
|
||||
|
||||
Integer m(Thread i){
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
interface SAM<T> {
|
||||
T m(Integer a);
|
||||
}
|
||||
|
||||
def <T> T foo(SAM<T> sam) {
|
||||
}
|
||||
|
||||
def a = new A()
|
||||
foo(a::m).toUpperCase()
|
||||
''', GrUnresolvedAccessInspection
|
||||
}
|
||||
|
||||
void 'test constructor reference static access'() {
|
||||
fileHighlightingTest GrUnresolvedAccessInspection
|
||||
}
|
||||
@@ -77,3 +130,12 @@ I i = {3}
|
||||
fileHighlightingTest()
|
||||
}
|
||||
}
|
||||
//
|
||||
//class A {
|
||||
// def String m(){
|
||||
//
|
||||
// }
|
||||
//}
|
||||
//List<A> list = []
|
||||
//
|
||||
//list.sort(Comparator.comparing(A::m))
|
||||
|
||||
Reference in New Issue
Block a user