preventing NPE
[fedora-idea.git] / plugins / groovy / src / org / jetbrains / plugins / groovy / lang / psi / impl / GrClosureType.java
blobbd756a33c690827db3c56881560c6fb13c95f322
1 /*
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;
19 import com.intellij.openapi.util.Comparing;
20 import com.intellij.pom.java.LanguageLevel;
21 import com.intellij.psi.*;
22 import com.intellij.psi.search.GlobalSearchScope;
23 import org.jetbrains.annotations.NonNls;
24 import org.jetbrains.annotations.NotNull;
25 import org.jetbrains.annotations.Nullable;
26 import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
27 import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
29 /**
30 * @author ven
32 public class GrClosureType extends PsiClassType {
33 private final GlobalSearchScope myScope;
34 @Nullable
35 private final PsiType myReturnType;
36 private final PsiType[] myParameterTypes;
37 private final boolean[] myOptionals;
38 private final PsiManager myManager;
40 private GrClosureType(GlobalSearchScope scope,
41 @Nullable PsiType returnType,
42 PsiType[] parameters,
43 boolean[] optionals,
44 PsiManager manager, LanguageLevel languageLevel) {
45 super(languageLevel);
46 myScope = scope;
47 myReturnType = returnType;
48 myParameterTypes = parameters;
49 myOptionals = optionals;
50 myManager = manager;
53 @Nullable
54 public PsiClass resolve() {
55 return JavaPsiFacade.getInstance(myManager.getProject()).findClass(GrClosableBlock.GROOVY_LANG_CLOSURE, getResolveScope());
58 @Nullable
59 public PsiType getClosureReturnType() {
60 return myReturnType;
63 public PsiType[] getClosureParameterTypes() {
64 return myParameterTypes;
67 public boolean isOptionalParameter(int parameterIndex) {
68 return myOptionals[parameterIndex];
71 public String getClassName() {
72 return "Closure";
75 @NotNull
76 public PsiType[] getParameters() {
77 //todo
78 return PsiType.EMPTY_ARRAY;
81 @NotNull
82 public ClassResolveResult resolveGenerics() {
83 return new ClassResolveResult() {
84 public PsiClass getElement() {
85 return resolve();
88 public PsiSubstitutor getSubstitutor() {
89 return PsiSubstitutor.UNKNOWN;
92 public boolean isPackagePrefixPackageReference() {
93 return false;
96 public boolean isAccessible() {
97 return true;
100 public boolean isStaticsScopeCorrect() {
101 return true;
104 public PsiElement getCurrentFileResolveScope() {
105 return null;
108 public boolean isValidResult() {
109 return isStaticsScopeCorrect() && isAccessible();
114 @NotNull
115 public PsiClassType rawType() {
116 return this;
119 public String getPresentableText() {
120 return "Closure";
123 @Nullable
124 public String getCanonicalText() {
125 PsiClass resolved = resolve();
126 if (resolved == null) return null;
127 return resolved.getQualifiedName();
130 public String getInternalCanonicalText() {
131 return getCanonicalText();
134 public boolean isValid() {
135 if (myParameterTypes.length > 0 && !myParameterTypes[0].isValid()) return false;
136 return myReturnType == null || myReturnType.isValid();
139 public boolean equals(Object obj) {
140 if (obj instanceof GrClosureType) {
141 GrClosureType other = (GrClosureType)obj;
142 if (!Comparing.equal(myReturnType, other.myReturnType)) return false;
143 if (myParameterTypes.length != other.myParameterTypes.length) return false;
144 for (int i = 0; i < myParameterTypes.length; i++) {
145 if (myOptionals[i] != other.myOptionals[i]) return false;
146 if (!other.myParameterTypes[i].equals(myParameterTypes[i])) return false;
148 return true;
151 return super.equals(obj);
154 public boolean isAssignableFrom(@NotNull PsiType type) {
155 if (type instanceof GrClosureType) {
156 GrClosureType other = (GrClosureType)type;
157 if (myReturnType == null || other.myReturnType == null) {
158 return myReturnType == null && other.myReturnType == null;
160 if (!myReturnType.isAssignableFrom(other.myReturnType)) return false;
161 if (myParameterTypes.length != other.myParameterTypes.length) return false;
162 for (int i = 0; i < myParameterTypes.length; i++) {
163 if (myOptionals[i] != other.myOptionals[i]) return false;
164 if (!other.myParameterTypes[i].isAssignableFrom(myParameterTypes[i])) return false;
166 return true;
168 return super.isAssignableFrom(type);
171 public boolean equalsToText(@NonNls String text) {
172 return text.equals(GrClosableBlock.GROOVY_LANG_CLOSURE);
175 @NotNull
176 public GlobalSearchScope getResolveScope() {
177 return myScope;
180 @NotNull
181 public LanguageLevel getLanguageLevel() {
182 return myLanguageLevel;
185 public PsiClassType setLanguageLevel(final LanguageLevel languageLevel) {
186 return create(myReturnType, myParameterTypes, myOptionals, myManager, myScope, languageLevel);
189 public static GrClosureType create(GrClosableBlock closure) {
190 return create(closure.getResolveScope(), closure.getReturnType(), closure.getAllParameters(), closure.getManager());
193 public static GrClosureType create(GlobalSearchScope scope, PsiType returnType, PsiParameter[] parameters, PsiManager manager) {
194 PsiType[] parameterTypes = new PsiType[parameters.length];
195 boolean[] optionals = new boolean[parameters.length];
196 for (int i = 0; i < optionals.length; i++) {
197 PsiParameter parameter = parameters[i];
198 if (parameter instanceof GrParameter) {
199 optionals[i] = ((GrParameter)parameter).isOptional();
200 } else if (i == 0) { // for implicit "it" parameter
201 optionals[i] = true;
202 } else {
203 optionals[i] = false;
205 parameterTypes[i] = parameter.getType();
207 return create(returnType, parameterTypes, optionals, manager, scope, LanguageLevel.JDK_1_5);
210 public static GrClosureType create(PsiType returnType,
211 PsiType[] parameterTypes,
212 boolean[] optionals,
213 PsiManager manager,
214 GlobalSearchScope scope, LanguageLevel languageLevel) {
215 return new GrClosureType(scope, returnType, parameterTypes, optionals, manager,languageLevel);
218 @Nullable
219 public PsiType curry(int num) {
220 if (num > myParameterTypes.length) return null;
221 PsiType[] newParameterTypes = new PsiType[myParameterTypes.length - num];
222 boolean[] newOptionals = new boolean[myParameterTypes.length - num];
223 System.arraycopy(myParameterTypes, num, newParameterTypes, 0, newParameterTypes.length);
224 System.arraycopy(myOptionals, num, newOptionals, 0, newOptionals.length);
225 return create(myReturnType, newParameterTypes, newOptionals, myManager, myScope, myLanguageLevel);