static CompleterResult GenerateProperties(SemanticModel model, INamedTypeSymbol type, InvocationExpressionSyntax[] chain) { var last = (MemberAccessExpressionSyntax)chain.Last().Expression; var ownerTypeSyntax = ((GenericNameSyntax)last.Expression).TypeArgumentList.Arguments.Single(); var ownerType = model.GetTypeInfo(ownerTypeSyntax).Type; if(ownerType != type) return new CompleterError(ownerTypeSyntax, Messages.DependecyProperty_IncorrectOwnerType).YieldToImmutable(); var properties = chain .Take(chain.Length - 1) .Select(property => { var memberAccess = (MemberAccessExpressionSyntax)property.Expression; var methodName = memberAccess.Name.Identifier.ValueText; if(!methodName.StartsWith("Register")) return null; var readOnly = methodName == "RegisterReadOnly" || methodName == "RegisterAttachedReadOnly"; var attached = methodName == "RegisterAttached" || methodName == "RegisterAttachedReadOnly"; var arguments = property.ArgumentList.Arguments; var propertySignature = (memberAccess.Name as GenericNameSyntax)?.TypeArgumentList.Arguments.Select(x => x.ToString()).ToArray(); if(propertySignature == null) { var defaultValueArgument = arguments[readOnly ? 3 : 2].Expression; var defaultExpressionTypeInfo = model.GetTypeInfo(defaultValueArgument); propertySignature = defaultExpressionTypeInfo.Type?.DisplayString(model, defaultValueArgument.GetLocation()).With(propertyType => !attached ? new string[] { propertyType } : (arguments[0].Expression as ParenthesizedLambdaExpressionSyntax).With(x => new string[] { x.ParameterList.Parameters.Single().Type.ToString(), propertyType }) ); } if(propertySignature == null) { var span = memberAccess.Name.LineSpan(); return new CompleterError(memberAccess.SyntaxTree, Messages.DependecyProperty_PropertyTypeMissed, new FileLinePositionSpan(string.Empty, span.EndLinePosition, span.EndLinePosition)); } var propertyName = GetPropertyName(arguments, attached, readOnly, memberAccess.Name.SyntaxTree); return propertyName.Select(name => { var overridedPropertyVisibility = GetOverridedPropertyVisibility(type, name); return GenerateFields(name, readOnly, overridedPropertyVisibility == null) + (attached ? GenerateAttachedProperty(propertySignature[0], propertySignature[1], name, readOnly, overridedPropertyVisibility) : GenerateProperty(propertySignature.Single(), name, readOnly, overridedPropertyVisibility)); }); }) .Where(x => x != null) .Reverse() .ToArray(); return properties .AggregateEither(errors => errors.ToImmutableArray(), values => values.ConcatStringsWithNewLines()); }