private BoundExpression BindPropertyAccessExpression(PropertyAccessExpressionSyntax node) { var target = BindExpression(node.Target); // For cases like Foo.Bar we check whether 'Foo' was resolved to a table instance. // If that's the case we bind a column otherwise we bind a normal expression. var boundTable = target as BoundTableExpression; if (boundTable != null) { // In Foo.Bar, Foo was resolved to a table. Bind Bar as column. var tableInstance = boundTable.Symbol; return(BindColumnInstance(node, tableInstance)); } // node.Target either wasn't a name expression or didn't resolve to a // table instance. Resolve node.Name as a property. var name = node.Name; if (target.Type.IsError()) { // To avoid cascading errors, we'll give up early. return(new BoundErrorExpression()); } var propertySymbols = LookupProperty(target.Type, name).ToImmutableArray(); if (propertySymbols.Length == 0) { var hasMethods = LookupMethod(target.Type, name).Any(); if (hasMethods) { Diagnostics.ReportInvocationRequiresParenthesis(name); } else { Diagnostics.ReportUndeclaredProperty(node, target.Type); } return(new BoundErrorExpression()); } if (propertySymbols.Length > 1) { Diagnostics.ReportAmbiguousProperty(name); } var propertySymbol = propertySymbols[0]; return(new BoundPropertyAccessExpression(target, propertySymbol)); }
private BoundExpression BindColumnInstance(PropertyAccessExpressionSyntax node, TableInstanceSymbol tableInstance) { var columnName = node.Name; var columnInstances = tableInstance.ColumnInstances.Where(c => columnName.Matches(c.Name)).ToImmutableArray(); if (columnInstances.Length == 0) { Diagnostics.ReportUndeclaredColumn(node, tableInstance); return(new BoundErrorExpression()); } if (columnInstances.Length > 1) { Diagnostics.ReportAmbiguousColumnInstance(columnName, columnInstances); } var columnInstance = columnInstances.First(); return(new BoundColumnExpression(columnInstance)); }
public virtual void VisitPropertyAccessExpression(PropertyAccessExpressionSyntax node) { DefaultVisit(node); }
public static void ReportUndeclaredProperty(this ICollection <Diagnostic> diagnostics, PropertyAccessExpressionSyntax node, Type type) { var typeName = type.ToDisplayName(); var propertyName = node.Name.ValueText; diagnostics.Report(node.Span, DiagnosticId.UndeclaredProperty, typeName, propertyName); }
public static void ReportUndeclaredColumn(this ICollection <Diagnostic> diagnostics, PropertyAccessExpressionSyntax node, TableInstanceSymbol tableInstance) { var tableName = tableInstance.Name; var columnName = node.Name.ValueText; diagnostics.Report(node.Span, DiagnosticId.UndeclaredColumn, tableName, columnName); }
public virtual TResult VisitPropertyAccessExpression(PropertyAccessExpressionSyntax node) { return(DefaultVisit(node)); }
private void ClassifyPropertyAccess(PropertyAccessExpressionSyntax node) { ClassifyNode(node.Target); ClassifyExpression(node, node.Name); }
private static IEnumerable <CompletionItem> GetMemberCompletions(SemanticModel semanticModel, PropertyAccessExpressionSyntax propertyAccessExpression) { var tableInstanceSymbol = semanticModel.GetSymbol(propertyAccessExpression.Target) as TableInstanceSymbol; if (tableInstanceSymbol != null) { return(GetTableCompletions(tableInstanceSymbol)); } var targetType = semanticModel.GetExpressionType(propertyAccessExpression.Target); if (targetType != null && !targetType.IsUnknown() && !targetType.IsError()) { return(GetTypeCompletions(semanticModel, targetType)); } return(Enumerable.Empty <CompletionItem>()); }