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)); // } }
private void initializeProperty( @NotNull ExpressionCodegen codegen, @NotNull JetProperty property) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property); assert propertyDescriptor != null; JetExpression initializer = property.getDelegateExpressionOrInitializer(); assert initializer != null : "shouldInitializeProperty must return false if initializer is null"; JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor); StackValue.Property propValue = codegen.intermediateValueForProperty( propertyDescriptor, true, null, MethodKind.INITIALIZER); if (!propValue.isStatic) { codegen.v.load(0, OBJECT_TYPE); } Type type = codegen.expressionType(initializer); if (jetType.isNullable()) { type = boxType(type); } codegen.gen(initializer, type); propValue.store(type, codegen.v); }
@Override public JetTypeInfo visitProperty(JetProperty property, ExpressionTypingContext context) { JetTypeReference receiverTypeRef = property.getReceiverTypeRef(); if (receiverTypeRef != null) { context.trace.report(LOCAL_EXTENSION_PROPERTY.on(receiverTypeRef)); } JetPropertyAccessor getter = property.getGetter(); if (getter != null) { context.trace.report(LOCAL_VARIABLE_WITH_GETTER.on(getter)); } JetPropertyAccessor setter = property.getSetter(); if (setter != null) { context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter)); } VariableDescriptor propertyDescriptor = context .expressionTypingServices .getDescriptorResolver() .resolveLocalVariableDescriptor( scope.getContainingDeclaration(), scope, property, context.dataFlowInfo, context.trace); JetExpression initializer = property.getInitializer(); DataFlowInfo dataFlowInfo = context.dataFlowInfo; if (initializer != null) { JetType outType = propertyDescriptor.getType(); JetTypeInfo typeInfo = facade.getTypeInfo(initializer, context.replaceExpectedType(outType).replaceScope(scope)); dataFlowInfo = typeInfo.getDataFlowInfo(); } { VariableDescriptor olderVariable = scope.getLocalVariable(propertyDescriptor.getName()); ExpressionTypingUtils.checkVariableShadowing(context, propertyDescriptor, olderVariable); } scope.addVariableDescriptor(propertyDescriptor); ModifiersChecker.create(context.trace).checkModifiersForLocalDeclaration(property); return DataFlowUtils.checkStatementType(property, context, dataFlowInfo); }
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); } }
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) { List<JetProperty> delegatedProperties = new ArrayList<JetProperty>(); for (JetDeclaration declaration : ((JetDeclarationContainer) element).getDeclarations()) { if (declaration instanceof JetProperty) { JetProperty property = (JetProperty) declaration; if (property.getDelegate() != null) { delegatedProperties.add(property); } } } if (delegatedProperties.isEmpty()) return; v.newField( null, ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.PROPERTY_METADATA_ARRAY_NAME, "[" + PROPERTY_METADATA_TYPE, null, null); InstructionAdapter iv = createOrGetClInitCodegen().v; iv.iconst(delegatedProperties.size()); iv.newarray(PROPERTY_METADATA_TYPE); for (int i = 0, size = delegatedProperties.size(); i < size; i++) { VariableDescriptor property = BindingContextUtils.getNotNull(bindingContext, VARIABLE, delegatedProperties.get(i)); iv.dup(); iv.iconst(i); iv.anew(PROPERTY_METADATA_IMPL_TYPE); iv.dup(); iv.visitLdcInsn(property.getName().asString()); iv.invokespecial( PROPERTY_METADATA_IMPL_TYPE.getInternalName(), "<init>", "(Ljava/lang/String;)V"); iv.astore(PROPERTY_METADATA_IMPL_TYPE); } iv.putstatic( thisAsmType.getInternalName(), JvmAbi.PROPERTY_METADATA_ARRAY_NAME, "[" + PROPERTY_METADATA_TYPE); }
@NotNull private JetType getPropertyOrDelegateType( @NotNull JetProperty property, @NotNull PropertyDescriptor descriptor) { JetExpression delegateExpression = property.getDelegateExpression(); if (delegateExpression != null) { JetType delegateType = bindingContext.get(BindingContext.EXPRESSION_TYPE, delegateExpression); assert delegateType != null : "Type of delegate expression should be recorded"; return delegateType; } return descriptor.getType(); }
private void generateBackingField(JetProperty p, PropertyDescriptor propertyDescriptor) { if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); if (CodegenUtil.isInterface(containingDeclaration)) return; Object value = null; final JetExpression initializer = p.getInitializer(); if (initializer != null) { if (initializer instanceof JetConstantExpression) { CompileTimeConstant<?> compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer); value = compileTimeValue != null ? compileTimeValue.getValue() : null; } } int modifiers; if (kind == OwnerKind.NAMESPACE) { int access = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0); modifiers = access | Opcodes.ACC_STATIC; } else { modifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0); } if (!propertyDescriptor.isVar()) { modifiers |= Opcodes.ACC_FINAL; } if (state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) { modifiers |= Opcodes.ACC_VOLATILE; } Type type = state .getInjector() .getJetTypeMapper() .mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); FieldVisitor fieldVisitor = v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, value); AnnotationCodegen.forField(fieldVisitor, state.getInjector().getJetTypeMapper()) .genAnnotations(propertyDescriptor); } }
private boolean shouldInitializeProperty(@NotNull JetProperty property) { JetExpression initializer = property.getDelegateExpressionOrInitializer(); if (initializer == null) return false; PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property); assert propertyDescriptor != null; CompileTimeConstant<?> compileTimeValue = propertyDescriptor.getCompileTimeInitializer(); if (compileTimeValue == null) return true; // TODO: OPTIMIZATION: don't initialize static final fields Object value = compileTimeValue.getValue(); JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor); Type type = typeMapper.mapType(jetType); return !skipDefaultValue(propertyDescriptor, value, type); }
private void generateGetter(JetProperty p, PropertyDescriptor propertyDescriptor) { final JetPropertyAccessor getter = p.getGetter(); if (getter != null) { if (getter.getBodyExpression() != null) { JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapGetterSignature(propertyDescriptor, kind); functionCodegen.generateMethod( getter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), propertyDescriptor.getGetter()); } else if (isExternallyAccessible(propertyDescriptor)) { generateDefaultGetter(p); } } else if (isExternallyAccessible(propertyDescriptor)) { generateDefaultGetter(p); } }
private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) { final JetPropertyAccessor setter = p.getSetter(); if (setter != null) { if (setter.getBodyExpression() != null) { final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); assert setterDescriptor != null; JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind); functionCodegen.generateMethod( setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), setterDescriptor); } else if (isExternallyAccessible(propertyDescriptor)) { generateDefaultSetter(p); } } else if (isExternallyAccessible(propertyDescriptor) && propertyDescriptor.isVar()) { generateDefaultSetter(p); } }
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); }
@Override public void visitProperty(JetProperty property) { nameStack.push(peekFromStack(nameStack) + '$' + property.getName()); super.visitProperty(property); nameStack.pop(); }