2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org
.jetbrains
.plugins
.groovy
.lang
.psi
.impl
.statements
.arguments
;
19 import com
.intellij
.lang
.ASTNode
;
20 import com
.intellij
.openapi
.util
.TextRange
;
21 import com
.intellij
.psi
.*;
22 import com
.intellij
.psi
.impl
.source
.resolve
.reference
.ReferenceProvidersRegistry
;
23 import com
.intellij
.psi
.impl
.source
.resolve
.reference
.impl
.PsiMultiReference
;
24 import com
.intellij
.psi
.util
.PropertyUtil
;
25 import com
.intellij
.util
.ArrayUtil
;
26 import com
.intellij
.util
.IncorrectOperationException
;
27 import org
.jetbrains
.annotations
.NotNull
;
28 import org
.jetbrains
.annotations
.Nullable
;
29 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.GroovyElementVisitor
;
30 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.GroovyPsiElementFactory
;
31 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.GroovyResolveResult
;
32 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.arguments
.GrArgumentLabel
;
33 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.arguments
.GrArgumentList
;
34 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.arguments
.GrNamedArgument
;
35 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.expressions
.GrExpression
;
36 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.expressions
.path
.GrCallExpression
;
37 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.api
.statements
.typedef
.GrAnonymousClassDefinition
;
38 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.impl
.GroovyPsiElementImpl
;
39 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.util
.GrStringUtil
;
40 import org
.jetbrains
.plugins
.groovy
.lang
.psi
.util
.PsiUtil
;
41 import org
.jetbrains
.plugins
.groovy
.lang
.resolve
.ResolveUtil
;
42 import org
.jetbrains
.plugins
.groovy
.lang
.resolve
.processors
.PropertyResolverProcessor
;
47 public class GrArgumentLabelImpl
extends GroovyPsiElementImpl
implements GrArgumentLabel
{
49 public GrArgumentLabelImpl(@NotNull ASTNode node
) {
53 public void accept(GroovyElementVisitor visitor
) {
54 visitor
.visitArgumentLabel(this);
57 public String
toString() {
58 return "Argument label";
61 public PsiReference
getReference() {
62 PsiReference
[] otherReferences
= ReferenceProvidersRegistry
.getReferencesFromProviders(this, GrArgumentLabel
.class);
63 PsiReference
[] thisReference
= {this};
64 return new PsiMultiReference(otherReferences
.length
== 0 ? thisReference
: ArrayUtil
.mergeArrays(thisReference
, otherReferences
, PsiReference
.class), this);
68 public String
getName() {
69 final PsiElement element
= getNameElement();
70 if (element
instanceof GrExpression
) {
74 return GrStringUtil
.removeQuotes(element
.getText());
78 public PsiElement
getElement() {
82 public TextRange
getRangeInElement() {
83 return new TextRange(0, getTextLength());
87 public PsiElement
resolve() {
88 String propName
= getText();
89 String setterName
= PropertyUtil
.suggestSetterName(propName
);
90 PsiElement context
= getParent().getParent();
91 if (context
instanceof GrArgumentList
) {
92 final PsiElement parent
= context
.getParent();
93 if (parent
instanceof GrCallExpression
) {
94 final PsiMethod resolvedMethod
= ((GrCallExpression
) parent
).resolveMethod();
95 if (resolvedMethod
!= null) {
96 final PsiParameter
[] parameters
= resolvedMethod
.getParameterList().getParameters();
97 if (parameters
.length
> 0) {
98 if (PsiUtil
.createMapType(resolvedMethod
.getManager(), resolvedMethod
.getResolveScope()).isAssignableFrom(parameters
[0].getType())) {
99 //call with named argument, not setting property
106 if (parent
instanceof GrExpression
|| parent
instanceof GrAnonymousClassDefinition
) {
108 parent
instanceof GrExpression ?
((GrExpression
)parent
).getType() : ((GrAnonymousClassDefinition
)parent
).getBaseClassType();
109 if (type
instanceof PsiClassType
) {
110 PsiClass clazz
= ((PsiClassType
) type
).resolve();
112 PsiMethod
[] byName
= clazz
.findMethodsByName(setterName
, true);
113 if (byName
.length
> 0) return byName
[0];
114 final PsiField field
= clazz
.findFieldByName(propName
, true);
115 if (field
!= null) return field
;
116 final PropertyResolverProcessor processor
= new PropertyResolverProcessor(propName
, this);
118 .processNonCodeMethods(JavaPsiFacade
.getElementFactory(getProject()).createType(clazz
), processor
, getProject(), this, false);
119 final GroovyResolveResult
[] candidates
= processor
.getCandidates();
120 if (candidates
.length
== 0) return null;
121 return candidates
[0].getElement();
129 public String
getCanonicalText() {
130 PsiElement resolved
= resolve();
131 if (resolved
instanceof PsiMember
&& resolved
instanceof PsiNamedElement
) {
132 PsiClass clazz
= ((PsiMember
) resolved
).getContainingClass();
134 String qName
= clazz
.getQualifiedName();
136 return qName
+ "." + ((PsiNamedElement
) resolved
).getName();
144 public PsiElement
handleElementRename(String newElementName
) throws IncorrectOperationException
{
145 final PsiElement resolved
= resolve();
146 if (resolved
instanceof PsiMethod
) {
147 final PsiMethod method
= (PsiMethod
) resolved
;
148 final String oldName
= getNameElement().getText();
149 if (!method
.getName().equals(oldName
)) { //was property reference to accessor
150 if (PropertyUtil
.isSimplePropertySetter(method
)) {
151 final String newPropertyName
= PropertyUtil
.getPropertyName(newElementName
);
152 if (newPropertyName
!= null) {
153 return doHandleElementRename(newPropertyName
);
155 //todo encapsulate fields:)
160 return doHandleElementRename(newElementName
);
163 private PsiElement
doHandleElementRename(String newElementName
) {
164 PsiElement nameElement
= getNameElement();
165 ASTNode node
= nameElement
.getNode();
166 ASTNode newNameNode
= GroovyPsiElementFactory
.getInstance(getProject()).createReferenceNameFromText(newElementName
).getNode();
167 assert newNameNode
!= null && node
!= null;
168 node
.getTreeParent().replaceChild(node
, newNameNode
);
172 public PsiElement
bindToElement(@NotNull PsiElement element
) throws IncorrectOperationException
{
173 throw new IncorrectOperationException("NIY");
176 public boolean isReferenceTo(PsiElement element
) {
177 return (element
instanceof PsiMethod
|| element
instanceof PsiField
) &&
178 getManager().areElementsEquivalent(element
, resolve());
183 public Object
[] getVariants() {
184 return ArrayUtil
.EMPTY_OBJECT_ARRAY
;
187 public boolean isSoft() {
192 public PsiElement
getNameElement() {
193 final PsiElement element
= getFirstChild();
194 assert element
!= null;
199 public PsiType
getExpectedArgumentType() {
200 final PsiElement resolved
= resolve();
201 if (resolved
instanceof PsiMethod
) {
202 final PsiMethod method
= (PsiMethod
) resolved
;
203 if (PropertyUtil
.isSimplePropertyGetter(method
))
204 return method
.getReturnType();
205 if (PropertyUtil
.isSimplePropertySetter(method
))
206 return method
.getParameterList().getParameters()[0].getType();
208 } else if (resolved
instanceof PsiField
) {
209 return ((PsiField
) resolved
).getType();
215 public GrNamedArgument
getNamedArgument() {
216 final PsiElement parent
= getParent();
217 assert parent
instanceof GrNamedArgument
;
218 return (GrNamedArgument
)parent
;