Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Intellij Community
Commits
70379901
Commit
70379901
authored
6 years ago
by
Daniil Ovchinnikov
Browse files
Options
Download
Email Patches
Plain Diff
[groovy] resolve r-value references separately from method calls
parent
53b07cf9
Branches unavailable
Tags unavailable
No related merge requests found
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionReference.kt
+41
-1
.../statements/expressions/GrReferenceExpressionReference.kt
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/psiUtil.kt
+2
-0
...src/org/jetbrains/plugins/groovy/lang/psi/util/psiUtil.kt
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.kt
+18
-8
.../org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.kt
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/AccessorAwareResolverProcessor.kt
+76
-0
...lang/resolve/processors/AccessorAwareResolverProcessor.kt
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/GroovyRValueProcessor.kt
+24
-0
...s/groovy/lang/resolve/processors/GroovyRValueProcessor.kt
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/KindsResolverProcessor.kt
+60
-0
.../groovy/lang/resolve/processors/KindsResolverProcessor.kt
with
221 additions
and
9 deletions
+221
-9
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionReference.kt
+
41
-
1
View file @
70379901
// Copyright 2000-2018 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.impl.statements.expressions
import
org.jetbrains.plugins.groovy.lang.psi.GroovyElementTypes
import
org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult
import
org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall
import
org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
import
org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrSuperReferenceResolver.resolveSuperExpression
import
org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrThisReferenceResolver.resolveThisExpression
import
org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil
import
org.jetbrains.plugins.groovy.lang.resolve.GrReferenceResolveRunner
import
org.jetbrains.plugins.groovy.lang.resolve.api.GroovyCachingReference
import
org.jetbrains.plugins.groovy.lang.resolve.processors.GroovyRValueProcessor
import
org.jetbrains.plugins.groovy.lang.resolve.processors.GroovyResolveKind.*
import
java.util.*
abstract
class
GrReferenceExpressionReference
(
ref
:
GrReferenceExpressionImpl
)
:
GroovyCachingReference
<
GrReferenceExpressionImpl
>(
ref
)
{
...
...
@@ -20,7 +30,24 @@ abstract class GrReferenceExpressionReference(ref: GrReferenceExpressionImpl) :
class
GrRValueExpressionReference
(
ref
:
GrReferenceExpressionImpl
)
:
GrReferenceExpressionReference
(
ref
)
{
override
fun
doResolveNonStatic
(
incomplete
:
Boolean
):
Collection
<
GroovyResolveResult
>
{
return
element
.
doPolyResolve
(
incomplete
,
true
)
val
expression
=
element
if
(
expression
.
parent
is
GrMethodCall
||
incomplete
)
{
return
expression
.
doPolyResolve
(
incomplete
,
true
)
}
expression
.
handleSpecialCases
()
?.
let
{
return
it
}
val
name
=
expression
.
referenceName
?:
return
emptyList
()
val
kinds
=
if
(
expression
.
isQualified
)
{
EnumSet
.
of
(
FIELD
,
PROPERTY
,
VARIABLE
)
}
else
{
EnumSet
.
of
(
FIELD
,
PROPERTY
,
VARIABLE
,
BINDING
)
}
val
processor
=
GroovyRValueProcessor
(
name
,
expression
,
kinds
)
GrReferenceResolveRunner
(
expression
,
processor
).
resolveReferenceExpression
()
return
processor
.
results
}
}
...
...
@@ -30,3 +57,16 @@ class GrLValueExpressionReference(ref: GrReferenceExpressionImpl) : GrReferenceE
return
element
.
doPolyResolve
(
incomplete
,
false
)
}
}
private
fun
GrReferenceExpression
.
handleSpecialCases
():
Collection
<
GroovyResolveResult
>?
{
when
(
referenceNameElement
?.
node
?.
elementType
)
{
GroovyElementTypes
.
KW_THIS
->
return
resolveThisExpression
(
this
)
GroovyElementTypes
.
KW_SUPER
->
return
resolveSuperExpression
(
this
)
GroovyElementTypes
.
KW_CLASS
->
{
if
(!
PsiUtil
.
isCompileStatic
(
this
)
&&
qualifier
?.
type
==
null
)
{
return
emptyList
()
}
}
}
return
null
}
This diff is collapsed.
Click to expand it.
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/psiUtil.kt
+
2
-
0
View file @
70379901
...
...
@@ -47,3 +47,5 @@ fun GrExpression?.isThisExpression(): Boolean {
fun
GrOperatorExpression
.
multiResolve
():
Array
<
out
GroovyResolveResult
>
{
return
reference
?.
multiResolve
(
false
)
?:
GroovyResolveResult
.
EMPTY_ARRAY
}
fun
elementInfo
(
element
:
PsiElement
):
String
=
"Element: $element; class: ${element.javaClass}; text: ${element.text}"
This diff is collapsed.
Click to expand it.
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.kt
+
18
-
8
View file @
70379901
...
...
@@ -21,11 +21,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement
import
org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner
import
org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
import
org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.DefaultConstructor
import
org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrBindingVariable
import
org.jetbrains.plugins.groovy.lang.psi.util.skipSameTypeParents
import
org.jetbrains.plugins.groovy.lang.resolve.api.GroovyProperty
import
org.jetbrains.plugins.groovy.lang.resolve.imports.importedNameKey
import
org.jetbrains.plugins.groovy.lang.resolve.processors.DynamicMembersHint
import
org.jetbrains.plugins.groovy.lang.resolve.processors.GroovyResolveKind
import
org.jetbrains.plugins.groovy.lang.resolve.processors.GroovyResolverProcessor
val
log
:
Logger
=
logger
(
::
log
)
...
...
@@ -74,9 +75,9 @@ fun PsiScopeProcessor.shouldProcessLocals(): Boolean = shouldProcess(GroovyResol
fun
PsiScopeProcessor
.
shouldProcessFields
():
Boolean
=
shouldProcess
(
GroovyResolveKind
.
FIELD
)
fun
PsiScopeProcessor
.
shouldProcessMethods
():
Boolean
{
return
ResolveUtil
.
shouldProcessMethods
(
getHint
(
ElementClassHint
.
KEY
))
}
fun
PsiScopeProcessor
.
shouldProcessMethods
():
Boolean
=
shouldProcess
(
GroovyResolveKind
.
METHOD
)
fun
PsiScopeProcessor
.
shouldProcessProperties
():
Boolean
=
shouldProcess
(
GroovyResolveKind
.
PROPERTY
)
fun
PsiScopeProcessor
.
shouldProcessClasses
():
Boolean
{
return
ResolveUtil
.
shouldProcessClasses
(
getHint
(
ElementClassHint
.
KEY
))
...
...
@@ -95,10 +96,6 @@ fun PsiScopeProcessor.shouldProcessTypeParameters(): Boolean {
return
groovyKindHint
.
shouldProcess
(
GroovyResolveKind
.
TYPE_PARAMETER
)
}
fun
PsiScopeProcessor
.
shouldProcessProperties
():
Boolean
{
return
this
is
GroovyResolverProcessor
&&
isPropertyResolve
}
private
fun
PsiScopeProcessor
.
shouldProcess
(
kind
:
GroovyResolveKind
):
Boolean
{
val
resolveKindHint
=
getHint
(
GroovyResolveKind
.
HINT_KEY
)
if
(
resolveKindHint
!=
null
)
return
resolveKindHint
.
shouldProcess
(
kind
)
...
...
@@ -159,3 +156,16 @@ fun valid(allCandidates: Collection<GroovyResolveResult>): List<GroovyResolveRes
fun
singleOrValid
(
allCandidates
:
List
<
GroovyResolveResult
>):
List
<
GroovyResolveResult
>
{
return
if
(
allCandidates
.
size
<=
1
)
allCandidates
else
valid
(
allCandidates
)
}
fun
getResolveKind
(
element
:
PsiNamedElement
):
GroovyResolveKind
?
{
return
when
(
element
)
{
is
PsiClass
->
GroovyResolveKind
.
CLASS
is
PsiPackage
->
GroovyResolveKind
.
PACKAGE
is
PsiMethod
->
GroovyResolveKind
.
METHOD
is
PsiField
->
GroovyResolveKind
.
FIELD
is
GrBindingVariable
->
GroovyResolveKind
.
BINDING
is
PsiVariable
->
GroovyResolveKind
.
VARIABLE
is
GroovyProperty
->
GroovyResolveKind
.
PROPERTY
else
->
null
}
}
This diff is collapsed.
Click to expand it.
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/AccessorAwareResolverProcessor.kt
0 → 100644
+
76
-
0
View file @
70379901
// Copyright 2000-2018 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
import
com.intellij.psi.PsiElement
import
com.intellij.psi.scope.ElementClassHint
import
com.intellij.psi.scope.PsiScopeProcessor
import
com.intellij.util.containers.ContainerUtil
import
org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult
import
org.jetbrains.plugins.groovy.lang.resolve.GrResolverProcessor
import
org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.filterSameSignatureCandidates
import
org.jetbrains.plugins.groovy.lang.resolve.singleOrValid
abstract
class
AccessorAwareResolverProcessor
(
name
:
String
,
place
:
PsiElement
,
kinds
:
Set
<
GroovyResolveKind
>
)
:
KindsResolverProcessor
(
name
,
place
,
kinds
),
GrResolverProcessor
<
GroovyResolveResult
>,
ElementClassHint
,
DynamicMembersHint
,
MultiProcessor
{
init
{
@Suppress
(
"LeakingThis"
)
hint
(
ElementClassHint
.
KEY
,
this
)
@Suppress
(
"LeakingThis"
)
hint
(
DynamicMembersHint
.
KEY
,
this
)
}
final
override
fun
shouldProcessProperties
():
Boolean
=
true
final
override
fun
shouldProcessMethods
():
Boolean
=
false
final
override
fun
shouldProcess
(
kind
:
ElementClassHint
.
DeclarationKind
):
Boolean
{
return
kind
!=
ElementClassHint
.
DeclarationKind
.
METHOD
&&
kinds
.
any
{
kind
in
it
.
declarationKinds
}
}
final
override
fun
getProcessors
():
Collection
<
PsiScopeProcessor
>
=
listOf
(
this
)
+
accessorProcessors
protected
abstract
val
accessorProcessors
:
Collection
<
GrResolverProcessor
<
*
>>
private
val
accessorCandidates
get
()
=
accessorProcessors
.
flatMap
{
it
.
results
}
private
fun
getCandidates
(
kind
:
GroovyResolveKind
):
List
<
GroovyResolveResult
>
{
val
result
=
getCandidate
(
kind
)
?.
let
(
::
listOf
)
?:
emptyList
()
return
if
(
kind
==
GroovyResolveKind
.
PROPERTY
)
result
+
accessorCandidates
else
result
}
final
override
val
results
:
List
<
GroovyResolveResult
>
get
()
{
val
variables
=
getCandidates
(
GroovyResolveKind
.
VARIABLE
)
if
(
variables
.
isNotEmpty
())
{
return
variables
}
val
properties
=
singleOrValid
(
getCandidates
(
GroovyResolveKind
.
PROPERTY
))
if
(!
properties
.
isEmpty
())
{
return
if
(
properties
.
size
<=
1
)
properties
else
ContainerUtil
.
newSmartList
(
properties
[
0
])
}
val
fields
=
getCandidates
(
GroovyResolveKind
.
FIELD
)
if
(!
fields
.
isEmpty
())
{
return
fields
}
if
(
properties
.
isNotEmpty
())
{
return
properties
}
val
bindings
=
getCandidates
(
GroovyResolveKind
.
BINDING
)
if
(
bindings
.
isNotEmpty
())
{
return
bindings
}
// TODO this is used to choose between two same methods from some class and its superclass, which is questionable
return
getAllCandidates
()
+
filterSameSignatureCandidates
(
accessorCandidates
)
}
}
This diff is collapsed.
Click to expand it.
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/GroovyRValueProcessor.kt
0 → 100644
+
24
-
0
View file @
70379901
// Copyright 2000-2018 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
import
com.intellij.lang.java.beans.PropertyKind
import
com.intellij.psi.PsiElement
import
com.intellij.psi.PsiType
import
org.jetbrains.plugins.groovy.lang.psi.util.isPropertyName
import
org.jetbrains.plugins.groovy.lang.resolve.GrResolverProcessor
class
GroovyRValueProcessor
(
name
:
String
,
place
:
PsiElement
,
kinds
:
Set
<
GroovyResolveKind
>
)
:
AccessorAwareResolverProcessor
(
name
,
place
,
kinds
)
{
override
val
accessorProcessors
:
Collection
<
GrResolverProcessor
<
*
>>
=
if
(
name
.
isPropertyName
())
listOf
(
AccessorProcessor
(
name
,
PropertyKind
.
GETTER
,
{
PsiType
.
EMPTY_ARRAY
},
place
),
AccessorProcessor
(
name
,
PropertyKind
.
BOOLEAN_GETTER
,
{
PsiType
.
EMPTY_ARRAY
},
place
)
)
else
{
emptyList
()
}
}
This diff is collapsed.
Click to expand it.
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/processors/KindsResolverProcessor.kt
0 → 100644
+
60
-
0
View file @
70379901
// Copyright 2000-2018 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
import
com.intellij.psi.PsiElement
import
com.intellij.psi.PsiNamedElement
import
com.intellij.psi.ResolveState
import
com.intellij.psi.scope.NameHint
import
com.intellij.psi.scope.ProcessorWithHints
import
com.intellij.util.enumMapOf
import
org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult
import
org.jetbrains.plugins.groovy.lang.psi.util.elementInfo
import
org.jetbrains.plugins.groovy.lang.resolve.BaseGroovyResolveResult
import
org.jetbrains.plugins.groovy.lang.resolve.getName
import
org.jetbrains.plugins.groovy.lang.resolve.getResolveKind
open
class
KindsResolverProcessor
(
protected
val
name
:
String
,
protected
val
place
:
PsiElement
,
protected
val
kinds
:
Set
<
GroovyResolveKind
>
)
:
ProcessorWithHints
(),
NameHint
,
GroovyResolveKind
.
Hint
{
init
{
@Suppress
(
"LeakingThis"
)
hint
(
NameHint
.
KEY
,
this
)
@Suppress
(
"LeakingThis"
)
hint
(
GroovyResolveKind
.
HINT_KEY
,
this
)
}
final
override
fun
getName
(
state
:
ResolveState
):
String
?
=
name
final
override
fun
shouldProcess
(
kind
:
GroovyResolveKind
):
Boolean
=
kind
in
kinds
private
val
candidates
=
enumMapOf
<
GroovyResolveKind
,
GroovyResolveResult
>()
final
override
fun
execute
(
element
:
PsiElement
,
state
:
ResolveState
):
Boolean
{
if
(
element
!
is
PsiNamedElement
)
return
true
require
(
element
.
isValid
)
{
"Invalid element. ${elementInfo(element)}"
}
val
elementName
=
getName
(
state
,
element
)
if
(
name
!=
elementName
)
return
true
val
kind
=
getResolveKind
(
element
)
?:
return
true
if
(
kind
!
in
kinds
)
{
return
true
}
if
(
kind
in
candidates
)
{
return
true
}
candidates
[
kind
]
=
BaseGroovyResolveResult
(
element
,
place
,
state
)
return
true
}
fun
getCandidate
(
kind
:
GroovyResolveKind
):
GroovyResolveResult
?
=
candidates
[
kind
]
fun
getAllCandidates
():
List
<
GroovyResolveResult
>
=
candidates
.
values
.
toList
()
}
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help