JavaDescriptorResolver.java 78.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright 2010-2012 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

17 18
package org.jetbrains.jet.lang.resolve.java;

19
import com.google.common.collect.Lists;
A
Andrey Breslav 已提交
20
import com.google.common.collect.Maps;
A
Andrey Breslav 已提交
21
import com.google.common.collect.Sets;
22
import com.intellij.openapi.project.Project;
23
import com.intellij.openapi.util.Pair;
24
import com.intellij.openapi.vfs.VirtualFile;
25
import com.intellij.psi.*;
26
import com.intellij.psi.impl.compiled.ClsClassImpl;
27
import com.intellij.psi.search.DelegatingGlobalSearchScope;
28
import com.intellij.psi.search.GlobalSearchScope;
29
import jet.typeinfo.TypeInfoVariance;
30 31
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
32
import org.jetbrains.jet.lang.descriptors.*;
A
Andrey Breslav 已提交
33
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
34
import org.jetbrains.jet.lang.psi.JetPsiUtil;
35
import org.jetbrains.jet.lang.resolve.*;
36
import org.jetbrains.jet.lang.resolve.constants.*;
M
Maxim Shafirov 已提交
37
import org.jetbrains.jet.lang.resolve.java.alt.AltClassFinder;
38
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
39
import org.jetbrains.jet.lang.types.*;
S
Stepan Koltsov 已提交
40
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
41
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
42
import org.jetbrains.jet.plugin.JetFileType;
43
import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
44 45 46
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
import org.jetbrains.jet.rt.signature.JetSignatureReader;
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
47

48
import javax.inject.Inject;
49
import java.util.*;
50 51 52 53 54

/**
 * @author abreslav
 */
public class JavaDescriptorResolver {
55
    
S
Stepan Koltsov 已提交
56
    public static final String JAVA_ROOT = "<java_root>";
57

S
Stepan Koltsov 已提交
58 59
    public static final ModuleDescriptor FAKE_ROOT_MODULE = new ModuleDescriptor(JAVA_ROOT);

60 61
    /*package*/ static final DeclarationDescriptor JAVA_METHOD_TYPE_PARAMETER_PARENT = new DeclarationDescriptorImpl(null, Collections.<AnnotationDescriptor>emptyList(), "<java_generic_method>") {

62 63
        @Override
        public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
64
            throw new UnsupportedOperationException();
65 66
        }

67 68
        @Override
        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
69
            return visitor.visitDeclarationDescriptor(this, data);
70 71 72
        }
    };

A
Andrey Breslav 已提交
73
    /*package*/ static final DeclarationDescriptor JAVA_CLASS_OBJECT = new DeclarationDescriptorImpl(null, Collections.<AnnotationDescriptor>emptyList(), "<java_class_object_emulation>") {
A
Andrey Breslav 已提交
74 75 76
        @NotNull
        @Override
        public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
77
            throw new UnsupportedOperationException();
A
Andrey Breslav 已提交
78 79 80 81 82 83 84
        }

        @Override
        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
            return visitor.visitDeclarationDescriptor(this, data);
        }
    };
85 86 87 88 89
    
    private enum TypeParameterDescriptorOrigin {
        JAVA,
        KOTLIN,
    }
90

91 92
    public static class TypeParameterDescriptorInitialization {
        @NotNull
93
        private final TypeParameterDescriptorOrigin origin;
94 95 96
        @NotNull
        final TypeParameterDescriptor descriptor;
        final PsiTypeParameter psiTypeParameter;
97 98 99 100
        @Nullable
        private final List<JetType> upperBoundsForKotlin;
        @Nullable
        private final List<JetType> lowerBoundsForKotlin;
101

102
        private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter) {
103
            this.origin = TypeParameterDescriptorOrigin.JAVA;
104
            this.descriptor = descriptor;
105
            this.psiTypeParameter = psiTypeParameter;
106 107 108 109
            this.upperBoundsForKotlin = null;
            this.lowerBoundsForKotlin = null;
        }

110
        private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter,
111 112 113
                List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
            this.origin = TypeParameterDescriptorOrigin.KOTLIN;
            this.descriptor = descriptor;
114
            this.psiTypeParameter = psiTypeParameter;
115 116
            this.upperBoundsForKotlin = upperBoundsForKotlin;
            this.lowerBoundsForKotlin = lowerBoundsForKotlin;
117 118
        }
    }
119 120


121
    private static abstract class ResolverScopeData {
122
        protected boolean kotlin;
123 124
        
        private Map<String, NamedMembers> namedMembersMap;
125 126 127
        
        @NotNull
        public abstract List<TypeParameterDescriptor> getTypeParameters();
128
    }
A
Andrey Breslav 已提交
129

130 131 132 133
    static abstract class ResolverClassData extends ResolverScopeData {

        @NotNull
        public abstract ClassDescriptor getClassDescriptor();
134 135 136 137 138 139

        @NotNull
        @Override
        public List<TypeParameterDescriptor> getTypeParameters() {
            return getClassDescriptor().getTypeConstructor().getParameters();
        }
140 141
    }

142
    /** Class with instance members */
143 144 145 146 147
    static class ResolverBinaryClassData extends ResolverClassData {

        ResolverBinaryClassData() {
        }

148
        private MutableClassDescriptorLite classDescriptor;
149

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
        List<TypeParameterDescriptorInitialization> typeParameters;

        @Override
        @NotNull
        public ClassDescriptor getClassDescriptor() {
            return classDescriptor;
        }
    }

    static class ResolverSrcClassData extends ResolverClassData {
        @NotNull
        private final ClassDescriptor classDescriptor;

        ResolverSrcClassData(@NotNull ClassDescriptor classDescriptor) {
            this.classDescriptor = classDescriptor;
        }

        @Override
168 169 170 171 172 173
        @NotNull
        public ClassDescriptor getClassDescriptor() {
            return classDescriptor;
        }
    }

174
    /** Either package or class with static members */
175
    private static class ResolverNamespaceData extends ResolverScopeData {
176 177 178 179 180 181
        private JavaNamespaceDescriptor namespaceDescriptor;

        @NotNull
        public NamespaceDescriptor getNamespaceDescriptor() {
            return namespaceDescriptor;
        }
182 183 184 185 186 187

        @NotNull
        @Override
        public List<TypeParameterDescriptor> getTypeParameters() {
            return new ArrayList<TypeParameterDescriptor>(0);
        }
188 189
    }

S
Stepan Koltsov 已提交
190 191
    protected final Map<FqName, ResolverBinaryClassData> classDescriptorCache = Maps.newHashMap();
    protected final Map<FqName, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
192 193
    protected final Map<PsiElement, ResolverNamespaceData> namespaceDescriptorCache = Maps.newHashMap();

194 195 196 197 198
    protected JavaPsiFacade javaFacade;
    protected Project project;
    protected GlobalSearchScope javaSearchScope ;
    protected JavaSemanticServices semanticServices;
    private AltClassFinder altClassFinder;
199
    private NamespaceFactory namespaceFactory;
200

201 202 203 204
    @Inject
    public void setProject(Project project) {
        this.project = project;
        this.altClassFinder = new AltClassFinder(project);
205 206 207 208 209 210
        this.javaSearchScope = new DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
            @Override
            public boolean contains(VirtualFile file) {
                return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE;
            }
        };
211 212 213
        this.javaFacade = JavaPsiFacade.getInstance(project);
    }

214 215 216 217 218
    @Inject
    public void setNamespaceFactory(NamespaceFactoryImpl namespaceFactory) {
        this.namespaceFactory = namespaceFactory;
    }

219 220
    @Inject
    public void setSemanticServices(JavaSemanticServices semanticServices) {
221 222
        this.semanticServices = semanticServices;
    }
223 224 225



226
    @Nullable
227
    ResolverClassData resolveClassData(@NotNull PsiClass psiClass, @NotNull DescriptorSearchRule searchRule) {
S
Stepan Koltsov 已提交
228
        FqName qualifiedName = new FqName(psiClass.getQualifiedName());
229

S
Stepan Koltsov 已提交
230
        if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
231 232 233
            // TODO: only if -$$TImpl class is created by Kotlin
            return null;
        }
234

235 236 237 238 239
        ClassDescriptor builtinClassDescriptor = semanticServices.getKotlinBuiltinClassDescriptor(qualifiedName);
        if (builtinClassDescriptor != null) {
            return new ResolverSrcClassData(builtinClassDescriptor);
        }

240
        // First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
241 242
        ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
        if (kotlinClassDescriptor != null) {
243 244 245 246 247 248 249 250 251 252
            if (searchRule == DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN) {
                throw new IllegalStateException("class must not be found in kotlin: " + qualifiedName);
            } else if (searchRule == DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN) {
                return null;
            } else if (searchRule == DescriptorSearchRule.INCLUDE_KOTLIN) {
                // TODO: probably this is evil
                return new ResolverSrcClassData(kotlinClassDescriptor);
            } else {
                throw new IllegalStateException("unknown searchRule: " + searchRule);
            }
253 254
        }

255 256 257
        PsiClass containingClass = psiClass.getContainingClass();
        if (containingClass != null) {
            // must resolve containing class first, because inner class must have a reference to it
258
            resolveClass(containingClass, DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
259 260
        }

261
        // Not let's take a descriptor of a Java class
262
        ResolverBinaryClassData classData = classDescriptorCache.get(qualifiedName);
263 264 265
        if (classData == null) {
            classData = createJavaClassDescriptor(psiClass);
            classDescriptorCache.put(qualifiedName, classData);
266
        }
267 268 269 270
        return classData;
    }

    @Nullable
271 272
    public ClassDescriptor resolveClass(@NotNull PsiClass psiClass, @NotNull DescriptorSearchRule searchRule) {
        ResolverClassData classData = resolveClassData(psiClass, searchRule);
273 274 275 276 277
        if (classData != null) {
            return classData.getClassDescriptor();
        } else {
            return null;
        }
278 279 280
    }

    @Nullable
281
    public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
282

S
Stepan Koltsov 已提交
283
        if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
284 285 286
            // TODO: only if -$$TImpl class is created by Kotlin
            return null;
        }
287 288 289 290 291 292

        ClassDescriptor builtinClassDescriptor = semanticServices.getKotlinBuiltinClassDescriptor(qualifiedName);
        if (builtinClassDescriptor != null) {
            return builtinClassDescriptor;
        }

293
        // First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
294 295
        ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
        if (kotlinClassDescriptor != null) {
296 297 298 299 300 301 302 303 304
            if (searchRule == DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN) {
                throw new IllegalStateException("class must not be found in kotlin: " + qualifiedName);
            } else if (searchRule == DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN) {
                return null;
            } else if (searchRule == DescriptorSearchRule.INCLUDE_KOTLIN) {
                return kotlinClassDescriptor;
            } else {
                throw new IllegalStateException("unknown searchRule: " + searchRule);
            }
305 306
        }

307
        // Not let's take a descriptor of a Java class
308
        ResolverBinaryClassData classData = classDescriptorCache.get(qualifiedName);
309
        if (classData == null) {
310
            PsiClass psiClass = findClass(qualifiedName);
311 312 313
            if (psiClass == null) {
                return null;
            }
314
            classData = createJavaClassDescriptor(psiClass);
315
        }
316
        return classData.getClassDescriptor();
317 318
    }

319
    private ResolverBinaryClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
S
Stepan Koltsov 已提交
320
        if (classDescriptorCache.containsKey(new FqName(psiClass.getQualifiedName()))) {
321 322
            throw new IllegalStateException(psiClass.getQualifiedName());
        }
A
Andrey Breslav 已提交
323

324 325
        checkPsiClassIsNotJet(psiClass);

326
        String name = psiClass.getName();
327
        ResolverBinaryClassData classData = new ResolverBinaryClassData();
S
Stepan Koltsov 已提交
328
        classDescriptorCache.put(new FqName(psiClass.getQualifiedName()), classData);
329
        ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS;
S
Stepan Koltsov 已提交
330
        ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
331
        classData.classDescriptor = new MutableClassDescriptorLite(containingDeclaration, kind);
332
        classData.classDescriptor.setName(name);
333 334
        classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass));

A
Andrey Breslav 已提交
335
        List<JetType> supertypes = new ArrayList<JetType>();
336

S
Stepan Koltsov 已提交
337 338 339
        TypeVariableResolver outerTypeVariableByNameResolver = TypeVariableResolvers.classTypeVariableResolver(
                (ClassOrNamespaceDescriptor) classData.classDescriptor.getContainingDeclaration(),
                "class " + psiClass.getQualifiedName());
340 341

        classData.typeParameters = createUninitializedClassTypeParameters(psiClass, classData, outerTypeVariableByNameResolver);
342 343 344 345 346 347
        
        List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>();
        for (TypeParameterDescriptorInitialization typeParameter : classData.typeParameters) {
            typeParameters.add(typeParameter.descriptor);
        }
        
348 349 350
        classData.classDescriptor.setTypeParameterDescriptors(typeParameters);
        classData.classDescriptor.setSupertypes(supertypes);
        classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass));
351 352 353 354 355 356 357 358 359 360
        Modality modality;
        if (classData.classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
            modality = Modality.FINAL;
        }
        else {
            modality = Modality.convertFromFlags(
                    psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
                    !psiClass.hasModifierProperty(PsiModifier.FINAL));
        }
        classData.classDescriptor.setModality(modality);
361 362
        classData.classDescriptor.createTypeConstructor();
        classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false));
363

S
Stepan Koltsov 已提交
364
        initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName());
365

S
Stepan Koltsov 已提交
366 367 368
        TypeVariableResolver resolverForTypeParameters = TypeVariableResolvers.classTypeVariableResolver(
                classData.classDescriptor,
                "class " + psiClass.getQualifiedName());
369

370
        // TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
371
        supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData.classDescriptor, classData.getTypeParameters()));
372

A
Andrey Breslav 已提交
373
        PsiMethod[] psiConstructors = psiClass.getConstructors();
374

375
        boolean isStatic = psiClass.hasModifierProperty(PsiModifier.STATIC);
376
        if (psiConstructors.length == 0) {
A
Andrey Breslav 已提交
377 378 379 380
            // We need to create default constructors for classes and abstract classes.
            // Example:
            // class Kotlin() : Java() {}
            // abstract public class Java {}
381
            if (!psiClass.isInterface()) {
382
                ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
383
                        classData.classDescriptor,
A
Andrey Breslav 已提交
384
                        Collections.<AnnotationDescriptor>emptyList(),
385
                        false);
386
                constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), classData.classDescriptor.getVisibility(), isStatic);
387
                constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
388
                classData.classDescriptor.addConstructor(constructorDescriptor, null);
389
                semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
390
            }
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
            if (psiClass.isAnnotationType()) {
                // A constructor for an annotation type takes all the "methods" in the @interface as parameters
                ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
                        classData.classDescriptor,
                        Collections.<AnnotationDescriptor>emptyList(),
                        false);

                List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
                PsiMethod[] methods = psiClass.getMethods();
                for (int i = 0; i < methods.length; i++) {
                    PsiMethod method = methods[i];
                    if (method instanceof PsiAnnotationMethod) {
                        PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
                        assert annotationMethod.getParameterList().getParameters().length == 0;

                        PsiType returnType = annotationMethod.getReturnType();

                        // We take the following heuristical convention:
                        // if the last method of the @interface is an array, we convert it into a vararg
                        JetType varargElementType = null;
                        if (i == methods.length - 1 && (returnType instanceof PsiArrayType)) {
412
                            varargElementType = semanticServices.getTypeTransformer().transformToType(((PsiArrayType) returnType).getComponentType(), resolverForTypeParameters);
413 414 415 416 417 418 419 420
                        }

                        valueParameters.add(new ValueParameterDescriptorImpl(
                                constructorDescriptor,
                                i,
                                Collections.<AnnotationDescriptor>emptyList(),
                                method.getName(),
                                false,
421
                                semanticServices.getTypeTransformer().transformToType(returnType, resolverForTypeParameters),
422 423 424 425 426
                                annotationMethod.getDefaultValue() != null,
                                varargElementType));
                    }
                }

427
                constructorDescriptor.initialize(typeParameters, valueParameters, classData.classDescriptor.getVisibility(), isStatic);
428 429 430 431
                constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
                classData.classDescriptor.addConstructor(constructorDescriptor, null);
                semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
            }
432 433
        }
        else {
434 435 436 437 438
            for (PsiMethod psiConstructor : psiConstructors) {
                PsiMethodWrapper constructor = new PsiMethodWrapper(psiConstructor);

                if (constructor.getJetConstructor().hidden()) {
                    continue;
439 440
                }

441
                ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
442
                        classData.classDescriptor,
A
Andrey Breslav 已提交
443
                        Collections.<AnnotationDescriptor>emptyList(), // TODO
444
                        false);
S
Stepan Koltsov 已提交
445
                String context = "constructor of class " + psiClass.getQualifiedName();
446
                ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
447
                        constructor.getParameters(),
S
Stepan Koltsov 已提交
448
                        TypeVariableResolvers.classTypeVariableResolver(classData.classDescriptor, context));
449 450 451
                if (valueParameterDescriptors.receiverType != null) {
                    throw new IllegalStateException();
                }
452
                constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors,
453
                        resolveVisibilityFromPsiModifiers(psiConstructor), isStatic);
454
                constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
455
                classData.classDescriptor.addConstructor(constructorDescriptor, null);
456
                semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiConstructor, constructorDescriptor);
457
            }
A
Andrey Breslav 已提交
458
        }
459

460 461 462 463
        MutableClassDescriptorLite classObject = createClassObjectDescriptor(classData.classDescriptor, psiClass);
        if (classObject != null) {
            classData.classDescriptor.setClassObjectDescriptor(classObject);
        }
464

465
        semanticServices.getTrace().record(BindingContext.CLASS, psiClass, classData.classDescriptor);
466

467
        return classData;
468 469
    }

470
    static void checkPsiClassIsNotJet(PsiClass psiClass) {
471
        if (psiClass instanceof JetJavaMirrorMarker) {
472
            throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName());
473 474 475
        }
    }

476 477 478 479 480 481 482 483 484 485
    @Nullable
    private PsiClass getInnerClassClassObject(@NotNull PsiClass outer) {
        for (PsiClass inner : outer.getInnerClasses()) {
            if (inner.getName().equals(JvmAbi.CLASS_OBJECT_CLASS_NAME)) {
                return inner;
            }
        }
        return null;
    }

486 487 488 489 490 491
    /**
     * TODO
     * @see #createJavaNamespaceDescriptor(com.intellij.psi.PsiClass)
     */
    @Nullable
    private MutableClassDescriptorLite createClassObjectDescriptor(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) {
492 493 494 495 496
        PsiClass classObjectPsiClass = getInnerClassClassObject(psiClass);
        if (classObjectPsiClass == null) {
            return null;
        }

497 498
        checkPsiClassIsNotJet(psiClass);

499 500 501 502
        ResolverBinaryClassData classData = new ResolverBinaryClassData();
        classData.kotlin = true;
        classData.classDescriptor = new MutableClassDescriptorLite(containing, ClassKind.OBJECT);

S
Stepan Koltsov 已提交
503
        classDescriptorCache.put(new FqName(classObjectPsiClass.getQualifiedName()), classData);
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518

        classData.classDescriptor.setSupertypes(getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData.classDescriptor, new ArrayList<TypeParameterDescriptor>(0)));
        classData.classDescriptor.setName(JetPsiUtil.NO_NAME_PROVIDED); // TODO
        classData.classDescriptor.setModality(Modality.FINAL);
        classData.classDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
        classData.classDescriptor.createTypeConstructor();
        classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, classObjectPsiClass, semanticServices, false));

        // TODO: wrong: class objects do not need visible constructors
        ConstructorDescriptorImpl constructor = new ConstructorDescriptorImpl(classData.classDescriptor, new ArrayList<AnnotationDescriptor>(0), true);
        constructor.setReturnType(classData.classDescriptor.getDefaultType());
        constructor.initialize(new ArrayList<TypeParameterDescriptor>(0), new ArrayList<ValueParameterDescriptor>(0), Visibility.PUBLIC);

        classData.classDescriptor.addConstructor(constructor, null);
        return classData.classDescriptor;
519 520
    }

521
    private List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, ResolverBinaryClassData classData, TypeVariableResolver typeVariableResolver) {
522 523 524 525 526
        JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
        classData.kotlin = jetClassAnnotation.isDefined();
        
        if (jetClassAnnotation.signature().length() > 0) {
            return resolveClassTypeParametersFromJetSignature(
S
Stepan Koltsov 已提交
527
                    jetClassAnnotation.signature(), psiClass, classData.classDescriptor);
528
        }
529

530
        return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters());
531 532
    }

533
    @NotNull
534
    private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) {
535 536 537 538 539
        for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) {
            if (typeParameter.getName().equals(name)) {
                return typeParameter; 
            }
        }
540 541 542
        throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found");
    }

S
Stepan Koltsov 已提交
543

544
    private static final FqName JL_OBJECT = new FqName("java.lang.Object");
S
Stepan Koltsov 已提交
545 546

    private boolean isJavaLangObject(JetType type) {
547 548 549
        ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
        return classifierDescriptor instanceof ClassDescriptor &&
               DescriptorUtils.getFQName(classifierDescriptor).equals(JL_OBJECT.toUnsafe());
S
Stepan Koltsov 已提交
550 551 552
    }


553
    private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter {
554 555

        @NotNull
556
        private final PsiTypeParameterListOwner psiOwner;
557
        @NotNull
558
        private final String name;
559
        @NotNull
560
        private final TypeVariableResolver typeVariableResolver;
561 562
        @NotNull
        private final TypeParameterDescriptor typeParameterDescriptor;
563

564 565
        protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner,
                String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptor typeParameterDescriptor)
566
        {
567 568 569
            if (name.isEmpty()) {
                throw new IllegalStateException();
            }
570

571 572
            this.psiOwner = psiOwner;
            this.name = name;
573
            this.typeVariableResolver = typeVariableResolver;
574
            this.typeParameterDescriptor = typeParameterDescriptor;
575 576 577 578
        }

        List<JetType> upperBounds = new ArrayList<JetType>();
        List<JetType> lowerBounds = new ArrayList<JetType>();
S
Stepan Koltsov 已提交
579
        
580 581
        @Override
        public JetSignatureVisitor visitClassBound() {
582
            return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) {
583 584
                @Override
                protected void done(@NotNull JetType jetType) {
S
Stepan Koltsov 已提交
585 586 587
                    if (isJavaLangObject(jetType)) {
                        return;
                    }
588 589 590 591 592 593 594
                    upperBounds.add(jetType);
                }
            };
        }

        @Override
        public JetSignatureVisitor visitInterfaceBound() {
595
            return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) {
596 597 598 599 600 601 602 603 604
                @Override
                protected void done(@NotNull JetType jetType) {
                    upperBounds.add(jetType);
                }
            };
        }

        @Override
        public void visitFormalTypeParameterEnd() {
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
            PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name);
            TypeParameterDescriptorInitialization typeParameterDescriptorInitialization = new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter, upperBounds, lowerBounds);
            done(typeParameterDescriptorInitialization);
        }
        
        protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor);
    }

    private class JetSignatureTypeParametersVisitor extends JetSignatureExceptionsAdapter {
        @NotNull
        private final DeclarationDescriptor containingDeclaration;
        @NotNull
        private final PsiTypeParameterListOwner psiOwner;

        private final List<TypeParameterDescriptor> previousTypeParameters = new ArrayList<TypeParameterDescriptor>();
        // note changes state in this method
        private final TypeVariableResolver typeVariableResolver;


S
Stepan Koltsov 已提交
624
        private JetSignatureTypeParametersVisitor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameterListOwner psiOwner, @NotNull String context) {
625 626 627
            this.containingDeclaration = containingDeclaration;
            this.psiOwner = psiOwner;

S
Stepan Koltsov 已提交
628 629 630 631
            this.typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(
                    previousTypeParameters,
                    containingDeclaration,
                    context);
632 633 634 635 636 637 638 639 640
        }

        private int formalTypeParameterIndex = 0;


        List<TypeParameterDescriptorInitialization> r = new ArrayList<TypeParameterDescriptorInitialization>();

        @Override
        public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
641 642 643
            TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification(
                    containingDeclaration,
                    Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
644
                    reified,
645 646
                    JetSignatureUtils.translateVariance(variance),
                    name,
647 648 649 650 651 652 653 654 655 656 657
                    formalTypeParameterIndex++);

            previousTypeParameters.add(typeParameter);

            return new JetSignatureTypeParameterVisitor(psiOwner, name, typeVariableResolver, typeParameter) {
                @Override
                protected void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor) {
                    r.add(typeParameterDescriptor);
                    previousTypeParameters.add(typeParameterDescriptor.descriptor);
                }
            };
658
        }
659 660
    }

661
    /**
S
Stepan Koltsov 已提交
662
     * @see #resolveMethodTypeParametersFromJetSignature(String, com.intellij.psi.PsiMethod, org.jetbrains.jet.lang.descriptors.DeclarationDescriptor)
663
     */
S
Stepan Koltsov 已提交
664 665 666 667
    private List<TypeParameterDescriptorInitialization> resolveClassTypeParametersFromJetSignature(String jetSignature,
            final PsiClass clazz, final ClassDescriptor classDescriptor) {
        String context = "class " + clazz.getQualifiedName();
        JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(classDescriptor, clazz, context) {
668 669 670 671 672 673 674 675 676 677 678
            @Override
            public JetSignatureVisitor visitSuperclass() {
                // TODO
                return new JetSignatureAdapter();
            }

            @Override
            public JetSignatureVisitor visitInterface() {
                // TODO
                return new JetSignatureAdapter();
            }
679 680 681
        };
        new JetSignatureReader(jetSignature).accept(jetSignatureTypeParametersVisitor);
        return jetSignatureTypeParametersVisitor.r;
682 683
    }

S
Stepan Koltsov 已提交
684
    private ClassOrNamespaceDescriptor resolveParentDescriptor(PsiClass psiClass) {
685 686
        PsiClass containingClass = psiClass.getContainingClass();
        if (containingClass != null) {
687
            return resolveClass(containingClass, DescriptorSearchRule.INCLUDE_KOTLIN);
688
        }
689

690
        return resolveNamespace(new FqName(psiClass.getQualifiedName()).parent(), DescriptorSearchRule.INCLUDE_KOTLIN);
691 692
    }

693 694
    private List<TypeParameterDescriptorInitialization> makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) {
        List<TypeParameterDescriptorInitialization> result = Lists.newArrayList();
695
        for (PsiTypeParameter typeParameter : typeParameters) {
696
            TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter);
A
Andrey Breslav 已提交
697
            result.add(typeParameterDescriptor);
698 699 700 701
        }
        return result;
    }

702
    @NotNull
703
    private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
704
        TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
705
                containingDeclaration,
A
Andrey Breslav 已提交
706
                Collections.<AnnotationDescriptor>emptyList(), // TODO
A
Andrey Breslav 已提交
707
                false,
708
                Variance.INVARIANT,
709 710
                psiTypeParameter.getName(),
                psiTypeParameter.getIndex()
711
        );
712
        return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter);
713 714
    }

715
    private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) {
716 717 718
        TypeParameterDescriptor typeParameterDescriptor = typeParameter.descriptor;
        if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
            List<?> upperBounds = typeParameter.upperBoundsForKotlin;
719 720 721
            if (upperBounds.size() == 0){
                typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
            } else {
722
                for (JetType upperBound : typeParameter.upperBoundsForKotlin) {
723 724 725 726 727
                    typeParameterDescriptor.addUpperBound(upperBound);
                }
            }

            // TODO: lower bounds
728
        } else {
729
            PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes();
730 731 732 733
            if (referencedTypes.length == 0){
                typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
            }
            else if (referencedTypes.length == 1) {
734
                typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], typeVariableByPsiResolver));
735 736 737
            }
            else {
                for (PsiClassType referencedType : referencedTypes) {
738
                    typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, typeVariableByPsiResolver));
739
                }
A
Andrey Breslav 已提交
740 741
            }
        }
742
        typeParameterDescriptor.setInitialized();
743 744
    }

S
Stepan Koltsov 已提交
745
    private void initializeTypeParameters(List<TypeParameterDescriptorInitialization> typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) {
746
        List<TypeParameterDescriptor> prevTypeParameters = new ArrayList<TypeParameterDescriptor>();
747
        for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) {
748
            prevTypeParameters.add(psiTypeParameter.descriptor);
S
Stepan Koltsov 已提交
749
            initializeTypeParameter(psiTypeParameter, TypeVariableResolvers.typeVariableResolverFromTypeParameters(prevTypeParameters, typeParametersOwner, context));
S
Stepan Koltsov 已提交
750
        }
A
Andrey Breslav 已提交
751 752
    }

753
    private Collection<JetType> getSupertypes(PsiClassWrapper psiClass, ClassDescriptor classDescriptor, List<TypeParameterDescriptor> typeParameters) {
754 755
        final List<JetType> result = new ArrayList<JetType>();

S
Stepan Koltsov 已提交
756 757
        String context = "class " + psiClass.getQualifiedName();

758
        if (psiClass.getJetClass().signature().length() > 0) {
S
Stepan Koltsov 已提交
759
            final TypeVariableResolver typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
760 761 762 763 764 765 766 767 768 769
            
            new JetSignatureReader(psiClass.getJetClass().signature()).accept(new JetSignatureExceptionsAdapter() {
                @Override
                public JetSignatureVisitor visitFormalTypeParameter(String name, TypeInfoVariance variance, boolean reified) {
                    // TODO: collect
                    return new JetSignatureAdapter();
                }

                @Override
                public JetSignatureVisitor visitSuperclass() {
770
                    return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) {
771 772 773 774 775 776 777 778 779 780 781
                        @Override
                        protected void done(@NotNull JetType jetType) {
                            if (!jetType.equals(JetStandardClasses.getAnyType())) {
                                result.add(jetType);
                            }
                        }
                    };
                }

                @Override
                public JetSignatureVisitor visitInterface() {
S
Stepan Koltsov 已提交
782
                    return visitSuperclass();
783 784 785
                }
            });
        } else {
S
Stepan Koltsov 已提交
786 787 788
            TypeVariableResolver typeVariableResolverForSupertypes = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
            transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
            transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
789
        }
790 791 792 793 794 795 796
        
        for (JetType supertype : result) {
            if (ErrorUtils.isErrorType(supertype)) {
                semanticServices.getTrace().record(BindingContext.INCOMPLETE_HIERARCHY, classDescriptor);
            }
        }
        
797 798 799
        if (result.isEmpty()) {
            result.add(JetStandardClasses.getAnyType());
        }
800 801 802
        return result;
    }

803
    private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes, TypeVariableResolver typeVariableResolver, boolean annotation) {
804
        for (PsiClassType type : extendsListTypes) {
805 806 807 808
            PsiClass resolved = type.resolve();
            if (resolved != null && resolved.getQualifiedName().equals(JvmStdlibNames.JET_OBJECT.getFqName())) {
                continue;
            }
809 810 811
            if (annotation && resolved.getQualifiedName().equals("java.lang.annotation.Annotation")) {
                continue;
            }
812
            
813
            JetType transform = semanticServices.getTypeTransformer().transformToType(type, typeVariableResolver);
814 815 816 817 818

            result.add(TypeUtils.makeNotNullable(transform));
        }
    }

819
    @Nullable
820
    public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
821 822 823
        // First, let's check that there is no Kotlin package:
        NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(qualifiedName);
        if (kotlinNamespaceDescriptor != null) {
824 825 826 827 828 829 830 831 832 833
            if (searchRule == DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN) {
                throw new IllegalStateException("class must not be found in kotlin: " + qualifiedName);
            } else if (searchRule == DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN) {
                return null;
            } else if (searchRule == DescriptorSearchRule.INCLUDE_KOTLIN) {
                // TODO: probably this is evil
                return kotlinNamespaceDescriptor;
            } else {
                throw new IllegalStateException("unknown searchRule: " + searchRule);
            }
834 835
        }

836
        PsiPackage psiPackage = findPackage(qualifiedName);
837
        if (psiPackage == null) {
838
            PsiClass psiClass = findClass(qualifiedName);
A
Andrey Breslav 已提交
839 840
            if (psiClass == null) return null;
            return resolveNamespace(psiClass);
841 842 843 844
        }
        return resolveNamespace(psiPackage);
    }

845
    @Nullable
S
Stepan Koltsov 已提交
846 847
    public PsiClass findClass(@NotNull FqName qualifiedName) {
        PsiClass original = javaFacade.findClass(qualifiedName.getFqName(), javaSearchScope);
M
Maxim Shafirov 已提交
848
        PsiClass altClass = altClassFinder.findClass(qualifiedName);
849
        PsiClass result = original;
850 851 852 853 854
        if (altClass != null) {
            if (altClass instanceof ClsClassImpl) {
                altClass.putUserData(ClsClassImpl.DELEGATE_KEY, original);
            }

855 856 857 858
            result = altClass;
        }

        if (result != null) {
S
Stepan Koltsov 已提交
859
            FqName actualQualifiedName = new FqName(result.getQualifiedName());
860
            if (!actualQualifiedName.equals(qualifiedName)) {
861
//                throw new IllegalStateException("requested " + qualifiedName + ", got " + actualQualifiedName);
862
            }
863
        }
864 865

        return result;
866 867
    }

S
Stepan Koltsov 已提交
868 869
    /*package*/ PsiPackage findPackage(@NotNull FqName qualifiedName) {
        return javaFacade.findPackage(qualifiedName.getFqName());
870 871
    }

872
    private NamespaceDescriptor resolveNamespace(@NotNull PsiPackage psiPackage) {
873 874 875 876
        ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiPackage);
        if (namespaceData == null) {
            namespaceData = createJavaNamespaceDescriptor(psiPackage);
            namespaceDescriptorCache.put(psiPackage, namespaceData);
S
Stepan Koltsov 已提交
877
            namespaceDescriptorCacheByFqn.put(new FqName(psiPackage.getQualifiedName()), namespaceData);
878
        }
879
        return namespaceData.namespaceDescriptor;
880 881
    }

A
Andrey Breslav 已提交
882
    private NamespaceDescriptor resolveNamespace(@NotNull PsiClass psiClass) {
883 884 885 886
        ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiClass);
        if (namespaceData == null) {
            namespaceData = createJavaNamespaceDescriptor(psiClass);
            namespaceDescriptorCache.put(psiClass, namespaceData);
S
Stepan Koltsov 已提交
887
            namespaceDescriptorCacheByFqn.put(new FqName(psiClass.getQualifiedName()), namespaceData);
A
Andrey Breslav 已提交
888
        }
889
        return namespaceData.namespaceDescriptor;
A
Andrey Breslav 已提交
890 891
    }

892 893
    private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull PsiPackage psiPackage) {
        ResolverNamespaceData namespaceData = new ResolverNamespaceData();
894
        String name = psiPackage.getName();
895
        namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor(
S
Stepan Koltsov 已提交
896
                (NamespaceDescriptorParent) resolveParentDescriptor(psiPackage),
A
Andrey Breslav 已提交
897
                Collections.<AnnotationDescriptor>emptyList(), // TODO
898
                name == null ? JAVA_ROOT : name,
S
Stepan Koltsov 已提交
899
                name == null ? FqName.ROOT : new FqName(psiPackage.getQualifiedName()),
900
                true
901
        );
902

S
Stepan Koltsov 已提交
903
        namespaceData.namespaceDescriptor.setMemberScope(createJavaPackageScope(new FqName(psiPackage.getQualifiedName()), namespaceData.namespaceDescriptor));
904 905 906 907
        semanticServices.getTrace().record(BindingContext.NAMESPACE, psiPackage, namespaceData.namespaceDescriptor);
        // TODO: hack
        namespaceData.kotlin = true;
        return namespaceData;
908 909
    }

S
Stepan Koltsov 已提交
910 911 912 913
    public JavaPackageScope createJavaPackageScope(@NotNull FqName fqName, @NotNull NamespaceDescriptor ns) {
        return new JavaPackageScope(fqName, ns, semanticServices);
    }

S
Stepan Koltsov 已提交
914
    @NotNull
915 916 917
    private DeclarationDescriptor resolveParentDescriptor(@NotNull PsiPackage psiPackage) {
        PsiPackage parentPackage = psiPackage.getParentPackage();
        if (parentPackage == null) {
S
Stepan Koltsov 已提交
918
            return FAKE_ROOT_MODULE;
919 920 921 922
        }
        return resolveNamespace(parentPackage);
    }

923 924 925 926
    /**
     * TODO
     * @see #createClassObjectDescriptor(org.jetbrains.jet.lang.descriptors.ClassDescriptor, com.intellij.psi.PsiClass)
     */
927
    private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) {
928 929 930

        checkPsiClassIsNotJet(psiClass);

931 932
        ResolverNamespaceData namespaceData = new ResolverNamespaceData();
        namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor(
S
Stepan Koltsov 已提交
933
                (NamespaceDescriptorParent) resolveParentDescriptor(psiClass),
A
Andrey Breslav 已提交
934
                Collections.<AnnotationDescriptor>emptyList(), // TODO
935
                psiClass.getName(),
S
Stepan Koltsov 已提交
936
                new FqName(psiClass.getQualifiedName()),
937
                false
938
        );
939 940 941
        namespaceData.namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true));
        semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor);
        return namespaceData;
942
    }
943 944 945 946 947 948 949 950 951 952
    
    private static class ValueParameterDescriptors {
        private final JetType receiverType;
        private final List<ValueParameterDescriptor> descriptors;

        private ValueParameterDescriptors(@Nullable JetType receiverType, List<ValueParameterDescriptor> descriptors) {
            this.receiverType = receiverType;
            this.descriptors = descriptors;
        }
    }
953

954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
    private enum JvmMethodParameterKind {
        REGULAR,
        RECEIVER,
        TYPE_INFO,
    }
    
    private static class JvmMethodParameterMeaning {
        private final JvmMethodParameterKind kind;
        private final JetType receiverType;
        private final ValueParameterDescriptor valueParameterDescriptor;
        private final Object typeInfo;

        private JvmMethodParameterMeaning(JvmMethodParameterKind kind, JetType receiverType, ValueParameterDescriptor valueParameterDescriptor, Object typeInfo) {
            this.kind = kind;
            this.receiverType = receiverType;
            this.valueParameterDescriptor = valueParameterDescriptor;
            this.typeInfo = typeInfo;
        }
        
        public static JvmMethodParameterMeaning receiver(@NotNull JetType receiverType) {
            return new JvmMethodParameterMeaning(JvmMethodParameterKind.RECEIVER, receiverType, null, null);
        }
        
        public static JvmMethodParameterMeaning regular(@NotNull ValueParameterDescriptor valueParameterDescriptor) {
            return new JvmMethodParameterMeaning(JvmMethodParameterKind.REGULAR, null, valueParameterDescriptor, null);
        }
        
        public static JvmMethodParameterMeaning typeInfo(@NotNull Object typeInfo) {
            return new JvmMethodParameterMeaning(JvmMethodParameterKind.TYPE_INFO, null, null, typeInfo);
        }
    }

    @NotNull
987
    private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i,
988 989 990 991 992 993 994
            PsiParameterWrapper parameter, TypeVariableResolver typeVariableResolver) {

        if (parameter.getJetTypeParameter().isDefined()) {
            return JvmMethodParameterMeaning.typeInfo(new Object());
        }

        PsiType psiType = parameter.getPsiParameter().getType();
995

996 997
        // TODO: must be very slow, make it lazy?
        String name = parameter.getPsiParameter().getName() != null ? parameter.getPsiParameter().getName() : "p" + i;
998

999 1000
        if (parameter.getJetValueParameter().name().length() > 0) {
            name = parameter.getJetValueParameter().name();
1001 1002
        }
        
1003 1004 1005 1006
        String typeFromAnnotation = parameter.getJetValueParameter().type();
        boolean receiver = parameter.getJetValueParameter().receiver();
        boolean hasDefaultValue = parameter.getJetValueParameter().hasDefaultValue();

S
Stepan Koltsov 已提交
1007
        JetType outType;
1008
        if (typeFromAnnotation.length() > 0) {
1009
            outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver);
S
Stepan Koltsov 已提交
1010
        } else {
1011
            outType = semanticServices.getTypeTransformer().transformToType(psiType, typeVariableResolver);
S
Stepan Koltsov 已提交
1012
        }
1013 1014 1015

        JetType varargElementType;
        if (psiType instanceof PsiEllipsisType) {
1016
            varargElementType = JetStandardLibrary.getInstance().getArrayElementType(outType);
1017 1018 1019 1020
        } else {
            varargElementType = null;
        }

1021 1022 1023
        if (receiver) {
            return JvmMethodParameterMeaning.receiver(outType);
        } else {
S
Stepan Koltsov 已提交
1024 1025 1026 1027 1028 1029 1030 1031 1032

            JetType transformedType;
            if (parameter.getJetValueParameter().nullable()) {
                transformedType = TypeUtils.makeNullableAsSpecified(outType, parameter.getJetValueParameter().nullable());
            } else if (parameter.getPsiParameter().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName()) != null) {
                transformedType = TypeUtils.makeNullableAsSpecified(outType, false);
            } else {
                transformedType = outType;
            }
1033 1034 1035 1036 1037
            return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl(
                    containingDeclaration,
                    i,
                    Collections.<AnnotationDescriptor>emptyList(), // TODO
                    name,
S
Stepan Koltsov 已提交
1038
                    false,
S
Stepan Koltsov 已提交
1039
                    transformedType,
1040
                    hasDefaultValue,
1041 1042 1043
                    varargElementType
            ));
        }
1044 1045
    }

S
Stepan Koltsov 已提交
1046
    public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, String fieldName, boolean staticMembers) {
1047
        ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
1048

1049 1050 1051
        NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName);
        if (namedMembers == null) {
            return Collections.emptySet();
1052
        }
1053
        Set<VariableDescriptor> r = new HashSet<VariableDescriptor>();
1054

S
Stepan Koltsov 已提交
1055
        resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, fieldName, "class or namespace " + psiClass.getQualifiedName());
1056

1057 1058 1059 1060 1061 1062 1063
        r.addAll(namedMembers.propertyDescriptors);

        for (JetType supertype : getSupertypes(scopeData)) {
            r.addAll(supertype.getMemberScope().getProperties(fieldName));
        }

        return r;
1064 1065 1066
    }
    
    @NotNull
S
Stepan Koltsov 已提交
1067
    public Set<VariableDescriptor> resolveFieldGroup(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, boolean staticMembers) {
1068

1069 1070
        ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
        
1071
        Set<VariableDescriptor> descriptors = Sets.newHashSet();
1072 1073 1074
        Map<String, NamedMembers> membersForProperties = scopeData.namedMembersMap;
        for (Map.Entry<String, NamedMembers> entry : membersForProperties.entrySet()) {
            NamedMembers namedMembers = entry.getValue();
1075
            if (namedMembers.propertyAccessors == null) {
1076 1077 1078 1079
                continue;
            }
            
            String propertyName = entry.getKey();
1080

S
Stepan Koltsov 已提交
1081
            resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, propertyName, "class or namespace " + psiClass.getQualifiedName());
1082
            descriptors.addAll(namedMembers.propertyDescriptors);
1083
        }
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093

        for (JetType supertype : getSupertypes(scopeData)) {
            for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
                // TODO: ugly
                if (descriptor instanceof VariableDescriptor) {
                    descriptors.add((VariableDescriptor) descriptor);
                }
            }
        }
        
1094
        return descriptors;
1095
    }
1096 1097 1098 1099 1100 1101 1102
    
    private Object key(TypeSource typeSource) {
        if (typeSource == null) {
            return "";
        } else if (typeSource.getTypeString().length() > 0) {
            return typeSource.getTypeString();
        } else {
1103
            return psiTypeToKey(typeSource.getPsiType());
1104 1105
        }
    }
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118

    private Object psiTypeToKey(PsiType psiType) {
        if (psiType instanceof PsiClassType) {
            return ((PsiClassType) psiType).getClassName();
        } else if (psiType instanceof PsiPrimitiveType) {
            return psiType.getPresentableText();
        } else if (psiType instanceof PsiArrayType) {
            return Pair.create("[", psiTypeToKey(((PsiArrayType) psiType).getComponentType()));
        } else {
            throw new IllegalStateException("" + psiType.getClass());
        }
    }

1119 1120 1121 1122 1123
    private Object propertyKeyForGrouping(PropertyAccessorData propertyAccessor) {
        Object type = key(propertyAccessor.getType());
        Object receiverType = key(propertyAccessor.getReceiverType());
        return Pair.create(type, receiverType);
    }
1124

1125 1126 1127
    private void resolveNamedGroupProperties(
            @NotNull ClassOrNamespaceDescriptor owner,
            @NotNull ResolverScopeData scopeData,
S
Stepan Koltsov 已提交
1128 1129 1130
            boolean staticMembers, @NotNull NamedMembers namedMembers, @NotNull String propertyName,
            @NotNull String context
            ) {
1131 1132 1133 1134
        if (namedMembers.propertyDescriptors != null) {
            return;
        }
        
1135
        if (namedMembers.propertyAccessors == null) {
1136 1137 1138
            namedMembers.propertyDescriptors = Collections.emptySet();
            return;
        }
1139

S
Stepan Koltsov 已提交
1140
        TypeVariableResolver typeVariableResolver = TypeVariableResolvers.classTypeVariableResolver(owner, context);
1141

1142 1143 1144 1145
        class GroupingValue {
            PropertyAccessorData getter;
            PropertyAccessorData setter;
            PropertyAccessorData field;
1146
            boolean ext;
1147
        }
1148 1149
        
        Map<Object, GroupingValue> map = new HashMap<Object, GroupingValue>();
1150

1151
        for (PropertyAccessorData propertyAccessor : namedMembers.propertyAccessors) {
1152

1153 1154 1155 1156 1157
            Object key = propertyKeyForGrouping(propertyAccessor);
            
            GroupingValue value = map.get(key);
            if (value == null) {
                value = new GroupingValue();
1158
                value.ext = propertyAccessor.getReceiverType() != null;
1159 1160
                map.put(key, value);
            }
1161

1162 1163 1164 1165
            if (value.ext != (propertyAccessor.getReceiverType() != null)) {
                throw new IllegalStateException("internal error, incorrect key");
            }

1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
            if (propertyAccessor.isGetter()) {
                if (value.getter != null) {
                    throw new IllegalStateException("oops, duplicate key");
                }
                value.getter = propertyAccessor;
            } else if (propertyAccessor.isSetter()) {
                if (value.setter != null) {
                    throw new IllegalStateException("oops, duplicate key");
                }
                value.setter = propertyAccessor;
            } else if (propertyAccessor.isField()) {
                if (value.field != null) {
                    throw new IllegalStateException("oops, duplicate key");
                }
                value.field = propertyAccessor;
            } else {
                throw new IllegalStateException();
            }
1184
        }
1185

1186
        
1187 1188
        Set<VariableDescriptor> r = new HashSet<VariableDescriptor>(1);

1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202
        int regularProperitesCount = 0;
        for (GroupingValue members : map.values()) {
            if (!members.ext) {
                ++regularProperitesCount;
            }
        }

        for (GroupingValue members : map.values()) {

            // we cannot have more then one property with given name even if java code
            // has several fields, getters and setter of different types
            if (!members.ext && regularProperitesCount > 1) {
                continue;
            }
1203

1204
            boolean isFinal;
1205 1206 1207
            if (!scopeData.kotlin) {
                isFinal = true;
            } else if (members.setter == null && members.getter == null) {
1208 1209 1210 1211 1212 1213 1214 1215
                isFinal = false;
            } else if (members.getter != null) {
                isFinal = members.getter.getMember().isFinal();
            } else if (members.setter != null) {
                isFinal = members.setter.getMember().isFinal();
            } else {
                isFinal = false;
            }
1216

1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
            PropertyAccessorData anyMember;
            if (members.getter != null) {
                anyMember = members.getter;
            } else if (members.field != null) {
                anyMember = members.field;
            } else if (members.setter != null) {
                anyMember = members.setter;
            } else {
                throw new IllegalStateException();
            }
1227

1228 1229 1230 1231 1232 1233
            boolean isVar;
            if (members.getter == null && members.setter == null) {
                isVar = !members.field.getMember().isFinal();
            } else {
                isVar = members.setter != null;
            }
1234 1235 1236 1237 1238 1239 1240 1241 1242 1243

            Modality modality;
            if (isFinal) {
                modality = Modality.FINAL;
            }
            else {
                modality = anyMember.getMember().isAbstract() ? Modality.ABSTRACT : Modality.OPEN;
            }


1244 1245
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
                    owner,
A
Alex Tkachman 已提交
1246
                    resolveAnnotations(anyMember.getMember().psiMember),
1247
                    modality,
1248 1249 1250
                    resolveVisibilityFromPsiModifiers(anyMember.getMember().psiMember),
                    isVar,
                    false,
1251 1252
                    propertyName,
                    CallableMemberDescriptor.Kind.DECLARATION);
1253

1254 1255 1256
            PropertyGetterDescriptor getterDescriptor = null;
            PropertySetterDescriptor setterDescriptor = null;
            if (members.getter != null) {
A
Alex Tkachman 已提交
1257
                getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, resolveAnnotations(members.getter.getMember().psiMember), Modality.OPEN, Visibility.PUBLIC, true, false, CallableMemberDescriptor.Kind.DECLARATION);
1258 1259
            }
            if (members.setter != null) {
A
Alex Tkachman 已提交
1260
                setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, resolveAnnotations(members.setter.getMember().psiMember), Modality.OPEN, Visibility.PUBLIC, true, false, CallableMemberDescriptor.Kind.DECLARATION);
1261
            }
1262

1263
            propertyDescriptor.initialize(getterDescriptor, setterDescriptor);
1264

S
Stepan Koltsov 已提交
1265
            List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(0);
1266 1267 1268

            if (members.setter != null) {
                PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember();
1269

1270
                if (anyMember == members.setter) {
S
Stepan Koltsov 已提交
1271
                    typeParameters = resolveMethodTypeParameters(method, propertyDescriptor, typeVariableResolver);
1272 1273 1274 1275 1276 1277
                }
            }
            if (members.getter != null) {
                PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember();

                if (anyMember == members.getter) {
S
Stepan Koltsov 已提交
1278
                    typeParameters = resolveMethodTypeParameters(method, propertyDescriptor, typeVariableResolver);
1279 1280 1281
                }
            }

S
Stepan Koltsov 已提交
1282
            TypeVariableResolver typeVariableResolverForPropertyInternals = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, propertyDescriptor, "property " + propertyName + " in " + context);
1283

1284 1285 1286 1287
            JetType propertyType;
            if (anyMember.getType().getTypeString().length() > 0) {
                propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals);
            } else {
1288
                propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType(), typeVariableResolverForPropertyInternals);
S
Stepan Koltsov 已提交
1289 1290 1291
                if (anyMember.getType().getPsiNotNullOwner().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName()) != null) {
                    propertyType = TypeUtils.makeNullableAsSpecified(propertyType, false);
                }
1292 1293 1294 1295 1296 1297 1298 1299
            }
            
            JetType receiverType;
            if (anyMember.getReceiverType() == null) {
                receiverType = null;
            } else if (anyMember.getReceiverType().getTypeString().length() > 0) {
                receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals);
            } else {
1300
                receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals);
1301 1302 1303 1304 1305 1306 1307
            }

            propertyDescriptor.setType(
                    propertyType,
                    typeParameters,
                    DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
                    receiverType
1308
            );
1309 1310 1311 1312
            if (getterDescriptor != null) {
                getterDescriptor.initialize(propertyType);
            }
            if (setterDescriptor != null) {
1313
                setterDescriptor.initialize(new ValueParameterDescriptorImpl(setterDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), "p0"/*TODO*/, false, propertyDescriptor.getType(), false, null));
1314 1315 1316 1317 1318
            }

            semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.getMember().psiMember, propertyDescriptor);
            
            r.add(propertyDescriptor);
1319
        }
1320

1321
        namedMembers.propertyDescriptors = r;
1322
    }
1323

1324
    private void resolveNamedGroupFunctions(ClassOrNamespaceDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, NamedMembers namedMembers, String methodName, ResolverScopeData scopeData) {
1325 1326 1327
        if (namedMembers.functionDescriptors != null) {
            return;
        }
1328 1329
        
        final Set<FunctionDescriptor> functions = new HashSet<FunctionDescriptor>();
1330

1331
        Set<SimpleFunctionDescriptor> functionsFromCurrent = Sets.newHashSet();
1332
        for (PsiMethodWrapper method : namedMembers.methods) {
1333 1334
            FunctionDescriptorImpl function = resolveMethodToFunctionDescriptor(owner, psiClass,
                    method);
1335
            if (function != null) {
1336
                functionsFromCurrent.add((SimpleFunctionDescriptor) function);
1337 1338 1339 1340 1341 1342
            }
        }

        if (owner instanceof ClassDescriptor) {
            ClassDescriptor classDescriptor = (ClassDescriptor) owner;

1343
            Set<SimpleFunctionDescriptor> functionsFromSupertypes = getFunctionsFromSupertypes(scopeData, methodName);
1344

S
Stepan Koltsov 已提交
1345
            OverrideResolver.generateOverridesInFunctionGroup(methodName, functionsFromSupertypes, functionsFromCurrent, classDescriptor, new OverrideResolver.DescriptorSink() {
1346
                @Override
S
Stepan Koltsov 已提交
1347 1348
                public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
                    functions.add((FunctionDescriptor) fakeOverride);
1349
                }
1350 1351

                @Override
S
Stepan Koltsov 已提交
1352
                public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
1353 1354
                    // nop
                }
1355 1356 1357 1358 1359 1360 1361 1362 1363
            });

        }

        functions.addAll(functionsFromCurrent);

        namedMembers.functionDescriptors = functions;
    }
    
1364 1365
    private Set<SimpleFunctionDescriptor> getFunctionsFromSupertypes(ResolverScopeData scopeData, String methodName) {
        Set<SimpleFunctionDescriptor> r = new HashSet<SimpleFunctionDescriptor>();
1366 1367
        for (JetType supertype : getSupertypes(scopeData)) {
            for (FunctionDescriptor function : supertype.getMemberScope().getFunctions(methodName)) {
1368
                r.add((SimpleFunctionDescriptor) function);
1369
            }
1370
        }
1371
        return r;
1372 1373
    }

1374
    private ResolverScopeData getResolverScopeData(@NotNull ClassOrNamespaceDescriptor owner, PsiClassWrapper psiClass) {
1375
        // TODO: store scopeData in Java*Scope
1376
        ResolverScopeData scopeData;
1377
        boolean staticMembers;
1378 1379
        if (owner instanceof JavaNamespaceDescriptor) {
            scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName());
1380
            staticMembers = true;
1381
        } else if (owner instanceof ClassDescriptor) {
S
Stepan Koltsov 已提交
1382
            scopeData = classDescriptorCache.get(new FqName(psiClass.getQualifiedName()));
1383
            staticMembers = false;
1384
        } else {
1385
            throw new IllegalStateException("unknown owner: " + owner.getClass().getName());
1386 1387 1388 1389 1390
        }
        if (scopeData == null) {
            throw new IllegalStateException();
        }
        
1391 1392
        if (scopeData.namedMembersMap == null) {
            scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(psiClass, staticMembers, scopeData.kotlin);
1393 1394
        }
        
1395
        return scopeData;
1396
    }
A
Andrey Breslav 已提交
1397

A
Andrey Breslav 已提交
1398
    @NotNull
1399
    public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull PsiClass psiClass, @NotNull String methodName, boolean staticMembers) {
A
Andrey Breslav 已提交
1400

1401
        ResolverScopeData resolverScopeData = getResolverScopeData(descriptor, new PsiClassWrapper(psiClass));
A
Andrey Breslav 已提交
1402

1403 1404 1405
        Map<String, NamedMembers> namedMembersMap = resolverScopeData.namedMembersMap;

        NamedMembers namedMembers = namedMembersMap.get(methodName);
1406 1407
        if (namedMembers != null && namedMembers.methods != null) {
            TypeSubstitutor typeSubstitutor = typeSubstitutorForGenericSupertypes(resolverScopeData);
1408

1409 1410 1411
            resolveNamedGroupFunctions(descriptor, psiClass, typeSubstitutor, namedMembers, methodName, resolverScopeData);

            return namedMembers.functionDescriptors;
1412
        } else {
1413
            return Collections.emptySet();
1414
        }
1415 1416
    }

1417
    private TypeSubstitutor createSubstitutorForGenericSupertypes(@Nullable ClassDescriptor classDescriptor) {
A
Andrey Breslav 已提交
1418 1419 1420 1421 1422 1423 1424 1425 1426
        TypeSubstitutor typeSubstitutor;
        if (classDescriptor != null) {
            typeSubstitutor = TypeUtils.buildDeepSubstitutor(classDescriptor.getDefaultType());
        }
        else {
            typeSubstitutor = TypeSubstitutor.EMPTY;
        }
        return typeSubstitutor;
    }
1427

1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451
    private ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration,
            List<PsiParameterWrapper> parameters, TypeVariableResolver typeVariableResolver) {
        List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
        JetType receiverType = null;
        int indexDelta = 0;
        for (int i = 0, parametersLength = parameters.size(); i < parametersLength; i++) {
            PsiParameterWrapper parameter = parameters.get(i);
            JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i + indexDelta, parameter, typeVariableResolver);
            if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
                // TODO
                --indexDelta;
            } else if (meaning.kind == JvmMethodParameterKind.REGULAR) {
                result.add(meaning.valueParameterDescriptor);
            } else if (meaning.kind == JvmMethodParameterKind.RECEIVER) {
                if (receiverType != null) {
                    throw new IllegalStateException("more then one receiver");
                }
                --indexDelta;
                receiverType = meaning.receiverType;
            }
        }
        return new ValueParameterDescriptors(receiverType, result);
    }

A
Andrey Breslav 已提交
1452
    @Nullable
S
Stepan Koltsov 已提交
1453
    private FunctionDescriptorImpl resolveMethodToFunctionDescriptor(ClassOrNamespaceDescriptor owner, final PsiClass psiClass, final PsiMethodWrapper method) {
1454

1455
        PsiType returnType = method.getReturnType();
A
Andrey Breslav 已提交
1456 1457 1458
        if (returnType == null) {
            return null;
        }
1459 1460
        ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));

1461 1462 1463 1464 1465 1466 1467 1468 1469
        boolean kotlin;
        if (owner instanceof JavaNamespaceDescriptor) {
            JavaNamespaceDescriptor javaNamespaceDescriptor = (JavaNamespaceDescriptor) owner;
            ResolverNamespaceData namespaceData = namespaceDescriptorCacheByFqn.get(javaNamespaceDescriptor.getQualifiedName());
            if (namespaceData == null) {
                throw new IllegalStateException("namespaceData not found by name " + javaNamespaceDescriptor.getQualifiedName());
            }
            kotlin = namespaceData.kotlin;
        } else {
S
Stepan Koltsov 已提交
1470
            ResolverBinaryClassData classData = classDescriptorCache.get(new FqName(psiClass.getQualifiedName()));
1471 1472 1473 1474 1475 1476
            if (classData == null) {
                throw new IllegalStateException("classData not found by name " + psiClass.getQualifiedName());
            }
            kotlin = classData.kotlin;
        }

1477
        // TODO: ugly
1478
        if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
1479
            return null;
1480
        }
1481

S
Stepan Koltsov 已提交
1482 1483 1484 1485 1486 1487 1488 1489
        if (kotlin) {
            // TODO: unless maybe class explicitly extends Object
            String ownerClassName = method.getPsiMethod().getContainingClass().getQualifiedName();
            if (ownerClassName.equals("java.lang.Object")) {
                return null;
            }
        }

1490
        ClassOrNamespaceDescriptor classDescriptor;
1491
        if (scopeData instanceof ResolverBinaryClassData) {
1492
            ClassDescriptor classClassDescriptor = resolveClass(method.getPsiMethod().getContainingClass(), DescriptorSearchRule.INCLUDE_KOTLIN);
1493
            classDescriptor = classClassDescriptor;
1494 1495 1496
        }
        else {
            classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass());
1497
        }
1498 1499 1500
        if (classDescriptor == null) {
            return null;
        }
1501

1502
        SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl(
A
Andrey Breslav 已提交
1503
                owner,
1504
                resolveAnnotations(method.getPsiMethod()),
1505 1506
                method.getName(),
                CallableMemberDescriptor.Kind.DECLARATION
A
Andrey Breslav 已提交
1507
        );
1508

S
Stepan Koltsov 已提交
1509 1510 1511
        String context = "method " + method.getName() + " in class " + psiClass.getQualifiedName();

        final TypeVariableResolver typeVariableResolverForParameters = TypeVariableResolvers.classTypeVariableResolver(classDescriptor, context);
1512

1513
        final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters);
1514

S
Stepan Koltsov 已提交
1515
        TypeVariableResolver methodTypeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(methodTypeParameters, functionDescriptorImpl, context);
1516 1517


1518
        ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver);
A
Andrey Breslav 已提交
1519
        functionDescriptorImpl.initialize(
1520
                valueParameterDescriptors.receiverType,
A
Andrey Breslav 已提交
1521
                DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
1522
                methodTypeParameters,
1523
                valueParameterDescriptors.descriptors,
1524
                makeReturnType(returnType, method, methodTypeVariableResolver),
1525 1526
                Modality.convertFromFlags(method.getPsiMethod().hasModifierProperty(PsiModifier.ABSTRACT), !method.isFinal()),
                resolveVisibilityFromPsiModifiers(method.getPsiMethod())
A
Andrey Breslav 已提交
1527
        );
1528
        semanticServices.getTrace().record(BindingContext.FUNCTION, method.getPsiMethod(), functionDescriptorImpl);
A
Andrey Breslav 已提交
1529
        FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
S
Stepan Koltsov 已提交
1530 1531
        if (method.getPsiMethod().getContainingClass() != psiClass && !method.isStatic()) {
            throw new IllegalStateException("non-static method in subclass");
A
Andrey Breslav 已提交
1532
        }
1533
        return (FunctionDescriptorImpl) substitutedFunctionDescriptor;
A
Andrey Breslav 已提交
1534
    }
1535

1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557
    private List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner) {
        PsiAnnotation[] psiAnnotations = owner.getModifierList().getAnnotations();
        List<AnnotationDescriptor> r = Lists.newArrayListWithCapacity(psiAnnotations.length);
        for (PsiAnnotation psiAnnotation : psiAnnotations) {
            AnnotationDescriptor annotation = resolveAnnotation(psiAnnotation);
            if (annotation != null) {
                r.add(annotation);
            }
        }
        return r;
    }

    @Nullable
    private AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation) {
        AnnotationDescriptor annotation = new AnnotationDescriptor();

        String qname = psiAnnotation.getQualifiedName();
        if (qname.startsWith("java.lang.annotation.") || qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName())) {
            // TODO
            return null;
        }

1558
        ClassDescriptor clazz = resolveClass(new FqName(psiAnnotation.getQualifiedName()), DescriptorSearchRule.INCLUDE_KOTLIN);
1559 1560 1561 1562
        if (clazz == null) {
            return null;
        }
        annotation.setAnnotationType(clazz.getDefaultType());
1563
        ArrayList<CompileTimeConstant<?>> valueArguments = new ArrayList<CompileTimeConstant<?>>();
1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591

        PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList();
        for (PsiNameValuePair psiNameValuePair : parameterList.getAttributes()) {
            PsiAnnotationMemberValue value = psiNameValuePair.getValue();
            // todo
            assert value instanceof PsiLiteralExpression;
            Object literalValue = ((PsiLiteralExpression) value).getValue();
            if(literalValue instanceof String)
                valueArguments.add(new StringValue((String) literalValue));
            else if(literalValue instanceof Byte)
                valueArguments.add(new ByteValue((Byte) literalValue));
            else if(literalValue instanceof Short)
                valueArguments.add(new ShortValue((Short) literalValue));
            else if(literalValue instanceof Character)
                valueArguments.add(new CharValue((Character) literalValue));
            else if(literalValue instanceof Integer)
                valueArguments.add(new IntValue((Integer) literalValue));
            else if(literalValue instanceof Long)
                valueArguments.add(new LongValue((Long) literalValue));
            else if(literalValue instanceof Float)
                valueArguments.add(new FloatValue((Float) literalValue));
            else if(literalValue instanceof Double)
                valueArguments.add(new DoubleValue((Double) literalValue));
            else if(literalValue == null)
                valueArguments.add(NullValue.NULL);
        }

        annotation.setValueArguments(valueArguments); // TODO
1592 1593 1594
        return annotation;
    }

1595
    public List<FunctionDescriptor> resolveMethods(@NotNull PsiClass psiClass, @NotNull ClassOrNamespaceDescriptor containingDeclaration) {
1596 1597
        ResolverScopeData scopeData = getResolverScopeData(containingDeclaration, new PsiClassWrapper(psiClass));

1598
        TypeSubstitutor substitutorForGenericSupertypes = typeSubstitutorForGenericSupertypes(scopeData);
1599

1600
        List<FunctionDescriptor> functions = new ArrayList<FunctionDescriptor>();
1601 1602 1603 1604 1605

        for (Map.Entry<String, NamedMembers> entry : scopeData.namedMembersMap.entrySet()) {
            String methodName = entry.getKey();
            NamedMembers namedMembers = entry.getValue();
            resolveNamedGroupFunctions(containingDeclaration, psiClass, substitutorForGenericSupertypes, namedMembers, methodName, scopeData);
1606
            functions.addAll(namedMembers.functionDescriptors);
1607
        }
1608

1609 1610
        return functions;
    }
1611

1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629
    private Collection<JetType> getSupertypes(ResolverScopeData scope) {
        if (scope instanceof ResolverBinaryClassData) {
            return ((ResolverBinaryClassData) scope).classDescriptor.getSupertypes();
        } else if (scope instanceof ResolverNamespaceData) {
            return Collections.emptyList();
        } else {
            throw new IllegalStateException();
        }
    }

    private TypeSubstitutor typeSubstitutorForGenericSupertypes(ResolverScopeData scopeData) {
        if (scopeData instanceof ResolverClassData) {
            return createSubstitutorForGenericSupertypes(((ResolverClassData) scopeData).getClassDescriptor());
        } else {
            return TypeSubstitutor.EMPTY;
        }
    }

1630
    private List<TypeParameterDescriptor> resolveMethodTypeParameters(
1631
            @NotNull PsiMethodWrapper method,
1632
            @NotNull DeclarationDescriptor functionDescriptor,
1633 1634
            @NotNull TypeVariableResolver classTypeVariableResolver) {

1635
        List<TypeParameterDescriptorInitialization> typeParametersIntialization;
1636
        if (method.getJetMethod().typeParameters().length() > 0) {
1637
            typeParametersIntialization = resolveMethodTypeParametersFromJetSignature(
S
Stepan Koltsov 已提交
1638
                    method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor);
1639
        } else {
1640
            typeParametersIntialization = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters());
1641
        }
1642

S
Stepan Koltsov 已提交
1643 1644
        String context = "method " + method.getName() + " in class " + method.getPsiMethod().getContainingClass().getQualifiedName();
        initializeTypeParameters(typeParametersIntialization, functionDescriptor, context);
1645 1646 1647 1648 1649 1650 1651
        
        List<TypeParameterDescriptor> typeParameters = Lists.newArrayListWithCapacity(typeParametersIntialization.size());
        
        for (TypeParameterDescriptorInitialization tpdi : typeParametersIntialization) {
            typeParameters.add(tpdi.descriptor);
        }
        
1652 1653
        return typeParameters;
    }
1654 1655

    /**
S
Stepan Koltsov 已提交
1656
     * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, org.jetbrains.jet.lang.descriptors.ClassDescriptor)
1657
     */
S
Stepan Koltsov 已提交
1658 1659
    private List<TypeParameterDescriptorInitialization> resolveMethodTypeParametersFromJetSignature(String jetSignature,
            final PsiMethod method, final DeclarationDescriptor functionDescriptor)
1660
    {
S
Stepan Koltsov 已提交
1661 1662
        String context = "method " + method.getName() + " in class " + method.getContainingClass().getQualifiedName();
        JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(functionDescriptor, method, context);
1663 1664
        new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(jetSignatureTypeParametersVisitor);
        return jetSignatureTypeParametersVisitor.r;
1665 1666
    }

1667 1668
    private JetType makeReturnType(PsiType returnType, PsiMethodWrapper method,
            @NotNull TypeVariableResolver typeVariableResolver) {
1669 1670 1671

        String returnTypeFromAnnotation = method.getJetMethod().returnType();

S
Stepan Koltsov 已提交
1672
        JetType transformedType;
1673
        if (returnTypeFromAnnotation.length() > 0) {
1674
            transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver);
S
Stepan Koltsov 已提交
1675
        } else {
1676
            transformedType = semanticServices.getTypeTransformer().transformToType(returnType, typeVariableResolver);
S
Stepan Koltsov 已提交
1677
        }
1678 1679
        if (method.getJetMethod().returnTypeNullable()) {
            return TypeUtils.makeNullableAsSpecified(transformedType, true);
S
Stepan Koltsov 已提交
1680 1681
        } else if (method.getPsiMethod().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName()) != null) {
            return TypeUtils.makeNullableAsSpecified(transformedType, false);
1682 1683 1684 1685 1686
        } else {
            return transformedType;
        }
    }

1687
    private static Visibility resolveVisibilityFromPsiModifiers(PsiModifierListOwner modifierListOwner) {
1688 1689 1690 1691 1692 1693
        //TODO report error
        return modifierListOwner.hasModifierProperty(PsiModifier.PUBLIC) ? Visibility.PUBLIC :
                                        (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE) ? Visibility.PRIVATE :
                                        (modifierListOwner.hasModifierProperty(PsiModifier.PROTECTED) ? Visibility.PROTECTED : Visibility.INTERNAL));
    }

1694
    public List<ClassDescriptor> resolveInnerClasses(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) {
1695 1696 1697 1698
        if (staticMembers) {
            return new ArrayList<ClassDescriptor>(0);
        }

1699 1700 1701
        PsiClass[] innerPsiClasses = psiClass.getInnerClasses();
        List<ClassDescriptor> r = new ArrayList<ClassDescriptor>(innerPsiClasses.length);
        for (PsiClass innerPsiClass : innerPsiClasses) {
1702 1703 1704 1705
            if (innerPsiClass.hasModifierProperty(PsiModifier.PRIVATE)) {
                // TODO: hack against inner classes
                continue;
            }
1706 1707 1708
            if (innerPsiClass.getName().equals(JvmAbi.CLASS_OBJECT_CLASS_NAME)) {
                continue;
            }
1709
            r.add(resolveClass(innerPsiClass, DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN));
1710 1711 1712
        }
        return r;
    }
1713
}