cleanup
[idea/community.git] / java / java-impl / src / com / intellij / util / xml / CanonicalPsiTypeConverterImpl.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.util.xml;
17
18 import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
19 import com.intellij.openapi.util.TextRange;
20 import com.intellij.openapi.util.UserDataCache;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.psi.*;
23 import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReference;
24 import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider;
25 import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceSet;
26 import com.intellij.psi.infos.CandidateInfo;
27 import com.intellij.psi.scope.PsiScopeProcessor;
28 import com.intellij.util.ArrayUtil;
29 import com.intellij.util.IncorrectOperationException;
30 import org.jetbrains.annotations.NonNls;
31 import org.jetbrains.annotations.NotNull;
32
33 /**
34  * @author peter
35 */
36 public class CanonicalPsiTypeConverterImpl extends CanonicalPsiTypeConverter implements CustomReferenceConverter<PsiType> {
37
38   private static final UserDataCache<JavaClassReferenceProvider, Project, Object> REFERENCE_PROVIDER = new UserDataCache<JavaClassReferenceProvider, Project, Object>("CanonicalPsiTypeConverterImpl") {
39     @Override
40     protected JavaClassReferenceProvider compute(Project project, Object p) {
41       return new JavaClassReferenceProvider(project);
42     }
43   };
44
45   @NonNls private static final String[] PRIMITIVES = new String[]{"boolean", "byte",
46     "char", "double", "float", "int", "long", "short"};
47   @NonNls private static final String ARRAY_PREFIX = "[L";
48
49   public PsiType fromString(final String s, final ConvertContext context) {
50     if (s == null) return null;
51     try {
52       return JavaPsiFacade.getInstance(context.getFile().getProject()).getElementFactory().createTypeFromText(s.replace('$', '.'), null);
53     }
54     catch (IncorrectOperationException e) {
55       return null;
56     }
57   }
58
59   public String toString(final PsiType t, final ConvertContext context) {
60     return t == null? null:t.getCanonicalText();
61   }
62
63   @NotNull
64   public PsiReference[] createReferences(final GenericDomValue<PsiType> genericDomValue, final PsiElement element, ConvertContext context) {
65     final String str = genericDomValue.getStringValue();
66     if (str != null) {
67       final ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(element);
68       assert manipulator != null;
69       String trimmed = str.trim();
70       int offset = manipulator.getRangeInElement(element).getStartOffset() + str.indexOf(trimmed);
71       if (trimmed.startsWith(ARRAY_PREFIX)) {
72         offset += ARRAY_PREFIX.length();
73         if (trimmed.endsWith(";")) {
74           trimmed = trimmed.substring(ARRAY_PREFIX.length(), trimmed.length() - 1);
75         } else {
76           trimmed = trimmed.substring(ARRAY_PREFIX.length());          
77         }
78       }
79       return new JavaClassReferenceSet(trimmed, element, offset, false, REFERENCE_PROVIDER.get(genericDomValue.getManager().getProject(), null)) {
80         protected JavaClassReference createReference(final int referenceIndex, final String subreferenceText, final TextRange textRange,
81                                                      final boolean staticImport) {
82           return new JavaClassReference(this, textRange, referenceIndex, subreferenceText, staticImport) {
83             public boolean isSoft() {
84               return true;
85             }
86
87             @NotNull
88             public JavaResolveResult advancedResolve(final boolean incompleteCode) {
89               PsiType type = genericDomValue.getValue();
90               if (type != null) {
91                 type = type.getDeepComponentType();
92               }
93               if (type instanceof PsiPrimitiveType) {
94                 return new CandidateInfo(element, PsiSubstitutor.EMPTY, false, false, element);
95               }
96
97               return super.advancedResolve(incompleteCode);
98             }
99
100             public void processVariants(final PsiScopeProcessor processor) {
101               if (processor instanceof JavaCompletionProcessor) {
102                 ((JavaCompletionProcessor)processor).setCompletionElements(getVariants());
103               } else {
104                 super.processVariants(processor);
105               }
106             }
107
108             @NotNull
109             public Object[] getVariants() {
110               final Object[] variants = super.getVariants();
111               if (myIndex == 0) {
112                 return ArrayUtil.mergeArrays(variants, PRIMITIVES, Object.class);
113               }
114               return variants;
115             }
116           };
117         }
118       }.getAllReferences();
119     }
120     return PsiReference.EMPTY_ARRAY;
121   }
122 }