001    /*
002     * Copyright 2010-2013 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.jet.lang.resolve;
018    
019    import com.google.common.collect.Lists;
020    import com.google.common.collect.Maps;
021    import com.intellij.lang.ASTNode;
022    import com.intellij.psi.PsiElement;
023    import com.intellij.psi.tree.IElementType;
024    import com.intellij.psi.util.PsiTreeUtil;
025    import org.jetbrains.annotations.NotNull;
026    import org.jetbrains.annotations.Nullable;
027    import org.jetbrains.jet.lang.descriptors.*;
028    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
029    import org.jetbrains.jet.lang.descriptors.impl.*;
030    import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1;
031    import org.jetbrains.jet.lang.psi.*;
032    import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
033    import org.jetbrains.jet.lang.resolve.name.Name;
034    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
035    import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
036    import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
037    import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
038    import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
039    import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
040    import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
041    import org.jetbrains.jet.lang.types.*;
042    import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
043    import org.jetbrains.jet.lang.types.expressions.DelegatedPropertyUtils;
044    import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
045    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
046    import org.jetbrains.jet.lexer.JetKeywordToken;
047    import org.jetbrains.jet.lexer.JetTokens;
048    import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue;
049    import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValueWithDefault;
050    
051    import javax.inject.Inject;
052    import java.util.*;
053    
054    import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
055    import static org.jetbrains.jet.lang.diagnostics.Errors.*;
056    import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR;
057    import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
058    import static org.jetbrains.jet.lang.resolve.ModifiersChecker.*;
059    import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD;
060    
061    public class DescriptorResolver {
062        public static final Name VALUE_OF_METHOD_NAME = Name.identifier("valueOf");
063        public static final Name VALUES_METHOD_NAME = Name.identifier("values");
064        public static final Name COPY_METHOD_NAME = Name.identifier("copy");
065        public static final String COMPONENT_FUNCTION_NAME_PREFIX = "component";
066    
067        @NotNull
068        private TypeResolver typeResolver;
069        @NotNull
070        private AnnotationResolver annotationResolver;
071        @NotNull
072        private ExpressionTypingServices expressionTypingServices;
073    
074        public static ReceiverParameterDescriptor resolveReceiverParameterFor(@NotNull CallableDescriptor owner, @Nullable JetType receiverParameterType) {
075            return receiverParameterType == null
076                                     ? NO_RECEIVER_PARAMETER
077                                     : new ReceiverParameterDescriptorImpl(owner, receiverParameterType, new ExtensionReceiver(owner, receiverParameterType));
078        }
079    
080        @Inject
081        public void setTypeResolver(@NotNull TypeResolver typeResolver) {
082            this.typeResolver = typeResolver;
083        }
084    
085        @Inject
086        public void setAnnotationResolver(@NotNull AnnotationResolver annotationResolver) {
087            this.annotationResolver = annotationResolver;
088        }
089    
090        @Inject
091        public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
092            this.expressionTypingServices = expressionTypingServices;
093        }
094    
095    
096        public void resolveMutableClassDescriptor(
097                @NotNull JetClass classElement,
098                @NotNull MutableClassDescriptor descriptor,
099                BindingTrace trace
100        ) {
101            // TODO : Where-clause
102            List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
103            int index = 0;
104            for (JetTypeParameter typeParameter : classElement.getTypeParameters()) {
105                // TODO: Support
106                AnnotationResolver.reportUnsupportedAnnotationForTypeParameter(typeParameter, trace);
107    
108                TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
109                        descriptor,
110                        Collections.<AnnotationDescriptor>emptyList(),
111                        typeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
112                        typeParameter.getVariance(),
113                        JetPsiUtil.safeName(typeParameter.getName()),
114                        index
115                );
116                trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
117                typeParameters.add(typeParameterDescriptor);
118                index++;
119            }
120            descriptor.setTypeParameterDescriptors(typeParameters);
121            Modality defaultModality = descriptor.getKind() == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
122            descriptor.setModality(resolveModalityFromModifiers(classElement, defaultModality));
123            descriptor.setVisibility(resolveVisibilityFromModifiers(classElement, getDefaultClassVisibility(descriptor)));
124    
125            trace.record(BindingContext.CLASS, classElement, descriptor);
126        }
127    
128        public void resolveSupertypesForMutableClassDescriptor(
129                @NotNull JetClassOrObject jetClass,
130                @NotNull MutableClassDescriptor descriptor,
131                BindingTrace trace
132        ) {
133            for (JetType supertype : resolveSupertypes(descriptor.getScopeForSupertypeResolution(), descriptor, jetClass, trace)) {
134                descriptor.addSupertype(supertype);
135            }
136        }
137    
138        public List<JetType> resolveSupertypes(
139                @NotNull JetScope scope,
140                @NotNull ClassDescriptor classDescriptor,
141                @NotNull JetClassOrObject jetClass,
142                BindingTrace trace
143        ) {
144            List<JetType> supertypes = Lists.newArrayList();
145            List<JetDelegationSpecifier> delegationSpecifiers = jetClass.getDelegationSpecifiers();
146            Collection<JetType> declaredSupertypes = resolveDelegationSpecifiers(
147                    scope,
148                    delegationSpecifiers,
149                    typeResolver, trace, false);
150    
151            for (JetType declaredSupertype : declaredSupertypes) {
152                addValidSupertype(supertypes, declaredSupertype);
153            }
154    
155            if (classDescriptor.getKind() == ClassKind.ENUM_CLASS && !containsClass(supertypes)) {
156                supertypes.add(0, KotlinBuiltIns.getInstance().getEnumType(classDescriptor.getDefaultType()));
157            }
158    
159            if (supertypes.isEmpty()) {
160                JetType defaultSupertype = getDefaultSupertype(jetClass, trace);
161                addValidSupertype(supertypes, defaultSupertype);
162            }
163    
164            return supertypes;
165        }
166    
167        private static void addValidSupertype(List<JetType> supertypes, JetType declaredSupertype) {
168            if (!ErrorUtils.isErrorType(declaredSupertype)) {
169                supertypes.add(declaredSupertype);
170            }
171        }
172    
173        private boolean containsClass(Collection<JetType> result) {
174            for (JetType type : result) {
175                ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
176                if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.TRAIT) {
177                    return true;
178                }
179            }
180            return false;
181        }
182    
183        private JetType getDefaultSupertype(JetClassOrObject jetClass, BindingTrace trace) {
184            // TODO : beautify
185            if (jetClass instanceof JetEnumEntry) {
186                JetClassOrObject parent = PsiTreeUtil.getParentOfType(jetClass, JetClassOrObject.class);
187                ClassDescriptor parentDescriptor = trace.getBindingContext().get(BindingContext.CLASS, parent);
188                if (parentDescriptor.getTypeConstructor().getParameters().isEmpty()) {
189                    return parentDescriptor.getDefaultType();
190                }
191                else {
192                    trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(jetClass.getNameIdentifier()));
193                    return ErrorUtils.createErrorType("Supertype not specified");
194                }
195            }
196            else if (jetClass instanceof JetClass && ((JetClass) jetClass).isAnnotation()) {
197                return KotlinBuiltIns.getInstance().getAnnotationType();
198            }
199            return KotlinBuiltIns.getInstance().getAnyType();
200        }
201    
202        public Collection<JetType> resolveDelegationSpecifiers(
203                JetScope extensibleScope,
204                List<JetDelegationSpecifier> delegationSpecifiers,
205                @NotNull TypeResolver resolver,
206                BindingTrace trace,
207                boolean checkBounds
208        ) {
209            if (delegationSpecifiers.isEmpty()) {
210                return Collections.emptyList();
211            }
212            Collection<JetType> result = Lists.newArrayList();
213            for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
214                JetTypeReference typeReference = delegationSpecifier.getTypeReference();
215                if (typeReference != null) {
216                    result.add(resolver.resolveType(extensibleScope, typeReference, trace, checkBounds));
217                    JetTypeElement bareSuperType = checkNullableSupertypeAndStripQuestionMarks(trace, typeReference.getTypeElement());
218                    checkProjectionsInImmediateArguments(trace, bareSuperType);
219                }
220                else {
221                    result.add(ErrorUtils.createErrorType("No type reference"));
222                }
223            }
224            return result;
225        }
226    
227        @Nullable
228        private static JetTypeElement checkNullableSupertypeAndStripQuestionMarks(@NotNull BindingTrace trace, @Nullable JetTypeElement typeElement) {
229            while (typeElement instanceof JetNullableType) {
230                JetNullableType nullableType = (JetNullableType) typeElement;
231                typeElement = nullableType.getInnerType();
232                // report only for innermost '?', the rest gets a 'redundant' warning
233                if (!(typeElement instanceof JetNullableType)) {
234                    trace.report(NULLABLE_SUPERTYPE.on(nullableType));
235                }
236            }
237            return typeElement;
238        }
239    
240        private static void checkProjectionsInImmediateArguments(@NotNull BindingTrace trace, @Nullable JetTypeElement typeElement) {
241            if (typeElement instanceof JetUserType) {
242                JetUserType userType = (JetUserType) typeElement;
243                List<JetTypeProjection> typeArguments = userType.getTypeArguments();
244                for (JetTypeProjection typeArgument : typeArguments) {
245                    if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) {
246                        trace.report(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE.on(typeArgument));
247                    }
248                }
249            }
250        }
251    
252        @NotNull
253        public SimpleFunctionDescriptor resolveFunctionDescriptorWithAnnotationArguments(
254                @NotNull DeclarationDescriptor containingDescriptor,
255                @NotNull JetScope scope,
256                @NotNull JetNamedFunction function,
257                @NotNull BindingTrace trace,
258                @NotNull DataFlowInfo dataFlowInfo
259        ) {
260            return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
261                                             annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace));
262        }
263    
264        @NotNull
265        public SimpleFunctionDescriptor resolveFunctionDescriptor(
266                @NotNull DeclarationDescriptor containingDescriptor,
267                @NotNull JetScope scope,
268                @NotNull JetNamedFunction function,
269                @NotNull BindingTrace trace,
270                @NotNull DataFlowInfo dataFlowInfo
271        ) {
272           return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
273                                            annotationResolver.resolveAnnotationsWithoutArguments(scope, function.getModifierList(), trace));
274        }
275    
276        @NotNull
277        private SimpleFunctionDescriptor resolveFunctionDescriptor(
278                @NotNull DeclarationDescriptor containingDescriptor,
279                @NotNull final JetScope scope,
280                @NotNull final JetNamedFunction function,
281                @NotNull final BindingTrace trace,
282                @NotNull final DataFlowInfo dataFlowInfo,
283                @NotNull List<AnnotationDescriptor> annotations
284        ) {
285            final SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
286                    containingDescriptor,
287                    annotations,
288                    JetPsiUtil.safeName(function.getName()),
289                    CallableMemberDescriptor.Kind.DECLARATION
290            );
291            WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace),
292                                                             "Function descriptor header scope");
293            innerScope.addLabeledDeclaration(functionDescriptor);
294    
295            List<TypeParameterDescriptorImpl> typeParameterDescriptors =
296                    resolveTypeParametersForCallableDescriptor(functionDescriptor, innerScope, function.getTypeParameters(), trace);
297            innerScope.changeLockLevel(WritableScope.LockLevel.BOTH);
298            resolveGenericBounds(function, innerScope, typeParameterDescriptors, trace);
299    
300            JetType receiverType = null;
301            JetTypeReference receiverTypeRef = function.getReceiverTypeRef();
302            if (receiverTypeRef != null) {
303                JetScope scopeForReceiver =
304                        function.hasTypeParameterListBeforeFunctionName()
305                        ? innerScope
306                        : scope;
307                receiverType = typeResolver.resolveType(scopeForReceiver, receiverTypeRef, trace, true);
308            }
309    
310            List<ValueParameterDescriptor> valueParameterDescriptors =
311                    resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters(), trace);
312    
313            innerScope.changeLockLevel(WritableScope.LockLevel.READING);
314    
315            JetTypeReference returnTypeRef = function.getReturnTypeRef();
316            JetType returnType;
317            if (returnTypeRef != null) {
318                returnType = typeResolver.resolveType(innerScope, returnTypeRef, trace, true);
319            }
320            else if (function.hasBlockBody()) {
321                returnType = KotlinBuiltIns.getInstance().getUnitType();
322            }
323            else {
324                JetExpression bodyExpression = function.getBodyExpression();
325                if (bodyExpression != null) {
326                    returnType =
327                            DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
328                                @Override
329                                protected JetType compute() {
330                                    JetType type = expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor);
331                                    return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace);
332                                }
333                            });
334                }
335                else {
336                    returnType = ErrorUtils.createErrorType("No type, no body");
337                }
338            }
339            boolean hasBody = function.getBodyExpression() != null;
340            Modality modality = resolveModalityFromModifiers(function, getDefaultModality(containingDescriptor, hasBody));
341            Visibility visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, containingDescriptor));
342            JetModifierList modifierList = function.getModifierList();
343            boolean isInline = (modifierList != null) && modifierList.hasModifier(JetTokens.INLINE_KEYWORD);
344            functionDescriptor.initialize(
345                    receiverType,
346                    getExpectedThisObjectIfNeeded(containingDescriptor),
347                    typeParameterDescriptors,
348                    valueParameterDescriptors,
349                    returnType,
350                    modality,
351                    visibility,
352                    isInline);
353    
354            BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor);
355            return functionDescriptor;
356        }
357    
358        @NotNull
359        public static SimpleFunctionDescriptor createComponentFunctionDescriptor(
360                int parameterIndex,
361                @NotNull PropertyDescriptor property,
362                @NotNull ValueParameterDescriptor parameter,
363                @NotNull ClassDescriptor classDescriptor,
364                @NotNull BindingTrace trace
365        ) {
366            String functionName = COMPONENT_FUNCTION_NAME_PREFIX + parameterIndex;
367            JetType returnType = property.getType();
368    
369            SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
370                    classDescriptor,
371                    Collections.<AnnotationDescriptor>emptyList(),
372                    Name.identifier(functionName),
373                    CallableMemberDescriptor.Kind.SYNTHESIZED
374            );
375    
376            functionDescriptor.initialize(
377                    null,
378                    classDescriptor.getThisAsReceiverParameter(),
379                    Collections.<TypeParameterDescriptor>emptyList(),
380                    Collections.<ValueParameterDescriptor>emptyList(),
381                    returnType,
382                    Modality.FINAL,
383                    property.getVisibility(),
384                    true
385            );
386    
387            trace.record(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter, functionDescriptor);
388    
389            return functionDescriptor;
390        }
391    
392        @NotNull
393        public static SimpleFunctionDescriptor createCopyFunctionDescriptor(
394                @NotNull Collection<ValueParameterDescriptor> constructorParameters,
395                @NotNull ClassDescriptor classDescriptor,
396                @NotNull BindingTrace trace
397        ) {
398            JetType returnType = classDescriptor.getDefaultType();
399    
400            SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
401                    classDescriptor,
402                    Collections.<AnnotationDescriptor>emptyList(),
403                    COPY_METHOD_NAME,
404                    CallableMemberDescriptor.Kind.SYNTHESIZED
405            );
406    
407            List<ValueParameterDescriptor> parameterDescriptors = Lists.newArrayList();
408    
409            for (ValueParameterDescriptor parameter : constructorParameters) {
410                PropertyDescriptor propertyDescriptor = trace.getBindingContext().get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
411                // If parameter hasn't corresponding property, so it mustn't have default value as a parameter in copy function for data class
412                boolean declaresDefaultValue = propertyDescriptor != null;
413                ValueParameterDescriptorImpl parameterDescriptor =
414                        new ValueParameterDescriptorImpl(functionDescriptor, parameter.getIndex(), parameter.getAnnotations(),
415                                                         parameter.getName(), parameter.getType(),
416                                                         declaresDefaultValue,
417                                                         parameter.getVarargElementType());
418                parameterDescriptors.add(parameterDescriptor);
419                if (declaresDefaultValue) {
420                    trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameterDescriptor, propertyDescriptor);
421                }
422            }
423    
424            functionDescriptor.initialize(
425                    null,
426                    classDescriptor.getThisAsReceiverParameter(),
427                    Collections.<TypeParameterDescriptor>emptyList(),
428                    parameterDescriptors,
429                    returnType,
430                    Modality.FINAL,
431                    classDescriptor.getVisibility(),
432                    true
433            );
434    
435            trace.record(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor, functionDescriptor);
436            return functionDescriptor;
437        }
438    
439        public static Visibility getDefaultVisibility(JetModifierListOwner modifierListOwner, DeclarationDescriptor containingDescriptor) {
440            Visibility defaultVisibility;
441            if (containingDescriptor instanceof ClassDescriptor) {
442                JetModifierList modifierList = modifierListOwner.getModifierList();
443                defaultVisibility = modifierList != null && modifierList.hasModifier(OVERRIDE_KEYWORD)
444                                               ? Visibilities.INHERITED
445                                               : Visibilities.INTERNAL;
446            }
447            else if (containingDescriptor instanceof FunctionDescriptor) {
448                defaultVisibility = Visibilities.LOCAL;
449            }
450            else {
451                defaultVisibility = Visibilities.INTERNAL;
452            }
453            return defaultVisibility;
454        }
455    
456        public static Modality getDefaultModality(DeclarationDescriptor containingDescriptor, boolean isBodyPresent) {
457            Modality defaultModality;
458            if (containingDescriptor instanceof ClassDescriptor) {
459                boolean isTrait = ((ClassDescriptor) containingDescriptor).getKind() == ClassKind.TRAIT;
460                boolean isDefinitelyAbstract = isTrait && !isBodyPresent;
461                Modality basicModality = isTrait ? Modality.OPEN : Modality.FINAL;
462                defaultModality = isDefinitelyAbstract ? Modality.ABSTRACT : basicModality;
463            }
464            else {
465                defaultModality = Modality.FINAL;
466            }
467            return defaultModality;
468        }
469    
470        @NotNull
471        private List<ValueParameterDescriptor> resolveValueParameters(
472                FunctionDescriptor functionDescriptor,
473                WritableScope parameterScope,
474                List<JetParameter> valueParameters,
475                BindingTrace trace
476        ) {
477            List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
478            for (int i = 0; i < valueParameters.size(); i++) {
479                JetParameter valueParameter = valueParameters.get(i);
480                JetTypeReference typeReference = valueParameter.getTypeReference();
481    
482                JetType type;
483                if (typeReference == null) {
484                    trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter));
485                    type = ErrorUtils.createErrorType("Type annotation was missing");
486                }
487                else {
488                    type = typeResolver.resolveType(parameterScope, typeReference, trace, true);
489                }
490    
491                if (!(functionDescriptor instanceof ConstructorDescriptor)) {
492                    checkParameterHasNoValOrVar(trace, valueParameter, VAL_OR_VAR_ON_FUN_PARAMETER);
493                    checkParameterHasNoModifier(trace, valueParameter);
494                } else {
495                    checkConstructorParameterHasNoModifier(trace, valueParameter);
496                }
497    
498                ValueParameterDescriptor valueParameterDescriptor =
499                        resolveValueParameterDescriptor(parameterScope, functionDescriptor, valueParameter, i, type, trace);
500                parameterScope.addVariableDescriptor(valueParameterDescriptor);
501                result.add(valueParameterDescriptor);
502            }
503            return result;
504        }
505    
506        @NotNull
507        public MutableValueParameterDescriptor resolveValueParameterDescriptor(
508                JetScope scope, DeclarationDescriptor declarationDescriptor,
509                JetParameter valueParameter, int index, JetType type, BindingTrace trace
510        ) {
511            return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
512                    annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace));
513        }
514    
515        @NotNull
516        public MutableValueParameterDescriptor resolveValueParameterDescriptorWithAnnotationArguments(
517                JetScope scope, DeclarationDescriptor declarationDescriptor,
518                JetParameter valueParameter, int index, JetType type, BindingTrace trace
519        ) {
520            return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
521                    annotationResolver.resolveAnnotationsWithArguments(scope, valueParameter.getModifierList(), trace));
522        }
523    
524        @NotNull
525        private MutableValueParameterDescriptor resolveValueParameterDescriptor(
526                DeclarationDescriptor declarationDescriptor,
527                JetParameter valueParameter, int index, JetType type, BindingTrace trace,
528                List<AnnotationDescriptor> annotations
529        ) {
530            JetType varargElementType = null;
531            JetType variableType = type;
532            if (valueParameter.hasModifier(JetTokens.VARARG_KEYWORD)) {
533                varargElementType = type;
534                variableType = DescriptorUtils.getVarargParameterType(type);
535            }
536            MutableValueParameterDescriptor valueParameterDescriptor = new ValueParameterDescriptorImpl(
537                    declarationDescriptor,
538                    index,
539                    annotations,
540                    JetPsiUtil.safeName(valueParameter.getName()),
541                    variableType,
542                    valueParameter.getDefaultValue() != null,
543                    varargElementType
544            );
545    
546            trace.record(BindingContext.VALUE_PARAMETER, valueParameter, valueParameterDescriptor);
547            return valueParameterDescriptor;
548        }
549    
550        public List<TypeParameterDescriptorImpl> resolveTypeParametersForCallableDescriptor(
551                DeclarationDescriptor containingDescriptor,
552                WritableScope extensibleScope,
553                List<JetTypeParameter> typeParameters,
554                BindingTrace trace
555        ) {
556            List<TypeParameterDescriptorImpl> result = new ArrayList<TypeParameterDescriptorImpl>();
557            for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
558                JetTypeParameter typeParameter = typeParameters.get(i);
559                result.add(resolveTypeParameterForCallableDescriptor(containingDescriptor, extensibleScope, typeParameter, i, trace));
560            }
561            return result;
562        }
563    
564        private TypeParameterDescriptorImpl resolveTypeParameterForCallableDescriptor(
565                DeclarationDescriptor containingDescriptor,
566                WritableScope extensibleScope,
567                JetTypeParameter typeParameter,
568                int index,
569                BindingTrace trace
570        ) {
571            if (typeParameter.getVariance() != Variance.INVARIANT) {
572                assert !(containingDescriptor instanceof ClassifierDescriptor) : "This method is intended for functions/properties";
573                trace.report(VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY.on(typeParameter));
574            }
575    
576            // TODO: Support annotation for type parameters
577            AnnotationResolver.reportUnsupportedAnnotationForTypeParameter(typeParameter, trace);
578    
579            TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
580                    containingDescriptor,
581                    Collections.<AnnotationDescriptor>emptyList(),
582                    typeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
583                    typeParameter.getVariance(),
584                    JetPsiUtil.safeName(typeParameter.getName()),
585                    index
586            );
587            trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
588            extensibleScope.addTypeParameterDescriptor(typeParameterDescriptor);
589            return typeParameterDescriptor;
590        }
591    
592        @NotNull
593        public static ConstructorDescriptorImpl createAndRecordPrimaryConstructorForObject(
594                @Nullable PsiElement object,
595                @NotNull ClassDescriptor classDescriptor,
596                @NotNull BindingTrace trace
597        ) {
598            ConstructorDescriptorImpl constructorDescriptor = createPrimaryConstructorForObject(classDescriptor);
599            if (object != null) {
600                trace.record(CONSTRUCTOR, object, constructorDescriptor);
601            }
602            return constructorDescriptor;
603        }
604    
605        @NotNull
606        public static ConstructorDescriptorImpl createPrimaryConstructorForObject(@NotNull ClassDescriptor containingClass) {
607            ConstructorDescriptorImpl constructorDescriptor =
608                    new ConstructorDescriptorImpl(containingClass, Collections.<AnnotationDescriptor>emptyList(), true);
609            constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
610                                             Collections.<ValueParameterDescriptor>emptyList(),
611                                             getDefaultConstructorVisibility(containingClass));
612            return constructorDescriptor;
613        }
614    
615        static final class UpperBoundCheckerTask {
616            JetTypeReference upperBound;
617            JetType upperBoundType;
618            boolean isClassObjectConstraint;
619    
620            private UpperBoundCheckerTask(JetTypeReference upperBound, JetType upperBoundType, boolean classObjectConstraint) {
621                this.upperBound = upperBound;
622                this.upperBoundType = upperBoundType;
623                isClassObjectConstraint = classObjectConstraint;
624            }
625        }
626    
627        public void resolveGenericBounds(
628                @NotNull JetTypeParameterListOwner declaration,
629                JetScope scope,
630                List<TypeParameterDescriptorImpl> parameters,
631                BindingTrace trace
632        ) {
633            List<UpperBoundCheckerTask> deferredUpperBoundCheckerTasks = Lists.newArrayList();
634    
635            List<JetTypeParameter> typeParameters = declaration.getTypeParameters();
636            Map<Name, TypeParameterDescriptorImpl> parameterByName = Maps.newHashMap();
637            for (int i = 0; i < typeParameters.size(); i++) {
638                JetTypeParameter jetTypeParameter = typeParameters.get(i);
639                TypeParameterDescriptorImpl typeParameterDescriptor = parameters.get(i);
640    
641                parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
642    
643                JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
644                if (extendsBound != null) {
645                    JetType type = typeResolver.resolveType(scope, extendsBound, trace, false);
646                    typeParameterDescriptor.addUpperBound(type);
647                    deferredUpperBoundCheckerTasks.add(new UpperBoundCheckerTask(extendsBound, type, false));
648                }
649            }
650            for (JetTypeConstraint constraint : declaration.getTypeConstraints()) {
651                JetSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName();
652                if (subjectTypeParameterName == null) {
653                    continue;
654                }
655                Name referencedName = subjectTypeParameterName.getReferencedNameAsName();
656                TypeParameterDescriptorImpl typeParameterDescriptor = parameterByName.get(referencedName);
657                JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
658                JetType bound = null;
659                if (boundTypeReference != null) {
660                    bound = typeResolver.resolveType(scope, boundTypeReference, trace, false);
661                    deferredUpperBoundCheckerTasks
662                            .add(new UpperBoundCheckerTask(boundTypeReference, bound, constraint.isClassObjectContraint()));
663                }
664    
665                if (typeParameterDescriptor == null) {
666                    // To tell the user that we look only for locally defined type parameters
667                    ClassifierDescriptor classifier = scope.getClassifier(referencedName);
668                    if (classifier != null) {
669                        trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(subjectTypeParameterName, constraint, declaration));
670                        trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, classifier);
671                    }
672                    else {
673                        trace.report(UNRESOLVED_REFERENCE.on(subjectTypeParameterName, subjectTypeParameterName));
674                    }
675                }
676                else {
677                    trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, typeParameterDescriptor);
678                    if (bound != null) {
679                        if (constraint.isClassObjectContraint()) {
680                            typeParameterDescriptor.addClassObjectBound(bound);
681                        }
682                        else {
683                            typeParameterDescriptor.addUpperBound(bound);
684                        }
685                    }
686                }
687            }
688    
689            for (TypeParameterDescriptorImpl parameter : parameters) {
690                parameter.addDefaultUpperBound();
691    
692                parameter.setInitialized();
693    
694                if (KotlinBuiltIns.getInstance().isNothing(parameter.getUpperBoundsAsType())) {
695                    PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier();
696                    if (nameIdentifier != null) {
697                        trace.report(CONFLICTING_UPPER_BOUNDS.on(nameIdentifier, parameter));
698                    }
699                }
700    
701                JetType classObjectType = parameter.getClassObjectType();
702                if (classObjectType != null && KotlinBuiltIns.getInstance().isNothing(classObjectType)) {
703                    PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier();
704                    if (nameIdentifier != null) {
705                        trace.report(CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS.on(nameIdentifier, parameter));
706                    }
707                }
708            }
709    
710            for (UpperBoundCheckerTask checkerTask : deferredUpperBoundCheckerTasks) {
711                checkUpperBoundType(checkerTask.upperBound, checkerTask.upperBoundType, checkerTask.isClassObjectConstraint, trace);
712            }
713        }
714    
715        private static void checkUpperBoundType(
716                JetTypeReference upperBound,
717                JetType upperBoundType,
718                boolean isClassObjectConstraint,
719                BindingTrace trace
720        ) {
721            if (!TypeUtils.canHaveSubtypes(JetTypeChecker.INSTANCE, upperBoundType)) {
722                if (isClassObjectConstraint) {
723                    trace.report(FINAL_CLASS_OBJECT_UPPER_BOUND.on(upperBound, upperBoundType));
724                }
725                else {
726                    trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType));
727                }
728            }
729        }
730    
731        @NotNull
732        public VariableDescriptor resolveLocalVariableDescriptor(
733                @NotNull JetScope scope,
734                @NotNull JetParameter parameter,
735                BindingTrace trace
736        ) {
737            JetType type = resolveParameterType(scope, parameter, trace);
738            return resolveLocalVariableDescriptor(parameter, type, trace, scope);
739        }
740    
741        private JetType resolveParameterType(JetScope scope, JetParameter parameter, BindingTrace trace) {
742            JetTypeReference typeReference = parameter.getTypeReference();
743            JetType type;
744            if (typeReference != null) {
745                type = typeResolver.resolveType(scope, typeReference, trace, true);
746            }
747            else {
748                // Error is reported by the parser
749                type = ErrorUtils.createErrorType("Annotation is absent");
750            }
751            if (parameter.hasModifier(JetTokens.VARARG_KEYWORD)) {
752                return DescriptorUtils.getVarargParameterType(type);
753            }
754            return type;
755        }
756    
757        public VariableDescriptor resolveLocalVariableDescriptor(
758                @NotNull JetParameter parameter,
759                @NotNull JetType type,
760                BindingTrace trace,
761                @NotNull JetScope scope
762        ) {
763            VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
764                    scope.getContainingDeclaration(),
765                    annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
766                    JetPsiUtil.safeName(parameter.getName()),
767                    type,
768                    false);
769            trace.record(BindingContext.VALUE_PARAMETER, parameter, variableDescriptor);
770            return variableDescriptor;
771        }
772    
773        @NotNull
774        public VariableDescriptor resolveLocalVariableDescriptor(
775                JetScope scope,
776                JetVariableDeclaration variable,
777                DataFlowInfo dataFlowInfo,
778                BindingTrace trace
779        ) {
780            DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration();
781            if (JetPsiUtil.isScriptDeclaration(variable)) {
782                PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
783                        containingDeclaration,
784                        annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
785                        Modality.FINAL,
786                        Visibilities.INTERNAL,
787                        variable.isVar(),
788                        JetPsiUtil.safeName(variable.getName()),
789                        CallableMemberDescriptor.Kind.DECLARATION
790                );
791    
792                JetType type =
793                        getVariableType(propertyDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
794    
795                ReceiverParameterDescriptor receiverParameter = ((ScriptDescriptor) containingDeclaration).getThisAsReceiverParameter();
796                propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), receiverParameter, (JetType) null);
797                trace.record(BindingContext.VARIABLE, variable, propertyDescriptor);
798                return propertyDescriptor;
799            }
800            else {
801                VariableDescriptorImpl variableDescriptor =
802                        resolveLocalVariableDescriptorWithType(scope, variable, null, trace);
803    
804                JetType type =
805                        getVariableType(variableDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
806                variableDescriptor.setOutType(type);
807                return variableDescriptor;
808            }
809        }
810    
811        @NotNull
812        public VariableDescriptorImpl resolveLocalVariableDescriptorWithType(
813                @NotNull JetScope scope,
814                @NotNull JetVariableDeclaration variable,
815                @Nullable JetType type,
816                @NotNull BindingTrace trace
817        ) {
818            VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
819                    scope.getContainingDeclaration(),
820                    annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
821                    JetPsiUtil.safeName(variable.getName()),
822                    type,
823                    variable.isVar());
824            trace.record(BindingContext.VARIABLE, variable, variableDescriptor);
825            return variableDescriptor;
826        }
827    
828        @NotNull
829        public VariableDescriptor resolveObjectDeclaration(
830                @NotNull JetScope scope,
831                @NotNull DeclarationDescriptor containingDeclaration,
832                @NotNull JetClassOrObject objectDeclaration,
833                @NotNull ClassDescriptor classDescriptor, BindingTrace trace
834        ) {
835            boolean isProperty = (containingDeclaration instanceof NamespaceDescriptor) || (containingDeclaration instanceof ClassDescriptor);
836            if (isProperty) {
837                return resolveObjectDeclarationAsPropertyDescriptor(scope, containingDeclaration, objectDeclaration, classDescriptor, trace);
838            }
839            else {
840                return resolveObjectDeclarationAsLocalVariable(containingDeclaration, objectDeclaration, classDescriptor, trace);
841            }
842        }
843    
844        @NotNull
845        public PropertyDescriptor resolveObjectDeclarationAsPropertyDescriptor(
846                @NotNull JetScope scope,
847                @NotNull DeclarationDescriptor containingDeclaration,
848                @NotNull JetClassOrObject objectDeclaration,
849                @NotNull ClassDescriptor classDescriptor, BindingTrace trace
850        ) {
851            JetModifierList modifierList = objectDeclaration.getModifierList();
852            PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorForObjectImpl(
853                    containingDeclaration,
854                    annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
855                    resolveVisibilityFromModifiers(objectDeclaration, getDefaultVisibilityForObjectPropertyDescriptor(classDescriptor)),
856                    JetPsiUtil.safeName(objectDeclaration.getName()),
857                    classDescriptor
858            );
859            propertyDescriptor.setType(getTypeForObjectDeclaration(classDescriptor), Collections.<TypeParameterDescriptor>emptyList(),
860                                       getExpectedThisObjectIfNeeded(containingDeclaration), NO_RECEIVER_PARAMETER);
861            propertyDescriptor.initialize(null, null);
862            JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
863            if (nameAsDeclaration != null) {
864                trace.record(BindingContext.OBJECT_DECLARATION, nameAsDeclaration, propertyDescriptor);
865            }
866            return propertyDescriptor;
867        }
868    
869        @NotNull
870        private static JetType getTypeForObjectDeclaration(@NotNull ClassDescriptor objectClassDescriptor) {
871            if (objectClassDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
872                DeclarationDescriptor containingDeclaration = objectClassDescriptor.getContainingDeclaration().getContainingDeclaration();
873                assert containingDeclaration instanceof ClassDescriptor;
874                ClassDescriptor enumClass = (ClassDescriptor) containingDeclaration;
875                assert enumClass.getKind() == ClassKind.ENUM_CLASS;
876                return enumClass.getDefaultType();
877            }
878            return objectClassDescriptor.getDefaultType();
879        }
880    
881        @NotNull
882        private VariableDescriptor resolveObjectDeclarationAsLocalVariable(
883                @NotNull DeclarationDescriptor containingDeclaration,
884                @NotNull JetClassOrObject objectDeclaration,
885                @NotNull ClassDescriptor classDescriptor, BindingTrace trace
886        ) {
887            VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptorForObject(
888                    containingDeclaration,
889                    annotationResolver.getResolvedAnnotations(objectDeclaration.getModifierList(), trace),
890                    JetPsiUtil.safeName(objectDeclaration.getName()),
891                    classDescriptor);
892            JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
893            if (nameAsDeclaration != null) {
894                trace.record(BindingContext.VARIABLE, nameAsDeclaration, variableDescriptor);
895            }
896            return variableDescriptor;
897        }
898    
899        public JetScope getPropertyDeclarationInnerScope(
900                @NotNull PropertyDescriptor propertyDescriptor,
901                @NotNull JetScope outerScope,
902                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
903                @Nullable ReceiverParameterDescriptor receiver,
904                BindingTrace trace
905        ) {
906            return getPropertyDeclarationInnerScope(propertyDescriptor, outerScope, typeParameters, receiver, trace, true);
907        }
908    
909        public JetScope getPropertyDeclarationInnerScopeForInitializer(
910                @NotNull JetScope outerScope,
911                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
912                @Nullable ReceiverParameterDescriptor receiver,
913                BindingTrace trace
914        ) {
915            return getPropertyDeclarationInnerScope(null, outerScope, typeParameters, receiver, trace, false);
916        }
917    
918        private JetScope getPropertyDeclarationInnerScope(
919                @Nullable PropertyDescriptor propertyDescriptor, // PropertyDescriptor can be null for property scope which hasn't label to property (in this case addLabelForProperty parameter must be false
920                @NotNull JetScope outerScope,
921                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
922                @Nullable ReceiverParameterDescriptor receiver,
923                BindingTrace trace,
924                boolean addLabelForProperty
925        ) {
926            WritableScopeImpl result = new WritableScopeImpl(
927                    outerScope, outerScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace),
928                    "Property declaration inner scope");
929            if (addLabelForProperty) {
930                assert propertyDescriptor != null : "PropertyDescriptor can be null for property scope which hasn't label to property";
931                result.addLabeledDeclaration(propertyDescriptor);
932            }
933            for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
934                result.addTypeParameterDescriptor(typeParameterDescriptor);
935            }
936            if (receiver != null) {
937                result.setImplicitReceiver(receiver);
938            }
939            result.changeLockLevel(WritableScope.LockLevel.READING);
940            return result;
941        }
942    
943        @NotNull
944        public PropertyDescriptor resolvePropertyDescriptor(
945                @NotNull DeclarationDescriptor containingDeclaration,
946                @NotNull JetScope scope,
947                @NotNull JetProperty property,
948                @NotNull BindingTrace trace,
949                @NotNull DataFlowInfo dataFlowInfo
950        ) {
951    
952            JetModifierList modifierList = property.getModifierList();
953            boolean isVar = property.isVar();
954    
955            boolean hasBody = hasBody(property);
956            Modality modality = containingDeclaration instanceof ClassDescriptor
957                                ? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, hasBody))
958                                : Modality.FINAL;
959            Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
960            PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
961                    containingDeclaration,
962                    annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
963                    modality,
964                    visibility,
965                    isVar,
966                    JetPsiUtil.safeName(property.getName()),
967                    CallableMemberDescriptor.Kind.DECLARATION
968            );
969    
970            List<TypeParameterDescriptorImpl> typeParameterDescriptors;
971            JetScope scopeWithTypeParameters;
972            JetType receiverType = null;
973    
974            {
975                List<JetTypeParameter> typeParameters = property.getTypeParameters();
976                if (typeParameters.isEmpty()) {
977                    scopeWithTypeParameters = scope;
978                    typeParameterDescriptors = Collections.emptyList();
979                }
980                else {
981                    WritableScope writableScope = new WritableScopeImpl(
982                            scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace),
983                            "Scope with type parameters of a property");
984                    typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(containingDeclaration, writableScope, typeParameters,
985                                                                                          trace);
986                    writableScope.changeLockLevel(WritableScope.LockLevel.READING);
987                    resolveGenericBounds(property, writableScope, typeParameterDescriptors, trace);
988                    scopeWithTypeParameters = writableScope;
989                }
990    
991                JetTypeReference receiverTypeRef = property.getReceiverTypeRef();
992                if (receiverTypeRef != null) {
993                    receiverType = typeResolver.resolveType(scopeWithTypeParameters, receiverTypeRef, trace, true);
994                }
995            }
996    
997            ReceiverParameterDescriptor receiverDescriptor = resolveReceiverParameterFor(propertyDescriptor, receiverType);
998    
999            JetScope propertyScope = getPropertyDeclarationInnerScope(propertyDescriptor, scope, typeParameterDescriptors,
1000                                                                      NO_RECEIVER_PARAMETER, trace);
1001    
1002            JetType type = getVariableType(propertyDescriptor, propertyScope, property, dataFlowInfo, true, trace);
1003    
1004            propertyDescriptor.setType(type, typeParameterDescriptors, getExpectedThisObjectIfNeeded(containingDeclaration),
1005                                       receiverDescriptor);
1006    
1007            PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
1008            PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
1009    
1010            propertyDescriptor.initialize(getter, setter);
1011    
1012            trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
1013            return propertyDescriptor;
1014        }
1015    
1016        /*package*/
1017        static boolean hasBody(JetProperty property) {
1018            boolean hasBody = property.getDelegateExpressionOrInitializer() != null;
1019            if (!hasBody) {
1020                JetPropertyAccessor getter = property.getGetter();
1021                if (getter != null && getter.getBodyExpression() != null) {
1022                    hasBody = true;
1023                }
1024                JetPropertyAccessor setter = property.getSetter();
1025                if (!hasBody && setter != null && setter.getBodyExpression() != null) {
1026                    hasBody = true;
1027                }
1028            }
1029            return hasBody;
1030        }
1031    
1032        @NotNull
1033        private JetType getVariableType(
1034                @NotNull final VariableDescriptor variableDescriptor,
1035                @NotNull final JetScope scope,
1036                @NotNull final JetVariableDeclaration variable,
1037                @NotNull final DataFlowInfo dataFlowInfo,
1038                boolean notLocal,
1039                @NotNull final BindingTrace trace
1040        ) {
1041            JetTypeReference propertyTypeRef = variable.getTypeRef();
1042    
1043            boolean hasDelegate = variable instanceof JetProperty && ((JetProperty) variable).getDelegateExpression() != null;
1044            if (propertyTypeRef == null) {
1045                final JetExpression initializer = variable.getInitializer();
1046                if (initializer == null) {
1047                    if (hasDelegate && variableDescriptor instanceof PropertyDescriptor) {
1048                        final JetExpression propertyDelegateExpression = ((JetProperty) variable).getDelegateExpression();
1049                        if (propertyDelegateExpression != null) {
1050                            return DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
1051                                @Override
1052                                protected JetType compute() {
1053                                    return resolveDelegatedPropertyType((PropertyDescriptor) variableDescriptor, scope,
1054                                                                                propertyDelegateExpression, dataFlowInfo, trace);
1055                                }
1056                            });
1057                        }
1058                    }
1059                    if (!notLocal) {
1060                        trace.report(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.on(variable));
1061                    }
1062                    return ErrorUtils.createErrorType("No type, no body");
1063                }
1064                else {
1065                    if (notLocal) {
1066                        return DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
1067                            @Override
1068                            protected JetType compute() {
1069                                JetType type = resolveInitializerType(scope, initializer, dataFlowInfo, trace);
1070    
1071                                return transformAnonymousTypeIfNeeded(variableDescriptor, variable, type, trace);
1072                            }
1073                        });
1074                    }
1075                    else {
1076                        return resolveInitializerType(scope, initializer, dataFlowInfo, trace);
1077                    }
1078                }
1079            }
1080            else {
1081                return typeResolver.resolveType(scope, propertyTypeRef, trace, true);
1082            }
1083        }
1084    
1085        @NotNull
1086        private JetType resolveDelegatedPropertyType(
1087                @NotNull PropertyDescriptor propertyDescriptor,
1088                @NotNull JetScope scope,
1089                @NotNull JetExpression delegateExpression,
1090                @NotNull DataFlowInfo dataFlowInfo,
1091                @NotNull BindingTrace trace
1092        ) {
1093            JetType type = expressionTypingServices.safeGetType(scope, delegateExpression, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace);
1094    
1095            JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, scope, this, trace);
1096            JetType getterReturnType = DelegatedPropertyUtils
1097                    .getDelegatedPropertyGetMethodReturnType(propertyDescriptor, delegateExpression, type, expressionTypingServices, trace,
1098                                                             accessorScope);
1099            if (getterReturnType != null) {
1100                return getterReturnType;
1101            }
1102            return ErrorUtils.createErrorType("Type from delegate");
1103        }
1104    
1105        @Nullable
1106        private JetType transformAnonymousTypeIfNeeded(
1107                @NotNull DeclarationDescriptorWithVisibility descriptor,
1108                @NotNull JetNamedDeclaration declaration,
1109                @NotNull JetType type,
1110                @NotNull BindingTrace trace
1111        ) {
1112            ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
1113            if (!DescriptorUtils.isAnonymous(classifierDescriptor)) {
1114                return type;
1115            }
1116    
1117            boolean definedInClass = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) != null;
1118            boolean isLocal = descriptor.getContainingDeclaration() instanceof CallableDescriptor;
1119            Visibility visibility = descriptor.getVisibility();
1120            boolean transformNeeded = !isLocal && !visibility.isPublicAPI()
1121                                      && !(definedInClass && Visibilities.PRIVATE.equals(visibility));
1122            if (transformNeeded) {
1123                if (type.getConstructor().getSupertypes().size() == 1) {
1124                    assert type.getArguments().isEmpty() : "Object expression couldn't have any type parameters!";
1125                    return type.getConstructor().getSupertypes().iterator().next();
1126                }
1127                else {
1128                    trace.report(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED.on(declaration, type.getConstructor().getSupertypes()));
1129                }
1130            }
1131            return type;
1132        }
1133    
1134        @NotNull
1135        private JetType resolveInitializerType(
1136                @NotNull JetScope scope,
1137                @NotNull JetExpression initializer,
1138                @NotNull DataFlowInfo dataFlowInfo,
1139                @NotNull BindingTrace trace
1140        ) {
1141            return expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace);
1142        }
1143    
1144        @Nullable
1145        private PropertySetterDescriptor resolvePropertySetterDescriptor(
1146                @NotNull JetScope scope,
1147                @NotNull JetProperty property,
1148                @NotNull PropertyDescriptor propertyDescriptor,
1149                BindingTrace trace
1150        ) {
1151            JetPropertyAccessor setter = property.getSetter();
1152            PropertySetterDescriptorImpl setterDescriptor = null;
1153            if (setter != null) {
1154                List<AnnotationDescriptor> annotations =
1155                        annotationResolver.resolveAnnotationsWithoutArguments(scope, setter.getModifierList(), trace);
1156                JetParameter parameter = setter.getParameter();
1157    
1158                setterDescriptor = new PropertySetterDescriptorImpl(
1159                        propertyDescriptor, annotations,
1160                        resolveModalityFromModifiers(setter, propertyDescriptor.getModality()),
1161                        resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()),
1162                        setter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
1163                if (parameter != null) {
1164    
1165                    // This check is redundant: the parser does not allow a default value, but we'll keep it just in case
1166                    JetExpression defaultValue = parameter.getDefaultValue();
1167                    if (defaultValue != null) {
1168                        trace.report(SETTER_PARAMETER_WITH_DEFAULT_VALUE.on(defaultValue));
1169                    }
1170    
1171                    JetType type;
1172                    JetTypeReference typeReference = parameter.getTypeReference();
1173                    if (typeReference == null) {
1174                        type = propertyDescriptor.getType(); // TODO : this maybe unknown at this point
1175                    }
1176                    else {
1177                        type = typeResolver.resolveType(scope, typeReference, trace, true);
1178                        JetType inType = propertyDescriptor.getType();
1179                        if (inType != null) {
1180                            if (!TypeUtils.equalTypes(type, inType)) {
1181                                trace.report(WRONG_SETTER_PARAMETER_TYPE.on(typeReference, inType, type));
1182                            }
1183                        }
1184                        else {
1185                            // TODO : the same check may be needed later???
1186                        }
1187                    }
1188    
1189                    MutableValueParameterDescriptor valueParameterDescriptor =
1190                            resolveValueParameterDescriptor(scope, setterDescriptor, parameter, 0, type, trace);
1191                    setterDescriptor.initialize(valueParameterDescriptor);
1192                }
1193                else {
1194                    setterDescriptor.initializeDefault();
1195                }
1196    
1197                trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
1198            }
1199            else if (property.isVar()) {
1200                if (property.getDelegateExpression() != null) {
1201                    setterDescriptor = createSetterForDelegatedProperty(propertyDescriptor);
1202                }
1203                else {
1204                    setterDescriptor = createDefaultSetter(propertyDescriptor);
1205                }
1206            }
1207    
1208            if (!property.isVar()) {
1209                if (setter != null) {
1210                    //                trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
1211                    trace.report(VAL_WITH_SETTER.on(setter));
1212                }
1213            }
1214            return setterDescriptor;
1215        }
1216    
1217        @NotNull
1218        public static PropertySetterDescriptorImpl createDefaultSetter(@NotNull PropertyDescriptor propertyDescriptor) {
1219            return createSetter(propertyDescriptor, false, true);
1220        }
1221    
1222        @NotNull
1223        public static PropertySetterDescriptorImpl createSetterForDelegatedProperty(@NotNull PropertyDescriptor propertyDescriptor) {
1224            return createSetter(propertyDescriptor, true, false);
1225        }
1226    
1227        @NotNull
1228        private static PropertySetterDescriptorImpl createSetter(@NotNull PropertyDescriptor propertyDescriptor, boolean hasBody, boolean isDefault) {
1229            PropertySetterDescriptorImpl setterDescriptor;
1230            setterDescriptor = new PropertySetterDescriptorImpl(
1231                    propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
1232                    propertyDescriptor.getVisibility(),
1233                    hasBody, isDefault, CallableMemberDescriptor.Kind.DECLARATION);
1234            setterDescriptor.initializeDefault();
1235            return setterDescriptor;
1236        }
1237    
1238        @Nullable
1239        private PropertyGetterDescriptorImpl resolvePropertyGetterDescriptor(
1240                @NotNull JetScope scope,
1241                @NotNull JetProperty property,
1242                @NotNull PropertyDescriptor propertyDescriptor,
1243                BindingTrace trace
1244        ) {
1245            PropertyGetterDescriptorImpl getterDescriptor;
1246            JetPropertyAccessor getter = property.getGetter();
1247            if (getter != null) {
1248                List<AnnotationDescriptor> annotations =
1249                        annotationResolver.resolveAnnotationsWithoutArguments(scope, getter.getModifierList(), trace);
1250    
1251                JetType outType = propertyDescriptor.getType();
1252                JetType returnType = outType;
1253                JetTypeReference returnTypeReference = getter.getReturnTypeReference();
1254                if (returnTypeReference != null) {
1255                    returnType = typeResolver.resolveType(scope, returnTypeReference, trace, true);
1256                    if (outType != null && !TypeUtils.equalTypes(returnType, outType)) {
1257                        trace.report(WRONG_GETTER_RETURN_TYPE.on(returnTypeReference, propertyDescriptor.getReturnType(), outType));
1258                    }
1259                }
1260    
1261                getterDescriptor = new PropertyGetterDescriptorImpl(
1262                        propertyDescriptor, annotations,
1263                        resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
1264                        resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
1265                        getter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
1266                getterDescriptor.initialize(returnType);
1267                trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
1268            }
1269            else {
1270                if (property.getDelegateExpression() != null) {
1271                    getterDescriptor = createGetterForDelegatedProperty(propertyDescriptor);
1272                }
1273                else {
1274                    getterDescriptor = createDefaultGetter(propertyDescriptor);
1275                }
1276                getterDescriptor.initialize(propertyDescriptor.getType());
1277            }
1278            return getterDescriptor;
1279        }
1280    
1281        @NotNull
1282        public static PropertyGetterDescriptorImpl createDefaultGetter(@NotNull PropertyDescriptor propertyDescriptor) {
1283            return createGetter(propertyDescriptor, false, true);
1284        }
1285    
1286        @NotNull
1287        public static PropertyGetterDescriptorImpl createGetterForDelegatedProperty(@NotNull PropertyDescriptor propertyDescriptor) {
1288            return createGetter(propertyDescriptor, true, false);
1289        }
1290    
1291        private static PropertyGetterDescriptorImpl createGetter(@NotNull PropertyDescriptor propertyDescriptor, boolean hasBody, boolean isDefault) {
1292            PropertyGetterDescriptorImpl getterDescriptor;
1293            getterDescriptor = new PropertyGetterDescriptorImpl(
1294                    propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
1295                    propertyDescriptor.getVisibility(),
1296                    hasBody, isDefault, CallableMemberDescriptor.Kind.DECLARATION);
1297            return getterDescriptor;
1298        }
1299    
1300        @NotNull
1301        private ConstructorDescriptorImpl createConstructorDescriptor(
1302                @NotNull JetScope scope,
1303                @NotNull ClassDescriptor classDescriptor,
1304                boolean isPrimary,
1305                @Nullable JetModifierList modifierList,
1306                @NotNull JetDeclaration declarationToTrace,
1307                List<TypeParameterDescriptor> typeParameters, @NotNull List<JetParameter> valueParameters, BindingTrace trace
1308        ) {
1309            ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
1310                    classDescriptor,
1311                    annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList, trace),
1312                    isPrimary
1313            );
1314            trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor);
1315            WritableScopeImpl parameterScope = new WritableScopeImpl(
1316                    scope, constructorDescriptor, new TraceBasedRedeclarationHandler(trace), "Scope with value parameters of a constructor");
1317            parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH);
1318            ConstructorDescriptorImpl constructor = constructorDescriptor.initialize(
1319                    typeParameters,
1320                    resolveValueParameters(
1321                            constructorDescriptor,
1322                            parameterScope,
1323                            valueParameters, trace),
1324                    resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor)),
1325                    DescriptorUtils.isConstructorOfStaticNestedClass(constructorDescriptor));
1326            if (isAnnotationClass(classDescriptor)) {
1327                AnnotationUtils.checkConstructorParametersType(valueParameters, trace);
1328            }
1329            return constructor;
1330        }
1331    
1332        @Nullable
1333        public ConstructorDescriptorImpl resolvePrimaryConstructorDescriptor(
1334                @NotNull JetScope scope,
1335                @NotNull ClassDescriptor classDescriptor,
1336                @NotNull JetClass classElement,
1337                BindingTrace trace
1338        ) {
1339            if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) return null;
1340            return createConstructorDescriptor(
1341                    scope,
1342                    classDescriptor,
1343                    true,
1344                    classElement.getPrimaryConstructorModifierList(),
1345                    classElement,
1346                    classDescriptor.getTypeConstructor().getParameters(), classElement.getPrimaryConstructorParameters(), trace);
1347        }
1348    
1349        @NotNull
1350        public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(
1351                @NotNull ClassDescriptor classDescriptor,
1352                @NotNull ValueParameterDescriptor valueParameter,
1353                @NotNull JetScope scope,
1354                @NotNull JetParameter parameter, BindingTrace trace
1355        ) {
1356            JetType type = resolveParameterType(scope, parameter, trace);
1357            Name name = parameter.getNameAsSafeName();
1358            boolean isMutable = parameter.isMutable();
1359            JetModifierList modifierList = parameter.getModifierList();
1360    
1361            if (modifierList != null) {
1362                ASTNode abstractNode = modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD);
1363                if (abstractNode != null) {
1364                    trace.report(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.on(parameter));
1365                }
1366            }
1367    
1368            PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
1369                    classDescriptor,
1370                    valueParameter.getAnnotations(),
1371                    resolveModalityFromModifiers(parameter, Modality.FINAL),
1372                    resolveVisibilityFromModifiers(parameter),
1373                    isMutable,
1374                    name,
1375                    CallableMemberDescriptor.Kind.DECLARATION
1376            );
1377            propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
1378                                       getExpectedThisObjectIfNeeded(classDescriptor), NO_RECEIVER_PARAMETER);
1379    
1380            PropertyGetterDescriptorImpl getter = createDefaultGetter(propertyDescriptor);
1381            PropertySetterDescriptor setter = propertyDescriptor.isVar() ? createDefaultSetter(propertyDescriptor) : null;
1382    
1383            propertyDescriptor.initialize(getter, setter);
1384            getter.initialize(propertyDescriptor.getType());
1385    
1386            trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor);
1387            trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter, propertyDescriptor);
1388            return propertyDescriptor;
1389        }
1390    
1391        public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, BindingTrace trace) {
1392            if (ErrorUtils.isErrorType(type)) return;
1393    
1394            JetTypeElement typeElement = typeReference.getTypeElement();
1395            if (typeElement == null) return;
1396    
1397            List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
1398            List<TypeProjection> arguments = type.getArguments();
1399            assert parameters.size() == arguments.size();
1400    
1401            List<JetTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
1402            assert jetTypeArguments.size() == arguments.size() : typeElement.getText();
1403    
1404            TypeSubstitutor substitutor = TypeSubstitutor.create(type);
1405            for (int i = 0; i < jetTypeArguments.size(); i++) {
1406                JetTypeReference jetTypeArgument = jetTypeArguments.get(i);
1407    
1408                if (jetTypeArgument == null) continue;
1409    
1410                JetType typeArgument = arguments.get(i).getType();
1411                checkBounds(jetTypeArgument, typeArgument, trace);
1412    
1413                TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
1414                checkBounds(jetTypeArgument, typeArgument, typeParameterDescriptor, substitutor, trace);
1415            }
1416        }
1417    
1418        public static void checkBounds(
1419                @NotNull JetTypeReference jetTypeArgument,
1420                @NotNull JetType typeArgument,
1421                @NotNull TypeParameterDescriptor typeParameterDescriptor,
1422                @NotNull TypeSubstitutor substitutor, BindingTrace trace
1423        ) {
1424            for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
1425                JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
1426                if (!JetTypeChecker.INSTANCE.isSubtypeOf(typeArgument, substitutedBound)) {
1427                    trace.report(UPPER_BOUND_VIOLATED.on(jetTypeArgument, substitutedBound, typeArgument));
1428                }
1429            }
1430        }
1431    
1432        @NotNull
1433        public static SimpleFunctionDescriptor createEnumClassObjectValuesMethod(
1434                @NotNull ClassDescriptor classObject,
1435                @NotNull BindingTrace trace
1436        ) {
1437            final ClassDescriptor enumClassDescriptor = (ClassDescriptor) classObject.getContainingDeclaration();
1438            assert DescriptorUtils.isEnumClass(enumClassDescriptor) : "values should be created in enum class: " + enumClassDescriptor;
1439            return createEnumClassObjectValuesMethod(classObject, DeferredType.create(trace, new RecursionIntolerantLazyValue<JetType>() {
1440                @Override
1441                protected JetType compute() {
1442                    return KotlinBuiltIns.getInstance().getArrayType(enumClassDescriptor.getDefaultType());
1443                }
1444            }));
1445        }
1446    
1447        @NotNull
1448        public static SimpleFunctionDescriptor createEnumClassObjectValuesMethod(
1449                @NotNull ClassDescriptor classObject,
1450                @NotNull JetType returnType
1451        ) {
1452            SimpleFunctionDescriptorImpl values =
1453                    new SimpleFunctionDescriptorImpl(classObject, Collections.<AnnotationDescriptor>emptyList(), VALUES_METHOD_NAME,
1454                                                     CallableMemberDescriptor.Kind.DECLARATION);
1455            return values.initialize(null, classObject.getThisAsReceiverParameter(), Collections.<TypeParameterDescriptor>emptyList(),
1456                                     Collections.<ValueParameterDescriptor>emptyList(),
1457                                     returnType, Modality.FINAL,
1458                                     Visibilities.PUBLIC, false);
1459        }
1460    
1461    
1462        @NotNull
1463        public static SimpleFunctionDescriptor createEnumClassObjectValueOfMethod(
1464                @NotNull ClassDescriptor classObject,
1465                @NotNull BindingTrace trace
1466        ) {
1467            final ClassDescriptor enumClassDescriptor = (ClassDescriptor) classObject.getContainingDeclaration();
1468            assert DescriptorUtils.isEnumClass(enumClassDescriptor) : "valueOf should be created in enum class: " + enumClassDescriptor;
1469            return createEnumClassObjectValueOfMethod(classObject, DeferredType.create(trace, new RecursionIntolerantLazyValue<JetType>() {
1470                @Override
1471                protected JetType compute() {
1472                    return enumClassDescriptor.getDefaultType();
1473                }
1474            }));
1475        }
1476    
1477        @NotNull
1478        public static SimpleFunctionDescriptor createEnumClassObjectValueOfMethod(
1479                @NotNull ClassDescriptor classObject,
1480                @NotNull JetType returnType
1481        ) {
1482            SimpleFunctionDescriptorImpl values =
1483                    new SimpleFunctionDescriptorImpl(classObject, Collections.<AnnotationDescriptor>emptyList(), VALUE_OF_METHOD_NAME,
1484                                                     CallableMemberDescriptor.Kind.DECLARATION);
1485            ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
1486                    values,
1487                    0,
1488                    Collections.<AnnotationDescriptor>emptyList(),
1489                    Name.identifier("value"),
1490                    KotlinBuiltIns.getInstance().getStringType(),
1491                    false,
1492                    null);
1493            return values.initialize(null, classObject.getThisAsReceiverParameter(),
1494                                     Collections.<TypeParameterDescriptor>emptyList(),
1495                                     Collections.singletonList(parameterDescriptor),
1496                                     returnType, Modality.FINAL,
1497                                     Visibilities.PUBLIC, false);
1498        }
1499    
1500        public static ReceiverParameterDescriptor createLazyReceiverParameterDescriptor(@NotNull final ClassDescriptor classDescriptor) {
1501            return new AbstractReceiverParameterDescriptor() {
1502    
1503                private ClassReceiver value;
1504    
1505                @NotNull
1506                @Override
1507                public JetType getType() {
1508                    // This must be lazy, thus the inner class
1509                    return classDescriptor.getDefaultType();
1510                }
1511    
1512                @NotNull
1513                @Override
1514                public ReceiverValue getValue() {
1515                    if (value == null) {
1516                        value = new ClassReceiver(classDescriptor);
1517                    }
1518                    return value;
1519                }
1520    
1521                @NotNull
1522                @Override
1523                public DeclarationDescriptor getContainingDeclaration() {
1524                    return classDescriptor;
1525                }
1526    
1527                @Override
1528                public String toString() {
1529                    return "class " + classDescriptor.getName() + "::this";
1530                }
1531            };
1532        }
1533    
1534        public static boolean checkHasOuterClassInstance(
1535                @NotNull JetScope scope,
1536                @NotNull BindingTrace trace,
1537                @NotNull PsiElement reportErrorsOn,
1538                @NotNull ClassDescriptor target
1539        ) {
1540            return checkHasOuterClassInstance(scope, trace, reportErrorsOn, target, true);
1541        }
1542    
1543        public static boolean checkHasOuterClassInstance(
1544                @NotNull JetScope scope,
1545                @NotNull BindingTrace trace,
1546                @NotNull PsiElement reportErrorsOn,
1547                @NotNull ClassDescriptor target,
1548                boolean doSuperClassCheck
1549        ) {
1550            DeclarationDescriptor descriptor = getContainingClass(scope);
1551    
1552            while (descriptor != null) {
1553                if (descriptor instanceof ClassDescriptor) {
1554                    ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
1555    
1556                    if (classDescriptor == target) {
1557                        return true;
1558                    }
1559    
1560                    if (doSuperClassCheck && isSubclass(classDescriptor, target)) {
1561                        return true;
1562                    }
1563    
1564                    if (isStaticNestedClass(classDescriptor)) {
1565                        trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
1566                        return false;
1567                    }
1568                }
1569                descriptor = descriptor.getContainingDeclaration();
1570            }
1571            return true;
1572        }
1573    
1574        public static void checkParameterHasNoValOrVar(
1575                @NotNull BindingTrace trace,
1576                @NotNull JetParameter parameter,
1577                @NotNull DiagnosticFactory1<PsiElement, JetKeywordToken> diagnosticFactory
1578        ) {
1579            ASTNode valOrVarNode = parameter.getValOrVarNode();
1580            if (valOrVarNode != null) {
1581                trace.report(diagnosticFactory.on(valOrVarNode.getPsi(), ((JetKeywordToken) valOrVarNode.getElementType())));
1582            }
1583        }
1584    
1585        private static void checkConstructorParameterHasNoModifier(
1586                @NotNull BindingTrace trace,
1587                @NotNull JetParameter parameter
1588        ) {
1589            // If is not a property, then it must have no modifier
1590            if (parameter.getValOrVarNode() == null) {
1591                checkParameterHasNoModifier(trace, parameter);
1592            }
1593        }
1594    
1595        public static void checkParameterHasNoModifier(
1596                @NotNull BindingTrace trace,
1597                @NotNull JetParameter parameter
1598        ) {
1599            JetModifierList modifiers = parameter.getModifierList();
1600            if (modifiers != null) {
1601                ASTNode node = modifiers.getNode().getFirstChildNode();
1602    
1603                while (node != null) {
1604                    IElementType elementType = node.getElementType();
1605    
1606                    if (elementType != JetTokens.VARARG_KEYWORD && elementType instanceof JetKeywordToken) {
1607                        trace.report(ILLEGAL_MODIFIER.on(node.getPsi(), (JetKeywordToken) elementType));
1608                    }
1609                    node = node.getTreeNext();
1610                }
1611            }
1612        }
1613    }