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.
16 package com
.intellij
.codeInsight
.daemon
.impl
.quickfix
;
18 import com
.intellij
.psi
.*;
19 import org
.jetbrains
.annotations
.Nullable
;
21 import java
.util
.HashMap
;
24 public class DeclarationSearcher
{
25 private final PsiMethod myMethod
;
26 private final PsiType myTargetType
;
28 private final Map
<PsiElement
, PsiVariable
> cache
;
30 public DeclarationSearcher(final PsiMethod method
, final PsiType targetType
) {
32 myTargetType
= targetType
;
34 cache
= new HashMap
<PsiElement
, PsiVariable
>();
38 public PsiVariable
getDeclaration(final PsiElement endPositionElement
) {
39 final PsiVariable localVariable
= getLocalDeclaration(endPositionElement
);
40 if (localVariable
!= null) {
43 return getParameterDeclaration();
47 private PsiVariable
getParameterDeclaration() {
48 for (PsiParameter parameter
: myMethod
.getParameterList().getParameters()) {
49 if (myTargetType
.equals(parameter
.getType())) {
50 return goThroughCache(myMethod
, parameter
);
57 private PsiVariable
getLocalDeclaration(final PsiElement endPositionElement
) {
58 final PsiElement parent
= endPositionElement
.getParent();
60 // reuse of cache is possible IF requests are done up-to-down. otherwise - not first declaration can be returned
61 final PsiVariable cachedCandidate
= cache
.get(parent
);
62 if (cachedCandidate
!= null) {
63 return cachedCandidate
;
66 if (parent
!= myMethod
) {
68 final PsiVariable parentResult
= getLocalDeclaration(parent
);
69 if (parentResult
!= null) {
75 for (PsiElement element
: parent
.getChildren()) {
76 if (element
== endPositionElement
) {
79 if (element
instanceof PsiDeclarationStatement
) {
80 final PsiElement
[] declared
= ((PsiDeclarationStatement
) element
).getDeclaredElements();
81 for (final PsiElement declaredElement
: declared
) {
82 if ((declaredElement
instanceof PsiLocalVariable
) && (myTargetType
.equals(((PsiLocalVariable
)declaredElement
).getType()))) {
83 return goThroughCache(parent
, (PsiVariable
) declaredElement
);
86 } else if (element
instanceof PsiParameter
) {
88 if (myTargetType
.equals(((PsiParameter
) element
).getType())) {
89 return goThroughCache(parent
, (PsiVariable
) element
);
97 private PsiVariable
goThroughCache(final PsiElement parent
, final PsiVariable variable
) {
98 cache
.put(parent
, variable
);