JavaDescriptorResolver.java 63.7 KB
Newer Older
1 2
package org.jetbrains.jet.lang.resolve.java;

3
import com.google.common.collect.Lists;
A
Andrey Breslav 已提交
4
import com.google.common.collect.Maps;
A
Andrey Breslav 已提交
5
import com.google.common.collect.Sets;
6
import com.intellij.openapi.project.Project;
7
import com.intellij.openapi.util.text.StringUtil;
8
import com.intellij.openapi.vfs.VirtualFile;
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
import com.intellij.psi.HierarchicalMethodSignature;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiEllipsisType;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeParameter;
import com.intellij.psi.PsiTypeParameterListOwner;
24
import com.intellij.psi.search.DelegatingGlobalSearchScope;
25
import com.intellij.psi.search.GlobalSearchScope;
26
import jet.typeinfo.TypeInfoVariance;
27 28
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
29 30 31 32 33 34 35 36 37 38 39
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.Modality;
import org.jetbrains.jet.lang.descriptors.NamedFunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
40 41
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
42 43 44 45 46
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.descriptors.Visibility;
A
Andrey Breslav 已提交
47
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
48
import org.jetbrains.jet.lang.resolve.BindingContext;
49
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
50 51 52 53 54 55 56
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructorImpl;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.Variance;
57
import org.jetbrains.jet.plugin.JetFileType;
58
import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
59 60 61
import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter;
import org.jetbrains.jet.rt.signature.JetSignatureReader;
import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
62

63 64 65 66 67 68
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
69 70 71 72 73

/**
 * @author abreslav
 */
public class JavaDescriptorResolver {
74 75
    
    public static String JAVA_ROOT = "<java_root>";
76

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

79 80
        @Override
        public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
81
            throw new UnsupportedOperationException();
82 83
        }

84 85
        @Override
        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
86
            return visitor.visitDeclarationDescriptor(this, data);
87 88 89
        }
    };

A
Andrey Breslav 已提交
90
    /*package*/ static final DeclarationDescriptor JAVA_CLASS_OBJECT = new DeclarationDescriptorImpl(null, Collections.<AnnotationDescriptor>emptyList(), "<java_class_object_emulation>") {
A
Andrey Breslav 已提交
91 92 93
        @NotNull
        @Override
        public DeclarationDescriptor substitute(TypeSubstitutor substitutor) {
94
            throw new UnsupportedOperationException();
A
Andrey Breslav 已提交
95 96 97 98 99 100 101
        }

        @Override
        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
            return visitor.visitDeclarationDescriptor(this, data);
        }
    };
102 103 104 105 106 107 108 109 110
    
    private enum TypeParameterDescriptorOrigin {
        JAVA,
        KOTLIN,
    }
    
    private static class TypeParameterDescriptorInitialization {
        private final TypeParameterDescriptorOrigin origin;
        private final TypeParameterDescriptor descriptor;
111 112 113 114
        @Nullable
        private final List<JetType> upperBoundsForKotlin;
        @Nullable
        private final List<JetType> lowerBoundsForKotlin;
115

116 117
        private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor) {
            this.origin = TypeParameterDescriptorOrigin.JAVA;
118
            this.descriptor = descriptor;
119 120 121 122 123 124 125 126 127 128
            this.upperBoundsForKotlin = null;
            this.lowerBoundsForKotlin = null;
        }

        private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor,
                List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
            this.origin = TypeParameterDescriptorOrigin.KOTLIN;
            this.descriptor = descriptor;
            this.upperBoundsForKotlin = upperBoundsForKotlin;
            this.lowerBoundsForKotlin = lowerBoundsForKotlin;
129 130
        }
    }
131 132 133 134
    
    private static abstract class ResolverScopeData {
        @Nullable
        private Set<VariableDescriptor> properties;
135
        protected boolean kotlin;
136
    }
A
Andrey Breslav 已提交
137

138
    private static class ResolverClassData extends ResolverScopeData {
139 140 141 142 143 144 145 146
        private JavaClassDescriptor classDescriptor;

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

147
    private static class ResolverNamespaceData extends ResolverScopeData {
148 149 150 151 152 153 154 155
        private JavaNamespaceDescriptor namespaceDescriptor;

        @NotNull
        public NamespaceDescriptor getNamespaceDescriptor() {
            return namespaceDescriptor;
        }
    }

156
    protected final Map<String, ResolverClassData> classDescriptorCache = Maps.newHashMap();
157 158 159
    protected final Map<String, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
    protected final Map<PsiElement, ResolverNamespaceData> namespaceDescriptorCache = Maps.newHashMap();

160
    private final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
A
Andrey Breslav 已提交
161
    protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
A
Andrey Breslav 已提交
162
    protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
163 164 165 166 167 168
    protected final JavaPsiFacade javaFacade;
    protected final GlobalSearchScope javaSearchScope;
    protected final JavaSemanticServices semanticServices;

    public JavaDescriptorResolver(Project project, JavaSemanticServices semanticServices) {
        this.javaFacade = JavaPsiFacade.getInstance(project);
169 170 171 172 173 174
        this.javaSearchScope = new DelegatingGlobalSearchScope(GlobalSearchScope.allScope(project)) {
            @Override
            public boolean contains(VirtualFile file) {
                return myBaseScope.contains(file) && file.getFileType() != JetFileType.INSTANCE;
            }
        };
175 176 177
        this.semanticServices = semanticServices;
    }

178
    @Nullable
179 180
    public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) {
        String qualifiedName = psiClass.getQualifiedName();
181

182 183 184 185
        if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
            // TODO: only if -$$TImpl class is created by Kotlin
            return null;
        }
186

187
        // First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
188 189 190 191 192
        ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
        if (kotlinClassDescriptor != null) {
            return kotlinClassDescriptor;
        }

193
        // Not let's take a descriptor of a Java class
194 195 196 197
        ResolverClassData classData = classDescriptorCache.get(qualifiedName);
        if (classData == null) {
            classData = createJavaClassDescriptor(psiClass);
            classDescriptorCache.put(qualifiedName, classData);
198
        }
199
        return classData.getClassDescriptor();
200 201 202 203
    }

    @Nullable
    public ClassDescriptor resolveClass(@NotNull String qualifiedName) {
204

205 206 207 208 209
        if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
            // TODO: only if -$$TImpl class is created by Kotlin
            return null;
        }
        
210
        // First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
211 212 213 214 215
        ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
        if (kotlinClassDescriptor != null) {
            return kotlinClassDescriptor;
        }

216
        // Not let's take a descriptor of a Java class
217 218
        ResolverClassData classData = classDescriptorCache.get(qualifiedName);
        if (classData == null) {
219
            PsiClass psiClass = findClass(qualifiedName);
220 221 222
            if (psiClass == null) {
                return null;
            }
223
            classData = createJavaClassDescriptor(psiClass);
224
        }
225
        return classData.getClassDescriptor();
226 227
    }

228
    private ResolverClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
A
Andrey Breslav 已提交
229 230 231
        assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName();
        classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO

232
        String name = psiClass.getName();
233 234
        ResolverClassData classData = new ResolverClassData();
        classData.classDescriptor = new JavaClassDescriptor(
235
                resolveParentDescriptor(psiClass), psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS
236
        );
237
        classData.classDescriptor.setName(name);
238
        
239 240 241 242 243 244 245 246 247
        class OuterClassTypeVariableResolver implements TypeVariableResolver {

            @NotNull
            @Override
            public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
                throw new IllegalStateException("not implemented"); // TODO
            }
        }

A
Andrey Breslav 已提交
248
        List<JetType> supertypes = new ArrayList<JetType>();
249 250 251
        List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classData, new OuterClassTypeVariableResolver());
        classData.classDescriptor.setTypeConstructor(new TypeConstructorImpl(
                classData.classDescriptor,
A
Andrey Breslav 已提交
252
                Collections.<AnnotationDescriptor>emptyList(), // TODO
253
                // TODO
254
                psiClass.hasModifierProperty(PsiModifier.FINAL),
A
Andrey Breslav 已提交
255
                name,
A
Andrey Breslav 已提交
256
                typeParameters,
A
Andrey Breslav 已提交
257 258
                supertypes
        ));
259
        classData.classDescriptor.setModality(Modality.convertFromFlags(
260 261
                psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
                !psiClass.hasModifierProperty(PsiModifier.FINAL))
A
Andrey Breslav 已提交
262
        );
263 264 265
        classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass));
        classDescriptorCache.put(psiClass.getQualifiedName(), classData);
        classData.classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false));
266

267 268
        // UGLY HACK (Andrey Breslav is not sure what did he mean)
        initializeTypeParameters(psiClass);
269

A
Andrey Breslav 已提交
270
        supertypes.addAll(getSupertypes(psiClass));
271
        if (psiClass.isInterface()) {
272
            //classData.classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object
273 274 275 276 277 278 279
        }
        else {
            PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
            assert extendsListTypes.length == 0 || extendsListTypes.length == 1;
            JetType superclassType = extendsListTypes.length == 0
                                            ? JetStandardClasses.getAnyType()
                                            : semanticServices.getTypeTransformer().transformToType(extendsListTypes[0]);
280
            //classData.classDescriptor.setSuperclassType(superclassType);
281
        }
A
Andrey Breslav 已提交
282 283

        PsiMethod[] psiConstructors = psiClass.getConstructors();
284 285

        if (psiConstructors.length == 0) {
A
Andrey Breslav 已提交
286 287 288 289 290
            // We need to create default constructors for classes and abstract classes.
            // Example:
            // class Kotlin() : Java() {}
            // abstract public class Java {}
            if (!psiClass.isInterface()) {
291
                ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
292
                        classData.classDescriptor,
A
Andrey Breslav 已提交
293
                        Collections.<AnnotationDescriptor>emptyList(),
294
                        false);
295 296 297
                constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), Modality.FINAL, classData.classDescriptor.getVisibility());
                constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
                classData.classDescriptor.addConstructor(constructorDescriptor);
298
                semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
299 300 301
            }
        }
        else {
302 303 304 305 306
            for (PsiMethod psiConstructor : psiConstructors) {
                PsiMethodWrapper constructor = new PsiMethodWrapper(psiConstructor);

                if (constructor.getJetConstructor().hidden()) {
                    continue;
307 308
                }

309
                ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
310
                        classData.classDescriptor,
A
Andrey Breslav 已提交
311
                        Collections.<AnnotationDescriptor>emptyList(), // TODO
312
                        false);
313
                ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
314
                        constructor.getParameters(),
315 316
                        new TypeParameterListTypeVariableResolver(typeParameters) // TODO: outer too
                    );
317 318 319 320
                if (valueParameterDescriptors.receiverType != null) {
                    throw new IllegalStateException();
                }
                constructorDescriptor.initialize(typeParameters, valueParameterDescriptors.descriptors, Modality.FINAL,
321
                                                 resolveVisibilityFromPsiModifiers(psiConstructor));
322 323
                constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType());
                classData.classDescriptor.addConstructor(constructorDescriptor);
324
                semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiConstructor, constructorDescriptor);
325
            }
A
Andrey Breslav 已提交
326
        }
327

328
        semanticServices.getTrace().record(BindingContext.CLASS, psiClass, classData.classDescriptor);
329

330
        return classData;
331 332
    }

333
    private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, ResolverClassData classData, TypeVariableResolver typeVariableResolver) {
334 335 336 337 338 339
        JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
        classData.kotlin = jetClassAnnotation.isDefined();
        
        if (jetClassAnnotation.signature().length() > 0) {
            return resolveClassTypeParametersFromJetSignature(
                    jetClassAnnotation.signature(), psiClass, classData.classDescriptor, typeVariableResolver);
340
        }
341

342
        return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters());
343 344
    }

345
    @NotNull
346
    private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) {
347 348 349 350 351
        for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) {
            if (typeParameter.getName().equals(name)) {
                return typeParameter; 
            }
        }
352 353 354
        throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found");
    }

S
Stepan Koltsov 已提交
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371

    // cache
    protected ClassDescriptor javaLangObject;

    @NotNull
    private ClassDescriptor getJavaLangObject() {
        if (javaLangObject == null) {
            javaLangObject = resolveClass("java.lang.Object");
        }
        return javaLangObject;
    }

    private boolean isJavaLangObject(JetType type) {
        return type.getConstructor().getDeclarationDescriptor() == getJavaLangObject();
    }


372 373 374 375 376
    private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter {
        
        private final DeclarationDescriptor containingDeclaration;
        private final PsiTypeParameterListOwner psiOwner;
        private final String name;
377
        private final int index;
378
        private final TypeInfoVariance variance;
379
        private final TypeVariableResolver typeVariableResolver;
380 381

        protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner,
382
                String name, int index, TypeInfoVariance variance, TypeVariableResolver typeVariableResolver)
383
        {
384 385 386 387
            if (name.isEmpty()) {
                throw new IllegalStateException();
            }
            
388 389 390
            this.containingDeclaration = containingDeclaration;
            this.psiOwner = psiOwner;
            this.name = name;
391
            this.index = index;
392
            this.variance = variance;
393
            this.typeVariableResolver = typeVariableResolver;
394 395 396 397
        }

        List<JetType> upperBounds = new ArrayList<JetType>();
        List<JetType> lowerBounds = new ArrayList<JetType>();
S
Stepan Koltsov 已提交
398
        
399 400
        @Override
        public JetSignatureVisitor visitClassBound() {
401
            return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
402 403
                @Override
                protected void done(@NotNull JetType jetType) {
S
Stepan Koltsov 已提交
404 405 406
                    if (isJavaLangObject(jetType)) {
                        return;
                    }
407 408 409 410 411 412 413
                    upperBounds.add(jetType);
                }
            };
        }

        @Override
        public JetSignatureVisitor visitInterfaceBound() {
414
            return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) {
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
                @Override
                protected void done(@NotNull JetType jetType) {
                    upperBounds.add(jetType);
                }
            };
        }

        @Override
        public void visitFormalTypeParameterEnd() {
            TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification(
                    containingDeclaration,
                    Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
                    true, // TODO: wrong
                    JetSignatureUtils.translateVariance(variance),
                    name,
430
                    index);
431 432 433 434 435 436
            PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name);
            typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameter, upperBounds, lowerBounds));
            done(typeParameter);
        }
        
        protected abstract void done(TypeParameterDescriptor typeParameterDescriptor);
437 438
    }

439 440 441
    /**
     * @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor)
     */
442 443
    private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz,
            final JavaClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) {
444
        final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
        
        class MyTypeVariableResolver implements TypeVariableResolver {

            @NotNull
            @Override
            public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
                for (TypeParameterDescriptor typeParameter : r) {
                    if (typeParameter.getName().equals(name)) {
                        return typeParameter;
                    }
                }
                return outerClassTypeVariableResolver.getTypeVariable(name);
            }
        }
        
460
        new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() {
461 462
            private int formalTypeParameterIndex = 0;
            
463 464
            @Override
            public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
465
                return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, formalTypeParameterIndex++, variance, new MyTypeVariableResolver()) {
466
                    @Override
467 468
                    protected void done(TypeParameterDescriptor typeParameterDescriptor) {
                        r.add(typeParameterDescriptor);
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
                    }
                };
            }

            @Override
            public JetSignatureVisitor visitSuperclass() {
                // TODO
                return new JetSignatureAdapter();
            }

            @Override
            public JetSignatureVisitor visitInterface() {
                // TODO
                return new JetSignatureAdapter();
            }
        });
        return r;
    }

488 489 490
    private DeclarationDescriptor resolveParentDescriptor(PsiClass psiClass) {
        PsiClass containingClass = psiClass.getContainingClass();
        if (containingClass != null) {
491
            return resolveClass(containingClass);
492 493 494 495 496 497 498
        }
        
        PsiJavaFile containingFile = (PsiJavaFile) psiClass.getContainingFile();
        String packageName = containingFile.getPackageName();
        return resolveNamespace(packageName);
    }

499
    private List<TypeParameterDescriptor> makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) {
500 501
        List<TypeParameterDescriptor> result = Lists.newArrayList();
        for (PsiTypeParameter typeParameter : typeParameters) {
502
            TypeParameterDescriptor typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter);
A
Andrey Breslav 已提交
503
            result.add(typeParameterDescriptor);
504 505 506 507
        }
        return result;
    }

508 509 510
    @NotNull
    private TypeParameterDescriptor makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
        assert typeParameterDescriptorCache.get(psiTypeParameter) == null : psiTypeParameter.getText();
511
        TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
512
                containingDeclaration,
A
Andrey Breslav 已提交
513
                Collections.<AnnotationDescriptor>emptyList(), // TODO
A
Andrey Breslav 已提交
514
                false,
515
                Variance.INVARIANT,
516 517
                psiTypeParameter.getName(),
                psiTypeParameter.getIndex()
518
        );
519
        typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameterDescriptor));
520 521 522
        return typeParameterDescriptor;
    }

523 524 525
    private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) {
        TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor;
        if (typeParameterDescriptorInitialization.origin == TypeParameterDescriptorOrigin.KOTLIN) {
526 527 528 529 530 531 532 533 534 535
            List<?> upperBounds = typeParameterDescriptorInitialization.upperBoundsForKotlin;
            if (upperBounds.size() == 0){
                typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
            } else {
                for (JetType upperBound : typeParameterDescriptorInitialization.upperBoundsForKotlin) {
                    typeParameterDescriptor.addUpperBound(upperBound);
                }
            }

            // TODO: lower bounds
536 537 538 539 540 541 542 543 544 545 546 547
        } else {
            PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes();
            if (referencedTypes.length == 0){
                typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
            }
            else if (referencedTypes.length == 1) {
                typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0]));
            }
            else {
                for (PsiClassType referencedType : referencedTypes) {
                    typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType));
                }
A
Andrey Breslav 已提交
548 549
            }
        }
550
        typeParameterDescriptor.setInitialized();
551 552 553 554
    }

    private void initializeTypeParameters(PsiTypeParameterListOwner typeParameterListOwner) {
        for (PsiTypeParameter psiTypeParameter : typeParameterListOwner.getTypeParameters()) {
555
            initializeTypeParameter(psiTypeParameter, resolveTypeParameterInitialization(psiTypeParameter));
556
        }
A
Andrey Breslav 已提交
557 558 559
    }

    @NotNull
560 561
    private TypeParameterDescriptorInitialization resolveTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
        TypeParameterDescriptorInitialization typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
S
Stepan Koltsov 已提交
562 563 564 565
        if (typeParameterDescriptor == null) {
            // TODO: report properly without crashing compiler
            throw new IllegalStateException("failed to resolve type parameter: " + psiTypeParameter.getName());
        }
A
Andrey Breslav 已提交
566 567 568
        return typeParameterDescriptor;
    }

A
Andrey Breslav 已提交
569 570
    private Collection<? extends JetType> getSupertypes(PsiClass psiClass) {
        List<JetType> result = new ArrayList<JetType>();
571 572 573 574 575 576
        result.add(JetStandardClasses.getAnyType());
        transformSupertypeList(result, psiClass.getExtendsListTypes());
        transformSupertypeList(result, psiClass.getImplementsListTypes());
        return result;
    }

A
Andrey Breslav 已提交
577
    private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes) {
578
        for (PsiClassType type : extendsListTypes) {
A
Andrey Breslav 已提交
579
            JetType transform = semanticServices.getTypeTransformer().transformToType(type);
580 581 582 583 584

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

585
    public NamespaceDescriptor resolveNamespace(String qualifiedName) {
586 587 588 589 590 591
        // First, let's check that there is no Kotlin package:
        NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(qualifiedName);
        if (kotlinNamespaceDescriptor != null) {
            return kotlinNamespaceDescriptor;
        }

592
        PsiPackage psiPackage = findPackage(qualifiedName);
593
        if (psiPackage == null) {
594
            PsiClass psiClass = findClass(qualifiedName);
A
Andrey Breslav 已提交
595 596
            if (psiClass == null) return null;
            return resolveNamespace(psiClass);
597 598 599 600
        }
        return resolveNamespace(psiPackage);
    }

601 602 603 604
    private PsiClass findClass(String qualifiedName) {
        return javaFacade.findClass(qualifiedName, javaSearchScope);
    }

605
    /*package*/ PsiPackage findPackage(String qualifiedName) {
606 607 608
        return javaFacade.findPackage(qualifiedName);
    }

609
    private NamespaceDescriptor resolveNamespace(@NotNull PsiPackage psiPackage) {
610 611 612 613 614
        ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiPackage);
        if (namespaceData == null) {
            namespaceData = createJavaNamespaceDescriptor(psiPackage);
            namespaceDescriptorCache.put(psiPackage, namespaceData);
            namespaceDescriptorCacheByFqn.put(psiPackage.getQualifiedName(), namespaceData);
615
        }
616
        return namespaceData.namespaceDescriptor;
617 618
    }

A
Andrey Breslav 已提交
619
    private NamespaceDescriptor resolveNamespace(@NotNull PsiClass psiClass) {
620 621 622 623 624
        ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiClass);
        if (namespaceData == null) {
            namespaceData = createJavaNamespaceDescriptor(psiClass);
            namespaceDescriptorCache.put(psiClass, namespaceData);
            namespaceDescriptorCacheByFqn.put(psiClass.getQualifiedName(), namespaceData);
A
Andrey Breslav 已提交
625
        }
626
        return namespaceData.namespaceDescriptor;
A
Andrey Breslav 已提交
627 628
    }

629 630
    private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull PsiPackage psiPackage) {
        ResolverNamespaceData namespaceData = new ResolverNamespaceData();
631
        String name = psiPackage.getName();
632
        namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor(
633
                resolveParentDescriptor(psiPackage),
A
Andrey Breslav 已提交
634
                Collections.<AnnotationDescriptor>emptyList(), // TODO
635 636
                name == null ? JAVA_ROOT : name,
                name == null ? JAVA_ROOT : psiPackage.getQualifiedName()
637
        );
638

639 640 641 642 643
        namespaceData.namespaceDescriptor.setMemberScope(new JavaPackageScope(psiPackage.getQualifiedName(), namespaceData.namespaceDescriptor, semanticServices));
        semanticServices.getTrace().record(BindingContext.NAMESPACE, psiPackage, namespaceData.namespaceDescriptor);
        // TODO: hack
        namespaceData.kotlin = true;
        return namespaceData;
644 645
    }

646 647 648 649 650 651 652 653
    private DeclarationDescriptor resolveParentDescriptor(@NotNull PsiPackage psiPackage) {
        PsiPackage parentPackage = psiPackage.getParentPackage();
        if (parentPackage == null) {
            return null;
        }
        return resolveNamespace(parentPackage);
    }

654 655 656
    private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) {
        ResolverNamespaceData namespaceData = new ResolverNamespaceData();
        namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor(
657
                resolveParentDescriptor(psiClass),
A
Andrey Breslav 已提交
658
                Collections.<AnnotationDescriptor>emptyList(), // TODO
659 660
                psiClass.getName(),
                psiClass.getQualifiedName()
661
        );
662 663 664
        namespaceData.namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true));
        semanticServices.getTrace().record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor);
        return namespaceData;
665
    }
666 667 668 669 670 671 672 673 674 675
    
    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;
        }
    }
676

677 678
    private ValueParameterDescriptors resolveParameterDescriptors(DeclarationDescriptor containingDeclaration,
            List<PsiParameterWrapper> parameters, TypeVariableResolver typeVariableResolver) {
679
        List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
680
        JetType receiverType = null;
681
        int indexDelta = 0;
682 683
        for (int i = 0, parametersLength = parameters.size(); i < parametersLength; i++) {
            PsiParameterWrapper parameter = parameters.get(i);
684
            JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i + indexDelta, parameter, typeVariableResolver);
685 686
            if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
                // TODO
687
                --indexDelta;
688 689 690 691 692 693
            } 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");
                }
694
                --indexDelta;
695
                receiverType = meaning.receiverType;
S
Stepan Koltsov 已提交
696
            }
697
        }
698
        return new ValueParameterDescriptors(receiverType, result);
699
    }
A
Andrey Breslav 已提交
700

701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
    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
734
    private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i,
735 736 737 738 739 740 741
            PsiParameterWrapper parameter, TypeVariableResolver typeVariableResolver) {

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

        PsiType psiType = parameter.getPsiParameter().getType();
742 743 744 745 746 747 748 749 750

        JetType varargElementType;
        if (psiType instanceof PsiEllipsisType) {
            PsiEllipsisType psiEllipsisType = (PsiEllipsisType) psiType;
            varargElementType = semanticServices.getTypeTransformer().transformToType(psiEllipsisType.getComponentType());
        }
        else {
            varargElementType = null;
        }
751

752
        boolean nullable = parameter.getJetValueParameter().nullable();
753

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

757 758
        if (parameter.getJetValueParameter().name().length() > 0) {
            name = parameter.getJetValueParameter().name();
759 760
        }
        
761 762 763 764
        String typeFromAnnotation = parameter.getJetValueParameter().type();
        boolean receiver = parameter.getJetValueParameter().receiver();
        boolean hasDefaultValue = parameter.getJetValueParameter().hasDefaultValue();

S
Stepan Koltsov 已提交
765
        JetType outType;
766
        if (typeFromAnnotation.length() > 0) {
767
            outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver);
S
Stepan Koltsov 已提交
768 769 770
        } else {
            outType = semanticServices.getTypeTransformer().transformToType(psiType);
        }
771 772 773 774 775 776 777 778
        if (receiver) {
            return JvmMethodParameterMeaning.receiver(outType);
        } else {
            return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl(
                    containingDeclaration,
                    i,
                    Collections.<AnnotationDescriptor>emptyList(), // TODO
                    name,
S
Stepan Koltsov 已提交
779
                    false,
780
                    nullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType,
781
                    hasDefaultValue,
782 783 784
                    varargElementType
            ));
        }
785 786
    }

787
    /*
A
Andrey Breslav 已提交
788 789 790 791 792 793 794 795 796
    public VariableDescriptor resolveFieldToVariableDescriptor(DeclarationDescriptor containingDeclaration, PsiField field) {
        VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
        if (variableDescriptor != null) {
            return variableDescriptor;
        }
        JetType type = semanticServices.getTypeTransformer().transformToType(field.getType());
        boolean isFinal = field.hasModifierProperty(PsiModifier.FINAL);
        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
                containingDeclaration,
A
Andrey Breslav 已提交
797
                Collections.<AnnotationDescriptor>emptyList(),
798
                Modality.FINAL,
799
                resolveVisibilityFromPsiModifiers(field),
A
Andrey Breslav 已提交
800 801
                !isFinal,
                null,
802
                DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
A
Andrey Breslav 已提交
803 804
                field.getName(),
                type);
805
        semanticServices.getTrace().record(BindingContext.VARIABLE, field, propertyDescriptor);
A
Andrey Breslav 已提交
806 807 808
        fieldDescriptorCache.put(field, propertyDescriptor);
        return propertyDescriptor;
    }
809 810 811 812 813
    */
    
    private static class PropertyKey {
        @NotNull
        private final String name;
814 815 816 817
        //@NotNull
        //private final PsiType type;
        //@Nullable
        //private final PsiType receiverType;
818

819
        private PropertyKey(@NotNull String name /*, @NotNull PsiType type, @Nullable PsiType receiverType */) {
820
            this.name = name;
821 822
            //this.type = type;
            //this.receiverType = receiverType;
823 824 825 826 827 828 829 830 831 832
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            PropertyKey that = (PropertyKey) o;

            if (!name.equals(that.name)) return false;
833 834 835
            //if (receiverType != null ? !receiverType.equals(that.receiverType) : that.receiverType != null)
            //    return false;
            //if (!type.equals(that.type)) return false;
836 837 838 839 840 841 842

            return true;
        }

        @Override
        public int hashCode() {
            int result = name.hashCode();
843 844
            //result = 31 * result + type.hashCode();
            //result = 31 * result + (receiverType != null ? receiverType.hashCode() : 0);
845 846 847 848 849
            return result;
        }
    }

    private static class MembersForProperty {
850 851 852 853 854 855
        private PsiFieldWrapper field;
        private PsiMethodWrapper setter;
        private PsiMethodWrapper getter;

        private PsiType type;
        private PsiType receiverType;
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
    }
    
    private Map<PropertyKey, MembersForProperty> getMembersForProperties(@NotNull PsiClass clazz, boolean staticMembers, boolean kotlin) {
        Map<PropertyKey, MembersForProperty> membersMap = Maps.newHashMap();
        if (!kotlin) {
            for (PsiField field : clazz.getFields()) {
                if (field.getModifierList().hasExplicitModifier(PsiModifier.STATIC) != staticMembers) {
                    continue;
                }

                if (field.hasModifierProperty(PsiModifier.PRIVATE)) {
                    continue;
                }

                MembersForProperty members = new MembersForProperty();
871 872 873
                members.field = new PsiFieldWrapper(field);
                members.type = field.getType();
                membersMap.put(new PropertyKey(field.getName() /*, field.getType(), null*/), members);
874 875 876
            }
        }
        
877 878 879 880
        for (PsiMethod psiMethod : clazz.getMethods()) {
            PsiMethodWrapper method = new PsiMethodWrapper(psiMethod);

            if (method.isStatic() != staticMembers) {
881 882 883
                continue;
            }

884
            if (method.isPrivate()) {
885 886 887 888
                continue;
            }

            // TODO: "is" prefix
889
            // TODO: remove getJavaClass
890 891
            if (psiMethod.getName().startsWith(JvmAbi.GETTER_PREFIX)) {

892
                // TODO: some java properties too
893
                if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
894 895 896 897 898 899 900

                    if (psiMethod.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD)) {
                        continue;
                    }

                    int i = 0;

901
                    PsiType receiverType;
902 903 904
                    if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) {
                        receiverType = method.getParameter(i).getPsiParameter().getType();
                        ++i;
905
                    } else {
906
                        receiverType = null;
907
                    }
908
                    
909 910 911
                    while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) {
                        // TODO: store is reified
                        ++i;
912
                    }
913 914 915 916 917 918
                    
                    if (i != method.getParameters().size()) {
                        // TODO: report error properly
                        throw new IllegalStateException();
                    }
                    
919
                    String propertyName = StringUtil.decapitalize(psiMethod.getName().substring(JvmAbi.GETTER_PREFIX.length()));
920
                    PropertyKey key = new PropertyKey(propertyName /*, psiMethod.getReturnType(), receiverType*/);
921 922 923 924 925
                    MembersForProperty members = membersMap.get(key);
                    if (members == null) {
                        members = new MembersForProperty();
                        membersMap.put(key, members);
                    }
926 927 928 929 930
                    members.getter = new PsiMethodWrapper(psiMethod);

                    // TODO: check conflicts with setter
                    members.type = psiMethod.getReturnType();
                    members.receiverType = receiverType;
931
                }
932 933
            } else if (psiMethod.getName().startsWith(JvmAbi.SETTER_PREFIX)) {

934
                if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
935
                    if (psiMethod.getParameterList().getParametersCount() == 0) {
936
                        // TODO: report error properly
937 938 939 940 941 942
                        throw new IllegalStateException();
                    }

                    int i = 0;

                    PsiType receiverType = null;
943 944 945 946
                    PsiParameterWrapper p1 = method.getParameter(0);
                    if (p1.getJetValueParameter().receiver()) {
                        receiverType = p1.getPsiParameter().getType();
                        ++i;
947
                    }
948
                    
949
                    while (i < method.getParameters().size() && method.getParameter(i).getJetTypeParameter().isDefined()) {
950 951 952
                        ++i;
                    }
                    
953
                    if (i + 1 != psiMethod.getParameterList().getParametersCount()) {
954 955 956
                        throw new IllegalStateException();
                    }
                    
957
                    PsiType propertyType = psiMethod.getParameterList().getParameters()[i].getType();
958

959
                    String propertyName = StringUtil.decapitalize(psiMethod.getName().substring(JvmAbi.SETTER_PREFIX.length()));
960
                    PropertyKey key = new PropertyKey(propertyName /*, propertyType, receiverType*/);
961 962 963 964 965
                    MembersForProperty members = membersMap.get(key);
                    if (members == null) {
                        members = new MembersForProperty();
                        membersMap.put(key, members);
                    }
966 967 968 969 970
                    members.setter = new PsiMethodWrapper(psiMethod);

                    // TODO: check conflicts with getter
                    members.type = propertyType;
                    members.receiverType = receiverType;
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
                }
            }
        }
        
        return membersMap;
    }
    
    public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) {
        Set<VariableDescriptor> r = Sets.newHashSet();
        // TODO: slow
        Set<VariableDescriptor> variables = resolveFieldGroup(owner, psiClass, staticMembers);
        for (VariableDescriptor variable : variables) {
            if (variable.getName().equals(fieldName)) {
                r.add(variable);
            }
        }
        return r;
    }

    @NotNull
    public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) {
        
        ResolverScopeData scopeData;
        if (owner instanceof JavaNamespaceDescriptor) {
            scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName());
        } else if (owner instanceof JavaClassDescriptor) {
            scopeData = classDescriptorCache.get(psiClass.getQualifiedName());
        } else {
            throw new IllegalStateException();
        }
        if (scopeData == null) {
            throw new IllegalStateException();
        }
        
        if (scopeData.properties != null) {
            return scopeData.properties;
        }
        
        Set<VariableDescriptor> descriptors = Sets.newHashSet();
1010 1011
        Map<PropertyKey, MembersForProperty> membersForProperties = getMembersForProperties(psiClass, staticMembers, scopeData.kotlin);
        for (Map.Entry<PropertyKey, MembersForProperty> entry : membersForProperties.entrySet()) {
1012 1013 1014 1015 1016
            //VariableDescriptor variableDescriptor = fieldDescriptorCache.get(field);
            //if (variableDescriptor != null) {
            //    return variableDescriptor;
            //}
            String propertyName = entry.getKey().name;
1017 1018
            PsiType propertyType = entry.getValue().type;
            PsiType receiverType = entry.getValue().receiverType;
1019 1020 1021 1022
            MembersForProperty members = entry.getValue();

            boolean isFinal;
            if (members.setter == null && members.getter == null) {
1023
                isFinal = false;
1024
            } else if (members.getter != null) {
1025
                isFinal = members.getter.isFinal();
1026
            } else if (members.setter != null) {
1027
                isFinal = members.setter.isFinal();
1028 1029 1030
            } else {
                isFinal = false;
            }
1031

1032
            PsiMemberWrapper anyMember;
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
            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();
            }
            
            boolean isVar;
            if (members.getter == null && members.setter == null) {
                isVar = true;
            } else {
                isVar = members.setter != null;
            }
            
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
                    owner,
                    Collections.<AnnotationDescriptor>emptyList(),
                    isFinal && !staticMembers ? Modality.FINAL : Modality.OPEN, // TODO: abstract
1054
                    resolveVisibilityFromPsiModifiers(anyMember.psiMember),
1055 1056
                    isVar,
                    false,
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
                    propertyName);
            
            PropertyGetterDescriptor getterDescriptor = null;
            PropertySetterDescriptor setterDescriptor = null;
            if (members.getter != null) {
                getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false);
            }
            if (members.setter != null) {
                setterDescriptor = new PropertySetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.OPEN, Visibility.PUBLIC, true, false);
            }
            
            propertyDescriptor.initialize(getterDescriptor, setterDescriptor);

            final List<TypeParameterDescriptor> classTypeParameters;
            if (anyMember instanceof PsiMethodWrapper && !anyMember.isStatic()) {
                classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters();
            } else {
                classTypeParameters = new ArrayList<TypeParameterDescriptor>(0);
            }
            TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters);

            List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(0);

            if (members.setter != null) {
                // call ugly code with side effects
                typeParameters = resolveMethodTypeParameters(members.setter, propertyDescriptor.getSetter(), typeVariableResolver);
            }
            if (members.getter != null) {
                // call ugly code with side effects
                typeParameters = resolveMethodTypeParameters(members.getter, propertyDescriptor.getGetter(), typeVariableResolver);
            }

            JetType receiverJetType;
            if (receiverType == null) {
                receiverJetType = null;
            } else {
                receiverJetType = semanticServices.getTypeTransformer().transformToType(receiverType);
            }

1096 1097
            JetType type = semanticServices.getTypeTransformer().transformToType(propertyType);

1098 1099 1100
            propertyDescriptor.setType(
                    type,
                    typeParameters,
1101
                    DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
                    receiverJetType
                );
            if (getterDescriptor != null) {
                getterDescriptor.initialize(type);
            }
            if (setterDescriptor != null) {
                // TODO: initialize
            }
            
            semanticServices.getTrace().record(BindingContext.VARIABLE, anyMember.psiMember, propertyDescriptor);
1112 1113 1114 1115 1116 1117
            //fieldDescriptorCache.put(field, propertyDescriptor);
            descriptors.add(propertyDescriptor);
        }
        scopeData.properties = descriptors;
        return descriptors;
    }
A
Andrey Breslav 已提交
1118

A
Andrey Breslav 已提交
1119
    @NotNull
A
Andrey Breslav 已提交
1120 1121
    public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor owner, @NotNull PsiClass psiClass, @Nullable ClassDescriptor classDescriptor, @NotNull String methodName, boolean staticMembers) {
        Set<FunctionDescriptor> writableFunctionGroup = Sets.newLinkedHashSet();
1122
        final Collection<HierarchicalMethodSignature> signatures = psiClass.getVisibleSignatures();
A
Andrey Breslav 已提交
1123
        TypeSubstitutor typeSubstitutor = createSubstitutorForGenericSupertypes(classDescriptor);
1124
        for (HierarchicalMethodSignature signature: signatures) {
1125
            if (!methodName.equals(signature.getName())) {
A
Andrey Breslav 已提交
1126 1127 1128
                 continue;
            }

1129
            FunctionDescriptor substitutedFunctionDescriptor = resolveHierarchicalSignatureToFunction(owner, psiClass, staticMembers, typeSubstitutor, signature);
1130
            if (substitutedFunctionDescriptor != null) {
A
Andrey Breslav 已提交
1131
                writableFunctionGroup.add(substitutedFunctionDescriptor);
1132
            }
A
Andrey Breslav 已提交
1133 1134 1135
        }
        return writableFunctionGroup;
    }
A
Andrey Breslav 已提交
1136

1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
    @Nullable
    private FunctionDescriptor resolveHierarchicalSignatureToFunction(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers, TypeSubstitutor typeSubstitutor, HierarchicalMethodSignature signature) {
        PsiMethod method = signature.getMethod();
        if (method.hasModifierProperty(PsiModifier.STATIC) != staticMembers) {
                return null;
        }
        FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(owner, psiClass, typeSubstitutor, method);
//        if (functionDescriptor != null && !staticMembers) {
//            for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) {
//                ((FunctionDescriptorImpl) functionDescriptor).addOverriddenFunction(resolveHierarchicalSignatureToFunction(owner, superSignature.getMethod().getContainingClass(), false, typeSubstitutor, superSignature));
//            }
//        }
        return functionDescriptor;
    }

A
Andrey Breslav 已提交
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162
    public TypeSubstitutor createSubstitutorForGenericSupertypes(ClassDescriptor classDescriptor) {
        TypeSubstitutor typeSubstitutor;
        if (classDescriptor != null) {
            typeSubstitutor = TypeUtils.buildDeepSubstitutor(classDescriptor.getDefaultType());
        }
        else {
            typeSubstitutor = TypeSubstitutor.EMPTY;
        }
        return typeSubstitutor;
    }

1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
    private static class TypeParameterListTypeVariableResolver implements TypeVariableResolver {

        private final List<TypeParameterDescriptor> typeParameters;

        private TypeParameterListTypeVariableResolver(List<TypeParameterDescriptor> typeParameters) {
            this.typeParameters = typeParameters;
        }

        @NotNull
        @Override
        public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
            for (TypeParameterDescriptor typeParameter : typeParameters) {
                if (typeParameter.getName().equals(name)) {
                    return typeParameter;
                }
            }
            throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly
        }
    }

A
Andrey Breslav 已提交
1183
    @Nullable
1184 1185 1186 1187
    public FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethod psiMethod) {
        PsiMethodWrapper method = new PsiMethodWrapper(psiMethod);
        
        PsiType returnType = psiMethod.getReturnType();
A
Andrey Breslav 已提交
1188 1189 1190
        if (returnType == null) {
            return null;
        }
1191
        FunctionDescriptor functionDescriptor = methodDescriptorCache.get(psiMethod);
A
Andrey Breslav 已提交
1192
        if (functionDescriptor != null) {
1193
            if (psiMethod.getContainingClass() != psiClass) {
A
Andrey Breslav 已提交
1194 1195 1196 1197
                functionDescriptor = functionDescriptor.substitute(typeSubstitutorForGenericSuperclasses);
            }
            return functionDescriptor;
        }
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214

        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 {
            ResolverClassData classData = classDescriptorCache.get(psiClass.getQualifiedName());
            if (classData == null) {
                throw new IllegalStateException("classData not found by name " + psiClass.getQualifiedName());
            }
            kotlin = classData.kotlin;
        }

1215
        // TODO: ugly
1216
        if (method.getJetMethod().kind() == JvmStdlibNames.JET_METHOD_KIND_PROPERTY) {
1217
            return null;
1218
        }
1219

S
Stepan Koltsov 已提交
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
        if (kotlin) {
            // TODO: unless maybe class explicitly extends Object
            String ownerClassName = method.getPsiMethod().getContainingClass().getQualifiedName();
            if (ownerClassName.equals("java.lang.Object")) {
                return null;
            }
            
            if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD) && method.getParameters().size() == 0) {
                return null;
            }
            
            if (method.getName().equals(JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD) && method.getParameters().size() == 0) {
                return null;
            }

            // TODO: check signature
            if (method.getName().equals(JvmAbi.SET_TYPE_INFO_METHOD)) {
                return null;
            }
        }

1241 1242
        DeclarationDescriptor classDescriptor;
        final List<TypeParameterDescriptor> classTypeParameters;
1243 1244
        if (method.isStatic()) {
            classDescriptor = resolveNamespace(psiMethod.getContainingClass());
1245 1246 1247
            classTypeParameters = Collections.emptyList();
        }
        else {
1248
            ClassDescriptor classClassDescriptor = resolveClass(psiMethod.getContainingClass());
1249 1250 1251
            classDescriptor = classClassDescriptor;
            classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters();
        }
1252 1253 1254
        if (classDescriptor == null) {
            return null;
        }
S
Stepan Koltsov 已提交
1255
        NamedFunctionDescriptorImpl functionDescriptorImpl = new NamedFunctionDescriptorImpl(
A
Andrey Breslav 已提交
1256 1257
                owner,
                Collections.<AnnotationDescriptor>emptyList(), // TODO
1258
                psiMethod.getName()
A
Andrey Breslav 已提交
1259
        );
1260
        methodDescriptorCache.put(psiMethod, functionDescriptorImpl);
1261 1262 1263 1264

        // TODO: add outer classes
        TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters);

1265
        final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(new PsiMethodWrapper(psiMethod), functionDescriptorImpl, typeVariableResolverForParameters);
1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286

        class MethodTypeVariableResolver implements TypeVariableResolver {

            @NotNull
            @Override
            public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
                for (TypeParameterDescriptor typeParameter : methodTypeParameters) {
                    if (typeParameter.getName().equals(name)) {
                        return typeParameter;
                    }
                }
                for (TypeParameterDescriptor typeParameter : classTypeParameters) {
                    if (typeParameter.getName().equals(name)) {
                        return typeParameter;
                    }
                }
                throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly
            }
        }


1287
        ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), new MethodTypeVariableResolver());
A
Andrey Breslav 已提交
1288
        functionDescriptorImpl.initialize(
1289
                valueParameterDescriptors.receiverType,
A
Andrey Breslav 已提交
1290
                DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
1291
                methodTypeParameters,
1292
                valueParameterDescriptors.descriptors,
1293
                makeReturnType(returnType, method, new MethodTypeVariableResolver()),
1294 1295
                Modality.convertFromFlags(psiMethod.hasModifierProperty(PsiModifier.ABSTRACT), !psiMethod.hasModifierProperty(PsiModifier.FINAL)),
                resolveVisibilityFromPsiModifiers(psiMethod)
A
Andrey Breslav 已提交
1296
        );
1297
        semanticServices.getTrace().record(BindingContext.FUNCTION, psiMethod, functionDescriptorImpl);
A
Andrey Breslav 已提交
1298
        FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
1299
        if (psiMethod.getContainingClass() != psiClass) {
A
Andrey Breslav 已提交
1300 1301 1302 1303
            substitutedFunctionDescriptor = functionDescriptorImpl.substitute(typeSubstitutorForGenericSuperclasses);
        }
        return substitutedFunctionDescriptor;
    }
1304

1305 1306 1307 1308
    private List<TypeParameterDescriptor> resolveMethodTypeParameters(
            @NotNull PsiMethodWrapper method,
            @NotNull FunctionDescriptor functionDescriptor,
            @NotNull TypeVariableResolver classTypeVariableResolver) {
1309
        if (method.getJetMethod().typeParameters().length() > 0) {
1310
            List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature(
1311
                    method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver);
1312
            initializeTypeParameters(method.getPsiMethod());
1313
            return r;
1314
        }
1315

1316 1317
        List<TypeParameterDescriptor> typeParameters = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters());
        initializeTypeParameters(method.getPsiMethod());
1318 1319
        return typeParameters;
    }
1320 1321

    /**
1322
     * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, JavaClassDescriptor) 
1323
     */
1324 1325 1326
    private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method,
            final FunctionDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver)
    {
1327
        final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>();
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
        
        class MyTypeVariableResolver implements TypeVariableResolver {

            @NotNull
            @Override
            public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
                for (TypeParameterDescriptor typeParameter : r) {
                    if (typeParameter.getName().equals(name)) {
                        return typeParameter;
                    }
                }
                return classTypeVariableResolver.getTypeVariable(name);
            }
        }
        
1343
        new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() {
1344 1345
            private int formalTypeParameterIndex = 0;
            
1346
            @Override
S
Stepan Koltsov 已提交
1347
            public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) {
1348
                
1349
                return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, formalTypeParameterIndex++, variance, new MyTypeVariableResolver()) {
1350
                    @Override
1351 1352
                    protected void done(TypeParameterDescriptor typeParameterDescriptor) {
                        r.add(typeParameterDescriptor);
1353 1354
                    }
                };
1355

1356 1357 1358 1359 1360
            }
        });
        return r;
    }

1361 1362 1363 1364
    private JetType makeReturnType(PsiType returnType, PsiMethodWrapper method, TypeVariableResolver typeVariableResolver) {

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

S
Stepan Koltsov 已提交
1365
        JetType transformedType;
1366
        if (returnTypeFromAnnotation.length() > 0) {
1367
            transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver);
S
Stepan Koltsov 已提交
1368 1369 1370
        } else {
            transformedType = semanticServices.getTypeTransformer().transformToType(returnType);
        }
1371 1372
        if (method.getJetMethod().returnTypeNullable()) {
            return TypeUtils.makeNullableAsSpecified(transformedType, true);
1373 1374 1375 1376 1377
        } else {
            return transformedType;
        }
    }

1378
    private static Visibility resolveVisibilityFromPsiModifiers(PsiModifierListOwner modifierListOwner) {
1379 1380 1381 1382 1383 1384
        //TODO report error
        return modifierListOwner.hasModifierProperty(PsiModifier.PUBLIC) ? Visibility.PUBLIC :
                                        (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE) ? Visibility.PRIVATE :
                                        (modifierListOwner.hasModifierProperty(PsiModifier.PROTECTED) ? Visibility.PROTECTED : Visibility.INTERNAL));
    }

1385 1386
    @NotNull
    private TypeParameterDescriptorInitialization resolveTypeParameterInitialization(PsiTypeParameter typeParameter) {
1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410
        PsiTypeParameterListOwner owner = typeParameter.getOwner();
        if (owner instanceof PsiClass) {
            PsiClass psiClass = (PsiClass) owner;
            return resolveTypeParameter(resolveClass(psiClass), typeParameter);
        }
        if (owner instanceof PsiMethod) {
            PsiMethod psiMethod = (PsiMethod) owner;
            PsiClass containingClass = psiMethod.getContainingClass();
            DeclarationDescriptor ownerOwner;
            TypeSubstitutor substitutorForGenericSupertypes;
            if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
                substitutorForGenericSupertypes = TypeSubstitutor.EMPTY;
                return resolveTypeParameter(JAVA_METHOD_TYPE_PARAMETER_PARENT, typeParameter);
            }
            else {
                ClassDescriptor classDescriptor = resolveClass(containingClass);
                ownerOwner = classDescriptor;
                substitutorForGenericSupertypes = semanticServices.getDescriptorResolver().createSubstitutorForGenericSupertypes(classDescriptor);
            }
            FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(ownerOwner, containingClass, substitutorForGenericSupertypes, psiMethod);
            return resolveTypeParameter(functionDescriptor, typeParameter);
        }
        throw new IllegalStateException("Unknown parent type: " + owner);
    }
1411 1412 1413 1414

    public TypeParameterDescriptor resolveTypeParameter(PsiTypeParameter typeParameter) {
        return resolveTypeParameterInitialization(typeParameter).descriptor;
    }
1415
}