private BoundExpression BindElementAccess(ElementAccessExpressionSyntax node) { Debug.Assert(node != null); var expr = BindExpression(node.Expression); // , BIND_RVALUEREQUIRED); var arguments = node.ArgumentList.Arguments .Select(arg => BindExpression(arg.Expression)) .ToList(); var argumentNames = node.ArgumentList.Arguments .Select(arg => arg.NameColonOpt) .Select(namecolon => namecolon != null ? namecolon.Identifier.GetText() : null) .ToList(); if (expr.GetExpressionType() == null) { return BoundArrayAccess.AsError(node, expr, arguments, null); } if (!expr.IsOK || arguments.Any(x => !x.IsOK)) { // At this point we definitely have reported an error, but we still might be // able to get more semantic analysis of the indexing operation. We do not // want to report cascading errors. // UNDONE: Set the error bit on the result? return GetErrorSuppressingAnalyzer().BindElementAccessCore(node, expr, arguments, argumentNames); } return BindElementAccessCore(node, expr, arguments, argumentNames); }
private BoundExpression BindElementAccessCore(ElementAccessExpressionSyntax node, BoundExpression expr, IList<BoundExpression> arguments, IList<string> argumentNames) { Debug.Assert(node != null); Debug.Assert(expr != null); Debug.Assert(arguments != null); Debug.Assert(argumentNames != null); // UNDONE: Suppose we have an indexed property P on an instance c. Suppose the // UNDONE: type of the property is int[]. When binding c.P[123] we must // UNDONE: treat this as an invocation of the indexed property, not as a // UNDONE: dereference of the array returned by the property. //if (expr.isPROP() && expr.asPROP().IsUnboundIndexedProperty() && // !IsPropertyBindingInsideBindIndexerContext(node.Expression)) //{ // return BindIndexerAccess(node, expr, arguments, argumentNames); //} var exprType = expr.GetExpressionType(); // UNDONE: Ensure that the type of the expression has members defined. if (exprType is ArrayTypeSymbol) { return BindArrayAccess(node, expr, arguments, argumentNames); } else if (exprType is PointerTypeSymbol) { return BindPointerElementAccess(node, expr, arguments, argumentNames); } else { return BindIndexerAccess(node, expr, arguments, argumentNames); } }
public override SyntaxNode VisitElementAccessExpression(ElementAccessExpressionSyntax node) { TypeInfo ti = Model.GetTypeInfo(node.Expression); if (ti.ConvertedType.TypeKind != TypeKind.Class) return base.VisitElementAccessExpression(node); if (ti.ConvertedType.GetFullyQualifiedName() == "LavishScript2.Table") { base.VisitElementAccessExpression(node); } // convert to method access SymbolInfo si = Model.GetSymbolInfo(node); if (si.Symbol.Kind != SymbolKind.Property) { throw new NotImplementedException("element access on type " + ti.ConvertedType.GetFullyQualifiedName() + " resolves to " + si.Symbol.Kind.ToString()); } IPropertySymbol ps = (IPropertySymbol)si.Symbol; if (ps.IsStatic) { throw new NotSupportedException("static indexer?"); } //SyntaxFactory.MemberAccessExpression(SyntaxKind.IdentifierName) return SyntaxFactory.InvocationExpression(SyntaxFactory.MemberAccessExpression ( SyntaxKind.SimpleMemberAccessExpression,node.Expression, SyntaxFactory.IdentifierName("get_Item") // ps.GetMethod.Name ), SyntaxFactory.ArgumentList(node.ArgumentList.Arguments)); //return base.VisitElementAccessExpression(node); }
public BoundElementAccessExpression(ElementAccessExpressionSyntax syntax, BoundExpression expression, BoundExpression index, IndexerSymbol indexer) : base(BoundNodeKind.ElementAccessExpression, syntax) { Expression = expression; Index = index; Type = indexer.AssociatedType; }
/// <summary> /// Ensures that we don't try to lift the arguments of an array access; we can't get a symbol for /// array's [] operator. /// </summary> public override SyntaxNode VisitElementAccessExpression(ElementAccessExpressionSyntax elementAccess) { if (elementAccess.Expression.GetExpressionType(SemanticModel).TypeKind == TypeKind.Array) return elementAccess; return base.VisitElementAccessExpression(elementAccess); }
public static void Go(OutputWriter writer, ElementAccessExpressionSyntax expression) { var type = TypeProcessor.GetTypeInfo(expression.Expression).Type; var typeStr = TypeProcessor.GenericTypeName(type); var additionalParam = ""; var symbol = TypeProcessor.GetSymbolInfo(expression); //This could be null if (symbol.Symbol != null) { var methodSymbol = symbol.Symbol as IPropertySymbol; //Lets find out if this is an interface implementation if (methodSymbol != null) { IEnumerable<ISymbol> interfaceMethods = methodSymbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(methodSymbol.Name)); interfaceMethods = interfaceMethods.Where( o => Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(o), methodSymbol)); if (interfaceMethods.Any()) { //Lets get the best match var interfaceMethod = interfaceMethods.FirstOrDefault(); additionalParam = "cast("+ TypeProcessor.ConvertType(interfaceMethod.ContainingType)+")null"; } } } //type.GetMembers("this[]") //Todo if we are using unsafe / fast mode, just use array->Data()[i] should bypass bounds check and indirection also should be as fast as pure c++ arrays //though fixed syntax could fix this too ?? // writer.Write("(*"); Core.Write(writer, expression.Expression); if (type.SpecialType == SpecialType.System_Array) // writer.Write(")"); writer.Write(".Items["); //TODO test this thoroughly else writer.Write("["); //TODO test this thoroughly var first = true; foreach (var argument in expression.ArgumentList.Arguments) { if (first) first = false; else writer.Write(", "); Core.Write(writer, argument.Expression); } if(additionalParam!="") writer.Write("," + additionalParam); writer.Write("]"); }
private static List<ExpressionSyntax> GetListCollectionInitializerElements(ElementAccessExpressionSyntax node) { var arguments = node.ArgumentList.Arguments; if (arguments.Count == 0) return null; if (arguments.Count == 1) { var arg = arguments[0]; //should be greaterThen expression containing lessthen expression var greaterThenBinaryExpression = arg.Expression as BinaryExpressionSyntax; if (greaterThenBinaryExpression == null || greaterThenBinaryExpression.OperatorToken.Kind != SyntaxKind.GreaterThanToken) return null; var lessThenBinaryExpression = greaterThenBinaryExpression.ChildNodes().OfType<BinaryExpressionSyntax>().FirstOrDefault(); if (lessThenBinaryExpression == null || lessThenBinaryExpression.OperatorToken.Kind != SyntaxKind.LessThanToken) return null; var result = lessThenBinaryExpression.ChildNodes().OfType<ExpressionSyntax>().SingleOrDefault(child => !child.IsMissing); if (result == null) { //we are dealing with [<>] construct - returning empty list return new List<ExpressionSyntax>(); } return new List<ExpressionSyntax> { result }; } else { var first = arguments[0].Expression as BinaryExpressionSyntax; var last = arguments.Last().Expression as BinaryExpressionSyntax; if (first == null || first.Kind != SyntaxKind.LessThanExpression || last == null || last.Kind != SyntaxKind.GreaterThanExpression) { return null; } var result = new List<ExpressionSyntax> { first.Right, last.Left }; var totalArgs = arguments.Count; result.InsertRange(1, arguments.Skip(1).Take(totalArgs - 2).Select(arg => arg.Expression)); return result; } }
private BoundExpression BindArrayAccess(ElementAccessExpressionSyntax node, BoundExpression expr, IList<BoundExpression> arguments, IList<string> argumentNames) { Debug.Assert(node != null); Debug.Assert(expr != null); Debug.Assert(arguments != null); Debug.Assert(argumentNames != null); // For an array access, the primary-no-array-creation-expression of the element-access must // be a value of an array-type. Furthermore, the argument-list of an array access is not // allowed to contain named arguments.The number of expressions in the argument-list must // be the same as the rank of the array-type, and each expression must be of type // int, uint, long, ulong, or must be implicitly convertible to one or more of these types. if (argumentNames.Any(x => x != null)) { Error(ErrorCode.ERR_NamedArgumentForArray, node); } var arrayType = (ArrayTypeSymbol)expr.GetExpressionType(); // Note that the spec says to determine which of {int, uint, long, ulong} *each* // index expression is convertible to. That is not what C# 1 through 4 // did; the implementations instead determined which of those four // types *all* of the index expressions converted to. int rank = arrayType.Rank; if (arguments.Count != arrayType.Rank) { Error(ErrorCode.ERR_BadIndexCount, node, rank); return BoundArrayAccess.AsError(node, expr, arguments, arrayType.ElementType); } var convertedArguments = arguments.Select(x => ConvertToArrayIndex(x)).ToList(); return new BoundArrayAccess(node, expr, convertedArguments, arrayType.ElementType); }
public override SyntaxNode VisitElementAccessExpression(ElementAccessExpressionSyntax node) { var elements = GetListCollectionInitializerElements(node); if (elements != null) { if (elements.Count > 0) { var type = GetArgumentType(elements[0]); var syntaxList = new SeparatedSyntaxList<ExpressionSyntax>(); var intializerExpr = Syntax.InitializerExpression(SyntaxKind.CollectionInitializerExpression, syntaxList.Add(elements.ToArray())); return Syntax.ParseExpression(string.Format("new System.Collections.Generic.List<{1}>{0}", intializerExpr, type)); } else { //no elements of list - returning empty list of objects return Syntax.ParseExpression("new System.Collections.Generic.List<Object>()"); } } return base.VisitElementAccessExpression(node); }
/// <summary> /// Same as SemanticModel.GetSymbolInfo().Symbol but works when <paramref name="node"/> is not in the syntax tree. /// </summary> /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param> /// <param name="node">The <see cref="ParameterSyntax"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <returns>A <see cref="IPropertySymbol"/> or an <see cref="IArrayTypeSymbol"/> or null.</returns> public static ISymbol GetSymbolSafe(this SemanticModel semanticModel, ElementAccessExpressionSyntax node, CancellationToken cancellationToken) { return(GetSymbolSafe(semanticModel, (SyntaxNode)node, cancellationToken)); }
private BoundExpression BindPointerElementAccess(ElementAccessExpressionSyntax node, BoundExpression expr, IList<BoundExpression> arguments, IList<string> argumentNames) { Debug.Assert(node != null); Debug.Assert(expr != null); Debug.Assert(arguments != null); Debug.Assert(argumentNames != null); // UNDONE: This is the error reported by the original compiler, but it seems wrong. We should not be // UNDONE: giving the error "named argument used in array access" for a pointer access. if (argumentNames.Any(x => x != null)) { Error(ErrorCode.ERR_NamedArgumentForArray, node); } throw new NotImplementedException(); }
public static ElementAccessExpressionSyntax WithArgumentList(this ElementAccessExpressionSyntax indexer, IEnumerable <ArgumentSyntax> arguments) => indexer.WithArgumentList(BracketedArgumentList(SeparatedList(arguments)));
public override SyntaxNode VisitElementAccessExpression(ElementAccessExpressionSyntax node) { this.VisitExpression(node.Expression); _output.TrivialWrite('['); if (node.ArgumentList.Arguments.Count > 1) { this.AppendCompileIssue(node, IssueType.Error, IssueId.MultiDimensionArrayAccessNotSupport); } this.MakeArgumentsList(node.ArgumentList.Arguments); _output.TrivialWrite(']'); return node; }
public override SyntaxNode VisitElementAccessExpression(ElementAccessExpressionSyntax node) { bool isAssignment = node.Expression.IsMissing; bool isParam = node.Expression is InvocationExpressionSyntax; if (!isAssignment && !isParam) return node; List<ExpressionSyntax> casting = new List<ExpressionSyntax>(); foreach (ArgumentSyntax arg in node.ArgumentList.Arguments) { casting.Add(arg.Expression); } ArrayCreationExpressionSyntax array = SyntaxFactory.ArrayCreationExpression( SyntaxFactory.ArrayType(SyntaxFactory.IdentifierName("object[]")), SyntaxFactory.InitializerExpression(SyntaxKind.ArrayInitializerExpression, SyntaxFactory.SeparatedList(casting))); if (isAssignment) { return ctx_.AddLinker(array, linkArray); } else if (isParam) { //first parameter is an array var invocation = (InvocationExpressionSyntax)node.Expression; var newInvocation = SyntaxFactory.InvocationExpression(invocation.Expression); var result = ctx_.AddLinker(newInvocation, (ctx, linkNode, newNode, model) => { var args = (ArgumentListSyntax)ctx.GetLinkData(linkNode); var inv = (InvocationExpressionSyntax)newNode; return inv.WithArgumentList(args); }); Debug.Assert(pending_ == null); pending_ = new ResolveArrayArgument(ctx_, result, array); return result; } return node; }
internal static bool IsArgumentListToken(ElementAccessExpressionSyntax expression, SyntaxToken token) { return(expression.ArgumentList.Span.Contains(token.SpanStart) && token != expression.ArgumentList.CloseBracketToken); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { this.OnNodeVisited(node, this.type.IsInstanceOfType(node)); base.VisitElementAccessExpression(node); }
static CodeAction CreateIndexerCodeAction(Document document, SyntaxNode root, ExpressionSyntax node, IPropertySymbol indexer, ElementAccessExpressionSyntax elementAccess) { var arguments = elementAccess.ArgumentList.Arguments; var idx = arguments.IndexOf(node.Parent as ArgumentSyntax); if (idx >= indexer.Parameters.Length) // this can happen with "params" parameters { return(null); } var name = indexer.Parameters[idx].Name; return(CodeActionFactory.Create( node.Span, DiagnosticSeverity.Info, string.Format("Add argument name '{0}'", name), t2 => { var newArguments = SyntaxFactory.SeparatedList <ArgumentSyntax>( elementAccess.ArgumentList.Arguments.Take(idx).Concat( elementAccess.ArgumentList.Arguments.Skip(idx).Select((arg, i) => { if (arg.NameColon != null) { return arg; } return arg.WithNameColon(SyntaxFactory.NameColon(indexer.Parameters[i + idx].Name)); }) ) ); var newAttribute = elementAccess.WithArgumentList(elementAccess.ArgumentList.WithArguments(newArguments)); var newRoot = root.ReplaceNode((SyntaxNode)elementAccess, newAttribute).WithAdditionalAnnotations(Formatter.Annotation); return Task.FromResult(document.WithSyntaxRoot(newRoot)); } )); }
public FlatOperand Resolve(ElementAccessExpressionSyntax node, TypeInfo result_type, FlatOperand into_lvalue, List<FlatStatement> instructions) { /* // Summary: // BracketedArgumentListSyntax node representing the list of arguments of the // element access expression. public BracketedArgumentListSyntax ArgumentList { get; } // // Summary: // ExpressionSyntax node representing the expression which is accessing the // element. public ExpressionSyntax Expression { get; } */ // resolve to an Array or Table //SymbolInfo si = Model.GetSymbolInfo(node.Expression); TypeInfo ti = Model.GetTypeInfo(node.Expression); switch (ti.ConvertedType.TypeKind) { case TypeKind.ArrayType: { FlatOperand fop_array = ResolveExpression(node.Expression, null, instructions); // resolve the array index List<FlatOperand> args = ResolveArguments(node.ArgumentList, instructions); FlatOperand key = ArrayIndexFrom(args, instructions); if (into_lvalue == null) { FlatOperand register_fop = AllocateRegister(""); into_lvalue = register_fop.GetLValue(this, instructions); } instructions.Add(FlatStatement.ARRAYGET(into_lvalue, fop_array, key)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } break; case TypeKind.Class: { // resolve method and perform method call.. // resolve the array index if (ti.ConvertedType.GetFullyQualifiedName() == "LavishScript2.Table") { FlatOperand fop_table = ResolveExpression(node.Expression, null, instructions); /* List<FlatOperand> args = ResolveArguments(node.ArgumentList, instructions); FlatOperand key = ArrayIndexFrom(args, instructions); /**/ ArgumentSyntax arg = node.ArgumentList.Arguments.Single(); FlatOperand key = ResolveArgument(arg,null,instructions); if (into_lvalue == null) { FlatOperand register_fop = AllocateRegister(""); into_lvalue = register_fop.GetLValue(this, instructions); } instructions.Add(FlatStatement.TABLEGET(into_lvalue, fop_table, key)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } SymbolInfo si = Model.GetSymbolInfo(node); if (si.Symbol.Kind != SymbolKind.Property) { throw new NotImplementedException("element access on type " + ti.ConvertedType.GetFullyQualifiedName() + " resolves to " + si.Symbol.Kind.ToString()); } IPropertySymbol ps = (IPropertySymbol)si.Symbol; if (ps.IsStatic) { throw new NotSupportedException("static indexer?"); } IMethodSymbol ms = ps.GetMethod; if (ms == null) { throw new LS2ILMethodException(ps.Name+" indexer has no get method?"); } /* if (into_lvalue == null) { FlatOperand register_fop = AllocateRegister(""); into_lvalue = register_fop.GetLValue(this, instructions); } /**/ //instructions.Add(FlatStatement.RESOLVEMETHOD()); //Resolve(IMethodSymbol method, FlatOperand fop_type, FlatOperand into_lvalue, List<FlatStatement> instructions) FlatOperand fop_type = Resolve(si.Symbol.ContainingType, null, instructions); FlatOperand fop_method = Resolve(ms, fop_type, null, instructions); return Resolve(si,ms,node.Expression,SyntaxFactory.ArgumentList(node.ArgumentList.Arguments),result_type,into_lvalue,instructions); /* instructions.Add(FlatStatement.TABLEGET(into_lvalue, fop_array, key)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); /**/ throw new NotImplementedException("element access on type " + ti.ConvertedType.GetFullyQualifiedName()); } break; default: throw new NotImplementedException("element access on type " + ti.ConvertedType.GetFullyQualifiedName());//fop_array.ImmediateValue.ValueType.ToString()); } // resolve the index /**/ throw new NotImplementedException(); } public FlatOperand Resolve(InitializerExpressionSyntax node, TypeInfo result_type, FlatOperand into_lvalue, List<FlatStatement> instructions) { /* // Summary: // SyntaxToken representing the close brace. public SyntaxToken CloseBraceToken { get; } // // Summary: // SeparatedSyntaxList of ExpressionSyntax representing the list of expressions // in the initializer expression. public SeparatedSyntaxList<ExpressionSyntax> Expressions { get; } // // Summary: // SyntaxToken representing the open brace. public SyntaxToken OpenBraceToken { get; } */ if (node.CSharpKind() == SyntaxKind.ArrayInitializerExpression) { return ResolveExpressionsToArray(node.Expressions, null, into_lvalue, instructions); } throw new NotImplementedException(); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { this.OnNodeVisited(node); if (!this.traverseRootOnly) base.VisitElementAccessExpression(node); }
public virtual void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { DefaultVisit(node); }
private static bool IsDictionarySetItem(ElementAccessExpressionSyntax elementAccess) => (elementAccess.GetSelfOrTopParenthesizedExpression().Parent as AssignmentExpressionSyntax) ?.Left.RemoveParentheses() == elementAccess;
private ProgramState ProcessElementAccess(ProgramState programState, ElementAccessExpressionSyntax elementAccess) => elementAccess.Expression is IdentifierNameSyntax identifier &&
public override string VisitElementAccessExpression(ElementAccessExpressionSyntax node) { return(Visit(node.Expression) + Visit(node.ArgumentList)); }
ParameterHintingResult HandleElementAccessExpression(SemanticModel semanticModel, ElementAccessExpressionSyntax node, CancellationToken cancellationToken) { var within = semanticModel.GetEnclosingNamedTypeOrAssembly(node.SpanStart, cancellationToken); var targetTypeInfo = semanticModel.GetTypeInfo(node.Expression); ITypeSymbol type = targetTypeInfo.Type; if (type == null) { return(ParameterHintingResult.Empty); } var result = new ParameterHintingResult(node.SpanStart); if (type.TypeKind == TypeKind.Array) { result.AddData(factory.CreateArrayDataProvider((IArrayTypeSymbol)type)); return(result); } var addedProperties = new List <IPropertySymbol> (); for (; type != null; type = type.BaseType) { foreach (var indexer in type.GetMembers().OfType <IPropertySymbol> ().Where(p => p.IsIndexer)) { if (addedProperties.Any(added => SignatureComparer.HaveSameSignature(indexer, added, true))) { continue; } if (indexer.IsAccessibleWithin(within)) { addedProperties.Add(indexer); result.AddData(factory.CreateIndexerParameterDataProvider(indexer, node)); } } } return(result); }
public async Task <JObject> Resolve(ElementAccessExpressionSyntax elementAccess, Dictionary <string, JObject> memberAccessValues, JObject indexObject, CancellationToken token) { try { JObject rootObject = null; string elementAccessStrExpression = elementAccess.Expression.ToString(); rootObject = await Resolve(elementAccessStrExpression, token); if (rootObject == null) { rootObject = indexObject; indexObject = null; } if (rootObject != null) { string elementIdxStr; int elementIdx = 0; // x[1] or x[a] or x[a.b] if (indexObject == null) { if (elementAccess.ArgumentList != null) { foreach (var arg in elementAccess.ArgumentList.Arguments) { // e.g. x[1] if (arg.Expression is LiteralExpressionSyntax) { var argParm = arg.Expression as LiteralExpressionSyntax; elementIdxStr = argParm.ToString(); int.TryParse(elementIdxStr, out elementIdx); } // e.g. x[a] or x[a.b] if (arg.Expression is IdentifierNameSyntax) { var argParm = arg.Expression as IdentifierNameSyntax; // x[a.b] memberAccessValues.TryGetValue(argParm.Identifier.Text, out indexObject); // x[a] if (indexObject == null) { indexObject = await Resolve(argParm.Identifier.Text, token); } elementIdxStr = indexObject["value"].ToString(); int.TryParse(elementIdxStr, out elementIdx); } } } } // e.g. x[a[0]], x[a[b[1]]] etc. else { elementIdxStr = indexObject["value"].ToString(); int.TryParse(elementIdxStr, out elementIdx); } if (elementIdx >= 0) { DotnetObjectId.TryParse(rootObject?["objectId"]?.Value <string>(), out DotnetObjectId objectId); switch (objectId.Scheme) { case "array": rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(objectId.Value), token); return((JObject)rootObject["value"][elementIdx]["value"]); case "object": var typeIds = await context.SdbAgent.GetTypeIdFromObject(int.Parse(objectId.Value), true, token); int methodId = await context.SdbAgent.GetMethodIdByName(typeIds[0], "ToArray", token); var commandParamsObjWriter = new MonoBinaryWriter(); commandParamsObjWriter.WriteObj(objectId, context.SdbAgent); var toArrayRetMethod = await context.SdbAgent.InvokeMethod(commandParamsObjWriter.GetParameterBuffer(), methodId, elementAccess.Expression.ToString(), token); rootObject = await GetValueFromObject(toArrayRetMethod, token); DotnetObjectId.TryParse(rootObject?["objectId"]?.Value <string>(), out DotnetObjectId arrayObjectId); rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(arrayObjectId.Value), token); return((JObject)rootObject["value"][elementIdx]["value"]); default: throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of type '{objectId.Scheme}'"); } } } return(null); } catch (Exception ex) { var e = ex; throw new Exception($"Unable to evaluate method '{elementAccess}'"); } }
// 元素访问表达式 public virtual void VisitElementAccessExpressionSyntax(ElementAccessExpressionSyntax value) { DefaultVisit(value); }
private ArgumentSyntax GetElementAccessKey(ElementAccessExpressionSyntax elementAccess) { return(elementAccess.ArgumentList.Arguments.First()); }
public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { Visit(node.Expression); suffix = node.ArgumentList.WithoutTrivia().ToFullString() + suffix; }
/// <summary> /// Returns the accessed indexer symbol for the element access expression. /// </summary> /// <param name="elementAccess">The element access expression that the symbol is required.</param> /// <param name="context">Current context.</param> /// <returns>The symbol for the invocation call.</returns> internal static IPropertySymbol?GetAccessedIndexerSymbol(ElementAccessExpressionSyntax elementAccess, SyntaxNodeAnalysisContext context) { return(context.SemanticModel.GetSymbolInfo(elementAccess).Symbol as IPropertySymbol); }
public static void WriteIndexingExpression(HaxeWriter writer, SyntaxToken operatorToken, ExpressionSyntax subExpressionOpt, ElementAccessExpressionSyntax elementAccess) { Core.Write(writer, elementAccess.Expression); writer.Write("."); Action writeArgs = () => { foreach (var arg in elementAccess.ArgumentList.Arguments) { Core.Write(writer, arg.Expression); writer.Write(", "); } }; if (operatorToken.Kind() == SyntaxKind.EqualsToken) { var leftTypeHaxe = TypeProcessor.ConvertType(elementAccess.Expression); if (leftTypeHaxe == "haxe.io.Bytes") { writer.Write("set("); } else { writer.Write("SetValue("); } writeArgs(); Core.Write(writer, subExpressionOpt); writer.Write(")"); } else { throw new Exception("Unexpected token following an element access expression " + Utility.Descriptor(elementAccess.Parent)); } }
public ElementAccessExpressionTranslation(ElementAccessExpressionSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { ArgumentList = syntax.ArgumentList.Get <BracketedArgumentListTranslation>(this); Expression = syntax.Expression.Get <ExpressionTranslation>(this); }
private BoundExpression BindIndexerAccess(ElementAccessExpressionSyntax node, BoundExpression expr, IList<BoundExpression> arguments, IList<String> argumentNames) { Debug.Assert(node != null); Debug.Assert(expr != null); Debug.Assert(arguments != null); Debug.Assert(argumentNames != null); // UNDONE: Make sure BindUserDefinedIndexerAccess handles the case where left is "base". throw new NotImplementedException(); }
public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { IsComplex = true; base.VisitElementAccessExpression(node); }
/// <summary> /// Try getting the <see cref="IPropertySymbol"/> or <see cref="IArrayTypeSymbol"/> for the node. /// Gets the semantic model for the tree if the node is not in the tree corresponding to <paramref name="semanticModel"/>. /// </summary> /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param> /// <param name="node">The <see cref="InvocationExpressionSyntax"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="symbol">The symbol if found.</param> /// <returns>True if a symbol was found.</returns> public static bool TryGetSymbol(this SemanticModel semanticModel, ElementAccessExpressionSyntax node, CancellationToken cancellationToken, out ISymbol symbol) { symbol = GetSymbolSafe(semanticModel, node, cancellationToken); return(symbol != null); }
private Block BuildElementAccessExpression(ElementAccessExpressionSyntax expression, Block currentBlock) { return(BuildInvocationLikeExpression(expression, currentBlock, expression.Expression, expression.ArgumentList?.Arguments)); }
public static void WriteIndexingExpression(HaxeWriter writer, SyntaxToken operatorToken, ExpressionSyntax subExpressionOpt, ElementAccessExpressionSyntax elementAccess) { Core.Write(writer, elementAccess.Expression); writer.Write("."); Action writeArgs = () => { foreach (var arg in elementAccess.ArgumentList.Arguments) { Core.Write(writer, arg.Expression); writer.Write(", "); } }; if (operatorToken.Kind() == SyntaxKind.EqualsToken) { var leftTypeHaxe = TypeProcessor.ConvertType(elementAccess.Expression); if (leftTypeHaxe == "haxe.io.Bytes") { writer.Write("set("); } else { var symbol = Program.GetModel(elementAccess).GetSymbolInfo(elementAccess).Symbol.OriginalDefinition.As <IPropertySymbol>(); var types = string.Join("", symbol.Parameters.ToArray().Select(o => "_" + o.Type.Name)); writer.Write("SetValue" + types + "("); } writeArgs(); Core.Write(writer, subExpressionOpt); writer.Write(")"); } else { throw new Exception("Unexpected token following an element access expression " + Utility.Descriptor(elementAccess.Parent)); } }
public FlatOperand Resolve(ElementAccessExpressionSyntax node, TypeInfo result_type, FlatOperand into_lvalue, List<FlatStatement> instructions) { /* // Summary: // BracketedArgumentListSyntax node representing the list of arguments of the // element access expression. public BracketedArgumentListSyntax ArgumentList { get; } // // Summary: // ExpressionSyntax node representing the expression which is accessing the // element. public ExpressionSyntax Expression { get; } */ // resolve to an Array or Table //SymbolInfo si = Model.GetSymbolInfo(node.Expression); TypeInfo ti = Model.GetTypeInfo(node.Expression); FlatOperand fop_array = ResolveExpression(node.Expression, into_lvalue, instructions); switch (ti.ConvertedType.TypeKind) { case TypeKind.ArrayType: { // resolve the array index List<FlatOperand> args = ResolveArguments(node.ArgumentList, instructions); FlatOperand key = ArrayIndexFrom(args, instructions); if (into_lvalue == null) { FlatOperand register_fop = AllocateRegister(""); into_lvalue = register_fop.GetLValue(this, instructions); } instructions.Add(FlatStatement.ARRAYGET(into_lvalue, fop_array, key)); return into_lvalue.AsRValue(FlatValue.FromType(result_type.ConvertedType)); } break; default: throw new NotImplementedException("element access on type " + fop_array.ImmediateValue.ValueType.ToString()); } // resolve the index /**/ throw new NotImplementedException(); } public FlatOperand Resolve(CastExpressionSyntax node, TypeInfo result_type, FlatOperand into_lvalue, List<FlatStatement> instructions) { /* // Summary: // SyntaxToken representing the close parenthesis. public SyntaxToken CloseParenToken { get; } // // Summary: // ExpressionSyntax node representing the expression that is being casted. public ExpressionSyntax Expression { get; } // // Summary: // SyntaxToken representing the open parenthesis. public SyntaxToken OpenParenToken { get; } // // Summary: // TypeSyntax node representing the type the expression is being casted to. public TypeSyntax Type { get; } /**/ return ResolveExpression(node.Expression, into_lvalue, instructions); throw new NotImplementedException("type-cast expression"); }
public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { LogUnsupportedSyntax(node); }
public static void Go(OutputWriter writer, ElementAccessExpressionSyntax expression) { var type = TypeProcessor.GetTypeInfo(expression.Expression).Type; var typeStr = TypeProcessor.GenericTypeName(type); var additionalParam = ""; var symbol = TypeProcessor.GetSymbolInfo(expression); //This could be null if (symbol.Symbol != null) { var methodSymbol = symbol.Symbol as IPropertySymbol; //Lets find out if this is an interface implementation if (methodSymbol != null) { IEnumerable <ISymbol> interfaceMethods = methodSymbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(methodSymbol.Name)); interfaceMethods = interfaceMethods.Where( o => Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(o), methodSymbol)); if (interfaceMethods.Any()) { //Lets get the best match var interfaceMethod = interfaceMethods.FirstOrDefault(); additionalParam = "cast(" + TypeProcessor.ConvertType(interfaceMethod.ContainingType) + ")null"; } } } //type.GetMembers("this[]") //Todo if we are using unsafe / fast mode, just use array->Data()[i] should bypass bounds check and indirection also should be as fast as pure c++ arrays //though fixed syntax could fix this too ?? // writer.Write("(*"); Core.Write(writer, expression.Expression); if (type.SpecialType == SpecialType.System_Array) { // writer.Write(")"); writer.Write(".Items["); //TODO test this thoroughly } else { writer.Write("["); //TODO test this thoroughly } var first = true; foreach (var argument in expression.ArgumentList.Arguments) { if (first) { first = false; } else { writer.Write(", "); } Core.Write(writer, argument.Expression); } if (additionalParam != "") { writer.Write("," + additionalParam); } writer.Write("]"); }
public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { this.VisitExpression(node); }
private void BuildElementAccessExpression(ElementAccessExpressionSyntax expression) { BuildInvocationLikeExpression(expression, expression.Expression, expression.ArgumentList?.Arguments); }
public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { Emit <ElementAccessExpressionBlock, ElementAccessExpressionSyntax>(node); }
public static Doc Print(ElementAccessExpressionSyntax node) { return(Doc.Concat(Node.Print(node.Expression), Node.Print(node.ArgumentList))); }
private ProgramState ProcessElementAccess(ProgramState programState, ElementAccessExpressionSyntax elementAccess) { var identifier = elementAccess.Expression as IdentifierNameSyntax; return ProcessAccessExpression(identifier, elementAccess, programState); }
private IEnumerable<ITypeSymbol> InferTypeInElementAccessExpression( ElementAccessExpressionSyntax elementAccess, int index, ArgumentSyntax argumentOpt = null) { var info = this.semanticModel.GetTypeInfo(elementAccess.Expression, cancellationToken); var type = info.Type as INamedTypeSymbol; if (type != null) { var indexers = type.GetMembers().OfType<IPropertySymbol>() .Where(p => p.IsIndexer && p.Parameters.Length > index); if (indexers.Any()) { return indexers.SelectMany(i => InferTypeInArgument(index, SpecializedCollections.SingletonEnumerable(i.Parameters), argumentOpt)); } } // For everything else, assume it's an integer. Note: this won't be correct for // type parameters that implement some interface, but that seems like a major // corner case for now. // // This does, however, cover the more common cases of // arrays/pointers/errors/dynamic. return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Int32)); }
ParameterHintingResult HandleElementAccessExpression(SemanticModel semanticModel, ElementAccessExpressionSyntax node, CancellationToken cancellationToken) { var within = semanticModel.GetEnclosingNamedTypeOrAssembly(node.SpanStart, cancellationToken); var targetTypeInfo = semanticModel.GetTypeInfo (node.Expression); ITypeSymbol type = targetTypeInfo.Type; if (type == null) return ParameterHintingResult.Empty; var result = new ParameterHintingResult(node.SpanStart); if (type.TypeKind == TypeKind.Array) { result.AddData (factory.CreateArrayDataProvider ((IArrayTypeSymbol)type)); return result; } var addedProperties = new List<IPropertySymbol> (); for (;type != null; type = type.BaseType) { foreach (var indexer in type.GetMembers ().OfType<IPropertySymbol> ().Where (p => p.IsIndexer)) { if (addedProperties.Any (added => SignatureComparer.HaveSameSignature (indexer, added, true))) continue; if (indexer.IsAccessibleWithin (within)) { addedProperties.Add (indexer); result.AddData (factory.CreateIndexerParameterDataProvider (indexer, node)); } } } return result; }
public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { base.VisitElementAccessExpression(node); }
internal static bool IsArgumentListToken(ElementAccessExpressionSyntax expression, SyntaxToken token) { return expression.ArgumentList.Span.Contains(token.SpanStart) && token != expression.ArgumentList.CloseBracketToken; }
public ElementAccessExpressionTranslation(ElementAccessExpressionSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { ArgumentList = syntax.ArgumentList.Get<BracketedArgumentListTranslation>(this); Expression = syntax.Expression.Get<ExpressionTranslation>(this); }
public override void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { var oper = m_Model.GetOperation(node); var symInfo = m_Model.GetSymbolInfo(node); var sym = symInfo.Symbol; var psym = sym as IPropertySymbol; if (null != sym && sym.IsStatic) { var ci = m_ClassInfoStack.Peek(); AddReferenceAndTryDeriveGenericTypeInstance(ci, sym); } if (null != psym && psym.IsIndexer) { CodeBuilder.AppendFormat("get{0}{1}indexer(", psym.ContainingAssembly == m_SymbolTable.AssemblySymbol ? string.Empty : "extern", psym.IsStatic ? "static" : "instance"); if (psym.IsStatic) { string fullName = ClassInfo.GetFullName(psym.ContainingType); CodeBuilder.Append(fullName); } else { VisitExpressionSyntax(node.Expression); } CodeBuilder.Append(", "); if (!psym.IsStatic) { string fnOfIntf = "nil"; CheckExplicitInterfaceAccess(psym.GetMethod, ref fnOfIntf); CodeBuilder.AppendFormat("{0}, ", fnOfIntf); } string manglingName = NameMangling(psym.GetMethod); CodeBuilder.AppendFormat("\"{0}\", ", manglingName); InvocationInfo ii = new InvocationInfo(); ii.Init(psym.GetMethod, node.ArgumentList, m_Model); OutputArgumentList(ii.Args, ii.DefaultValueArgs, ii.GenericTypeArgs, ii.ArrayToParams, false, node); CodeBuilder.Append(")"); } else if (oper.Kind == OperationKind.ArrayElementReferenceExpression) { VisitExpressionSyntax(node.Expression); CodeBuilder.Append("["); VisitBracketedArgumentList(node.ArgumentList); CodeBuilder.Append("]"); } else if (null != sym) { CodeBuilder.AppendFormat("get{0}{1}element(", sym.ContainingAssembly == m_SymbolTable.AssemblySymbol ? string.Empty : "extern", sym.IsStatic ? "static" : "instance"); if (sym.IsStatic) { string fullName = ClassInfo.GetFullName(sym.ContainingType); CodeBuilder.Append(fullName); } else { VisitExpressionSyntax(node.Expression); } CodeBuilder.Append(", "); CodeBuilder.AppendFormat("\"{0}\", ", sym.Name); VisitBracketedArgumentList(node.ArgumentList); CodeBuilder.Append(")"); } else { ReportIllegalSymbol(node, symInfo); } }
public void VisitElementAccessExpression(ElementAccessExpressionSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); ExpressionStart(node); node.Expression.Accept(this); node.ArgumentList.Accept(this); ExpressionEnd(node); }
public static ElementAccessExpressionSyntax WithArgumentList(this ElementAccessExpressionSyntax indexer, params ArgumentSyntax[] arguments) => WithArgumentList(indexer, (IEnumerable <ArgumentSyntax>)arguments);
public static void ReportUndeclaredIndexer(this ICollection<Diagnostic> diagnostics, ElementAccessExpressionSyntax node, TypeSymbol declaringType, IEnumerable<TypeSymbol> argumentTypes) { var declaringTypeName = declaringType.ToDisplayName(); var argumentTypeNames = string.Join(@", ", argumentTypes.Select(t => t.ToDisplayName())); diagnostics.Report(node.GetTextSpanRoot(), DiagnosticId.UndeclaredIndexer, declaringTypeName, argumentTypeNames); }
private static bool IsDictionarySetItem(ElementAccessExpressionSyntax elementAccess) => (elementAccess.GetFirstNonParenthesizedParent() as AssignmentExpressionSyntax) ?.Left.RemoveParentheses() == elementAccess;
private bool TryGenerateArrayElementAccess(ElementAccessExpressionSyntax elementAccessExpression) { using (ArrayElementAccessTag()) { if (!TryGenerateExpression(elementAccessExpression.Expression)) { return false; } foreach (var argument in elementAccessExpression.ArgumentList.Arguments) { if (!TryGenerateExpression(argument.Expression)) { return false; } } } return true; }
protected override void CompileElementAccessExpression(ElementAccessExpressionSyntax expression) { var argument = expression.ArgumentList.Arguments[0]; var symbol = GetSymbol(argument); var type = GetType(symbol); //if (expression.ToFullString().Contains("Far")) Console.Write("!"); if (type != null && type.Name == "vec2") { Write("tex2D("); CompileExpression(expression.Expression); Write(Comma); CompileExpression(argument.Expression); Write(")"); } else if (type != null && type.Name == "RelativeIndex") { // Without .5,.5 shift Write("tex2D("); CompileExpression(expression.Expression); Write(Comma); Write("psin.TexCoords{0}+{0}(", Space); CompileExpression(argument.Expression); Write("){0}*{0}", Space); CompileExpression(expression.Expression); Write("_{0})", Sampler.DxDySuffix); // With .5,.5 shift. This may be needed on some architectures due to rounding/interpolation issues. //Write("tex2D("); //CompileExpression(expression.Expression); //Write(Comma); //Write("psin.TexCoords{0}+{0}(float2(.5,.5){0}+{0}(", Space); //CompileExpression(argument.Expression); //Write(")){0}*{0}", Space); ////CompileExpression(expression.Expression); ////Write("_d)", Space); //Write("float2(1.0 / 1024.0, 1.0 / 1024.0))"); } else { //Write("tex2D("); //CompileExpression(expression.Expression); //Write(Comma); //Write("float2(2,1) * float2(1,1)/16.0)"); // Assume form [i, j] Write("tex2D("); CompileExpression(expression.Expression); Write(Comma); Write("float2(", Space); var arg1 = expression.ArgumentList.Arguments[0]; CompileExpression(arg1.Expression); Write("+.5,.5+" + Space); var arg2 = expression.ArgumentList.Arguments[1]; CompileExpression(arg2.Expression); //Write(") * float2(1,1)/16.0)"); Write("){0}*{0}", Space); CompileExpression(expression.Expression); Write("_{0})", Sampler.DxDySuffix); } }
private ExpressionSyntax ParsePostFixExpression(ExpressionSyntax expr) { Debug.Assert(expr != null); while (true) { var tk = Current.Kind; switch (tk) { case SyntaxKind.OpenParenToken: expr = new InvocationExpressionSyntax(expr, ParseParenthesizedArgumentList(false)); break; case SyntaxKind.OpenBracketToken: expr = new ElementAccessExpressionSyntax(expr, Match(SyntaxKind.OpenBracketToken), ParseExpression(), Match(SyntaxKind.CloseBracketToken)); break; case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: expr = new PostfixUnaryExpressionSyntax(SyntaxFacts.GetPostfixUnaryExpression(tk), expr, NextToken()); break; case SyntaxKind.DotToken: expr = new MemberAccessExpressionSyntax(expr, NextToken(), ParseIdentifier()); break; default: return expr; } } }
public static void ReportUndeclaredIndexer(this ICollection <Diagnostic> diagnostics, ElementAccessExpressionSyntax node, TypeSymbol declaringType, IEnumerable <TypeSymbol> argumentTypes) { var declaringTypeName = declaringType.ToDisplayName(); var argumentTypeNames = string.Join(@", ", argumentTypes.Select(t => t.ToDisplayName())); diagnostics.Report(node.SourceRange, DiagnosticId.UndeclaredIndexer, declaringTypeName, argumentTypeNames); }