public void resolvePropertyAccessors( @NotNull BodiesResolveContext c, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) { ObservableBindingTrace fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor); JetPropertyAccessor getter = property.getGetter(); PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter(); if (getter != null && getterDescriptor != null) { LexicalScope accessorScope = makeScopeForPropertyAccessor(c, getter, propertyDescriptor); ForceResolveUtil.forceResolveAllContents(getterDescriptor.getAnnotations()); resolveFunctionBody( c.getOuterDataFlowInfo(), fieldAccessTrackingTrace, getter, getterDescriptor, accessorScope); } JetPropertyAccessor setter = property.getSetter(); PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); if (setter != null && setterDescriptor != null) { LexicalScope accessorScope = makeScopeForPropertyAccessor(c, setter, propertyDescriptor); ForceResolveUtil.forceResolveAllContents(setterDescriptor.getAnnotations()); resolveFunctionBody( c.getOuterDataFlowInfo(), fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope); } }
private void checkAccessors( @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) { for (JetPropertyAccessor accessor : property.getAccessors()) { PropertyAccessorDescriptor propertyAccessorDescriptor = accessor.isGetter() ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); assert propertyAccessorDescriptor != null : "No property accessor descriptor for " + property.getText(); modifiersChecker.checkModifiersForDeclaration(accessor, propertyAccessorDescriptor); modifiersChecker.reportIllegalModalityModifiers(accessor); } JetPropertyAccessor getter = property.getGetter(); PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter(); JetModifierList getterModifierList = getter != null ? getter.getModifierList() : null; if (getterModifierList != null && getterDescriptor != null) { Map<JetModifierKeywordToken, ASTNode> nodes = ModifiersChecker.getNodesCorrespondingToModifiers( getterModifierList, Sets.newHashSet( JetTokens.PUBLIC_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PRIVATE_KEYWORD, JetTokens.INTERNAL_KEYWORD)); if (getterDescriptor.getVisibility() != propertyDescriptor.getVisibility()) { for (ASTNode node : nodes.values()) { trace.report(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.on(node.getPsi())); } } else { for (ASTNode node : nodes.values()) { trace.report(Errors.REDUNDANT_MODIFIER_IN_GETTER.on(node.getPsi())); } } } }
private void resolveProperty( @NotNull BodiesResolveContext c, @Nullable LexicalScope parentScope, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) { computeDeferredType(propertyDescriptor.getReturnType()); JetExpression initializer = property.getInitializer(); LexicalScope propertyScope = getScopeForProperty(c, property); if (parentScope == null) { parentScope = propertyScope; } if (initializer != null) { resolvePropertyInitializer( c.getOuterDataFlowInfo(), property, propertyDescriptor, initializer, propertyScope); } JetExpression delegateExpression = property.getDelegateExpression(); if (delegateExpression != null) { assert initializer == null : "Initializer should be null for delegated property : " + property.getText(); resolvePropertyDelegate( c.getOuterDataFlowInfo(), property, propertyDescriptor, delegateExpression, parentScope, propertyScope); } resolvePropertyAccessors(c, property, propertyDescriptor); }
private static void forceResolvePackageDeclarations( @NotNull Collection<JetFile> files, @NotNull KotlinCodeAnalyzer session) { for (JetFile file : files) { // SCRIPT: not supported if (file.isScript()) continue; FqName packageFqName = file.getPackageFqName(); // make sure we create a package descriptor PackageViewDescriptor packageDescriptor = session.getModuleDescriptor().getPackage(packageFqName); if (packageDescriptor.isEmpty()) { LOG.warn( "No descriptor found for package " + packageFqName + " in file " + file.getName() + "\n" + file.getText()); session.forceResolveAll(); continue; } for (JetDeclaration declaration : file.getDeclarations()) { if (declaration instanceof JetFunction) { JetFunction jetFunction = (JetFunction) declaration; Name name = jetFunction.getNameAsSafeName(); Collection<FunctionDescriptor> functions = packageDescriptor.getMemberScope().getFunctions(name, LookupLocation.NO_LOCATION); for (FunctionDescriptor descriptor : functions) { ForceResolveUtil.forceResolveAllContents(descriptor); } } else if (declaration instanceof JetProperty) { JetProperty jetProperty = (JetProperty) declaration; Name name = jetProperty.getNameAsSafeName(); Collection<VariableDescriptor> properties = packageDescriptor.getMemberScope().getProperties(name, LookupLocation.NO_LOCATION); for (VariableDescriptor descriptor : properties) { ForceResolveUtil.forceResolveAllContents(descriptor); } } else if (declaration instanceof JetClassOrObject) { // Do nothing: we are not interested in classes } else { LOG.error( "Unsupported declaration kind: " + declaration + " in file " + file.getName() + "\n" + file.getText()); } } } }
private void resolvePropertyDeclarationBodies() { // Member properties Set<JetProperty> processed = Sets.newHashSet(); for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) { JetClass jetClass = entry.getKey(); if (!context.completeAnalysisNeeded(jetClass)) continue; MutableClassDescriptor classDescriptor = entry.getValue(); for (JetProperty property : jetClass.getProperties()) { final PropertyDescriptor propertyDescriptor = this.context.getProperties().get(property); assert propertyDescriptor != null; computeDeferredType(propertyDescriptor.getReturnType()); JetExpression initializer = property.getInitializer(); if (initializer != null) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (primaryConstructor != null) { JetScope declaringScopeForPropertyInitializer = this.context.getDeclaringScopes().get(property); resolvePropertyInitializer( property, propertyDescriptor, initializer, declaringScopeForPropertyInitializer); } } resolvePropertyAccessors(property, propertyDescriptor); processed.add(property); } } // Top-level properties & properties of objects for (Map.Entry<JetProperty, PropertyDescriptor> entry : this.context.getProperties().entrySet()) { JetProperty property = entry.getKey(); if (!context.completeAnalysisNeeded(property)) continue; if (processed.contains(property)) continue; final PropertyDescriptor propertyDescriptor = entry.getValue(); computeDeferredType(propertyDescriptor.getReturnType()); JetScope declaringScope = this.context.getDeclaringScopes().get(property); JetExpression initializer = property.getInitializer(); if (initializer != null) { resolvePropertyInitializer(property, propertyDescriptor, initializer, declaringScope); } resolvePropertyAccessors(property, propertyDescriptor); } }
private void resolvePropertyInitializer( JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) { // JetFlowInformationProvider flowInformationProvider = // context.getDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15 JetType expectedTypeForInitializer = property.getPropertyTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE; JetType type = expressionTypingServices.getType( descriptorResolver.getPropertyDeclarationInnerScope( scope, propertyDescriptor, propertyDescriptor.getTypeParameters(), propertyDescriptor.getReceiverParameter(), trace), initializer, expectedTypeForInitializer, trace); // // JetType expectedType = propertyDescriptor.getInType(); // if (expectedType == null) { // expectedType = propertyDescriptor.getType(); // } // if (type != null && expectedType != null // && !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, // expectedType)) { //// trace.report(TYPE_MISMATCH.on(initializer, expectedType, type)); // } }
@NotNull private static LexicalScope getScopeForProperty( @NotNull BodiesResolveContext c, @NotNull JetProperty property) { LexicalScope scope = c.getDeclaringScope(property); assert scope != null : "Scope for property " + property.getText() + " should exists"; return scope; }
public void resolvePropertyDelegate( @NotNull DataFlowInfo outerDataFlowInfo, @NotNull JetProperty jetProperty, @NotNull PropertyDescriptor propertyDescriptor, @NotNull JetExpression delegateExpression, @NotNull LexicalScope parentScopeForAccessor, @NotNull LexicalScope propertyScope) { JetPropertyAccessor getter = jetProperty.getGetter(); if (getter != null && getter.hasBody()) { trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(getter)); } JetPropertyAccessor setter = jetProperty.getSetter(); if (setter != null && setter.hasBody()) { trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter)); } LexicalScope propertyDeclarationInnerScope = JetScopeUtils.getPropertyDeclarationInnerScopeForInitializer( propertyDescriptor, propertyScope, propertyDescriptor.getTypeParameters(), null, trace); LexicalScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor( propertyDescriptor, parentScopeForAccessor, trace); JetType delegateType = delegatedPropertyResolver.resolveDelegateExpression( delegateExpression, jetProperty, propertyDescriptor, propertyDeclarationInnerScope, accessorScope, trace, outerDataFlowInfo); delegatedPropertyResolver.resolveDelegatedPropertyGetMethod( propertyDescriptor, delegateExpression, delegateType, trace, accessorScope); if (jetProperty.isVar()) { delegatedPropertyResolver.resolveDelegatedPropertySetMethod( propertyDescriptor, delegateExpression, delegateType, trace, accessorScope); } delegatedPropertyResolver.resolveDelegatedPropertyPDMethod( propertyDescriptor, delegateExpression, delegateType, trace, accessorScope); }
private void resolvePropertyAccessors( JetProperty property, PropertyDescriptor propertyDescriptor) { ObservableBindingTrace fieldAccessTrackingTrace = createFieldTrackingTrace(propertyDescriptor); JetPropertyAccessor getter = property.getGetter(); PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter(); if (getter != null && getterDescriptor != null) { JetScope accessorScope = makeScopeForPropertyAccessor(getter, propertyDescriptor); resolveFunctionBody(fieldAccessTrackingTrace, getter, getterDescriptor, accessorScope); } JetPropertyAccessor setter = property.getSetter(); PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); if (setter != null && setterDescriptor != null) { JetScope accessorScope = makeScopeForPropertyAccessor(setter, propertyDescriptor); resolveFunctionBody(fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope); } }
public void resolvePropertyInitializer( @NotNull DataFlowInfo outerDataFlowInfo, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor, @NotNull JetExpression initializer, @NotNull LexicalScope scope) { LexicalScope propertyDeclarationInnerScope = JetScopeUtils.getPropertyDeclarationInnerScopeForInitializer( propertyDescriptor, scope, propertyDescriptor.getTypeParameters(), null, trace); JetType expectedTypeForInitializer = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE; if (propertyDescriptor.getCompileTimeInitializer() == null) { expressionTypingServices.getType( propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, outerDataFlowInfo, trace); } }
private static void propertyAdditionalResolve( final ResolveSession resolveSession, final JetProperty jetProperty, DelegatingBindingTrace trace, JetFile file) { final JetScope propertyResolutionScope = resolveSession .getInjector() .getScopeProvider() .getResolutionScopeForDeclaration(jetProperty); BodyResolveContextForLazy bodyResolveContext = new BodyResolveContextForLazy( new Function<JetDeclaration, JetScope>() { @Override public JetScope apply(JetDeclaration declaration) { assert declaration.getParent() == jetProperty : "Must be called only for property accessors, but called for " + declaration; return propertyResolutionScope; } }); BodyResolver bodyResolver = createBodyResolver( trace, file, bodyResolveContext, resolveSession.getModuleConfiguration()); PropertyDescriptor descriptor = (PropertyDescriptor) resolveSession.resolveToDescriptor(jetProperty); JetExpression propertyInitializer = jetProperty.getInitializer(); if (propertyInitializer != null) { bodyResolver.resolvePropertyInitializer( jetProperty, descriptor, propertyInitializer, propertyResolutionScope); } bodyResolver.resolvePropertyAccessors(jetProperty, descriptor); }
private void checkPropertyAbstractness( @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor, @NotNull ClassDescriptor classDescriptor) { JetPropertyAccessor getter = property.getGetter(); JetPropertyAccessor setter = property.getSetter(); JetModifierList modifierList = property.getModifierList(); ASTNode abstractNode = modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null; if (abstractNode != null) { // has abstract modifier if (!classCanHaveAbstractMembers(classDescriptor)) { String name = property.getName(); trace.report( ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on( property, name != null ? name : "", classDescriptor)); return; } if (classDescriptor.getKind() == ClassKind.INTERFACE) { trace.report(ABSTRACT_MODIFIER_IN_TRAIT.on(property)); } } if (propertyDescriptor.getModality() == Modality.ABSTRACT) { JetExpression initializer = property.getInitializer(); if (initializer != null) { trace.report(ABSTRACT_PROPERTY_WITH_INITIALIZER.on(initializer)); } JetPropertyDelegate delegate = property.getDelegate(); if (delegate != null) { trace.report(ABSTRACT_DELEGATED_PROPERTY.on(delegate)); } if (getter != null && getter.hasBody()) { trace.report(ABSTRACT_PROPERTY_WITH_GETTER.on(getter)); } if (setter != null && setter.hasBody()) { trace.report(ABSTRACT_PROPERTY_WITH_SETTER.on(setter)); } } }
private void checkPropertyInitializer( @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) { JetPropertyAccessor getter = property.getGetter(); JetPropertyAccessor setter = property.getSetter(); boolean hasAccessorImplementation = (getter != null && getter.hasBody()) || (setter != null && setter.hasBody()); if (propertyDescriptor.getModality() == Modality.ABSTRACT) { if (!property.hasDelegateExpressionOrInitializer() && property.getTypeReference() == null) { trace.report(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER.on(property)); } return; } DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); boolean inTrait = containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.INTERFACE; JetExpression initializer = property.getInitializer(); JetPropertyDelegate delegate = property.getDelegate(); boolean backingFieldRequired = Boolean.TRUE.equals( trace .getBindingContext() .get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)); if (inTrait && backingFieldRequired && hasAccessorImplementation) { trace.report(BACKING_FIELD_IN_TRAIT.on(property)); } if (initializer == null && delegate == null) { boolean error = false; if (backingFieldRequired && !inTrait && Boolean.TRUE.equals( trace.getBindingContext().get(BindingContext.IS_UNINITIALIZED, propertyDescriptor))) { if (!(containingDeclaration instanceof ClassDescriptor) || hasAccessorImplementation) { error = true; trace.report(MUST_BE_INITIALIZED.on(property)); } else { error = true; trace.report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property)); } } if (!error && property.getTypeReference() == null) { trace.report(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER.on(property)); } if (inTrait && property.hasModifier(JetTokens.FINAL_KEYWORD) && backingFieldRequired) { trace.report(FINAL_PROPERTY_IN_TRAIT.on(property)); } return; } if (inTrait) { if (delegate != null) { trace.report(DELEGATED_PROPERTY_IN_TRAIT.on(delegate)); } else { trace.report(PROPERTY_INITIALIZER_IN_TRAIT.on(initializer)); } } else if (delegate == null) { if (!backingFieldRequired) { trace.report(PROPERTY_INITIALIZER_NO_BACKING_FIELD.on(initializer)); } else if (property.getReceiverTypeReference() != null) { trace.report(EXTENSION_PROPERTY_WITH_BACKING_FIELD.on(initializer)); } } }