public FieldAccessExpression(IFieldSymbol fieldSymbol, SyntaxNode node, UcfgExpression target) : base(fieldSymbol, node, target) { var fieldAccess = new FieldAccess { Field = new Variable { Name = fieldSymbol.Name } }; switch (Target) { case ThisExpression thisExpression: fieldAccess.This = Target.Expression.This; break; case VariableExpression variableExpression: fieldAccess.Object = Target.Expression.Var; break; case ClassNameExpression classNameExpression: fieldAccess.Classname = Target.Expression.Classname; break; default: throw new UcfgException("Expecting target object to be 'This', 'Variable' or 'ClassName' but " + $"got '{Target}'. " + $"Node: {node} " + $"File: {node.GetLocation()?.GetLineSpan().Path ?? "{unknown}"} " + $"Line: {node.GetLocation()?.GetLineSpan().StartLinePosition}"); } Expression = new Expression { FieldAccess = fieldAccess }; }
public UcfgExpression Create(SyntaxNode node, ISymbol symbol, UcfgExpression targetExpression) { switch (symbol) { case null: return(UcfgExpression.Unknown); case IParameterSymbol parameterSymbol: return(parameterSymbol.Type.IsAny(UnsupportedVariableTypes) ? (UcfgExpression) new UcfgExpression.ConstantExpression(parameterSymbol) : new UcfgExpression.VariableExpression(parameterSymbol, node)); case ILocalSymbol localSymbol: return(new UcfgExpression.VariableExpression(symbol, node)); case IFieldSymbol fieldSymbol: return(new UcfgExpression.FieldAccessExpression(fieldSymbol, node, targetExpression)); case IPropertySymbol propertySymbol: return(new UcfgExpression.PropertyAccessExpression(propertySymbol, node, targetExpression)); case INamedTypeSymbol namedTypeSymbol: return(CreateClassName(namedTypeSymbol)); case IMethodSymbol methodSymbol: return(new UcfgExpression.MethodAccessExpression(methodSymbol, node, targetExpression)); default: throw new UcfgException($"Create UcfgExpression does not expect symbol of type '{symbol.GetType().Name}'."); } }
private IEnumerable <Instruction> ProcessInvocationExpression(InvocationExpressionSyntax invocationSyntax) { var methodSymbol = GetSymbol <IMethodSymbol>(invocationSyntax); if (methodSymbol == null) { expressionService.Associate(invocationSyntax, expressionService.CreateConstant()); return(NoInstructions); } var invocationExpression = expressionService.GetExpression(invocationSyntax.Expression); var methodExpression = invocationExpression as UcfgExpression.MethodAccessExpression; if (methodExpression == null) { expressionService.Associate(invocationSyntax, expressionService.CreateConstant(invocationExpression.TypeSymbol)); return(NoInstructions); } UcfgExpression targetExpression; UcfgExpression memberAccessArgument = null; if (IsCalledAsExtension(methodSymbol)) { if (invocationSyntax.Expression is MemberAccessExpressionSyntax memberAccessExpression) { // First argument is the class name (static method call) targetExpression = expressionService.CreateClassName(methodSymbol.ContainingType); // Second argument is the left side of the invocation memberAccessArgument = expressionService.GetExpression(memberAccessExpression.Expression); } else { throw new UcfgException("Unexpected state, method called as extension of a member but there is no " + "member access available."); } } else { targetExpression = methodExpression.Target; } var additionalArguments = new List <UcfgExpression>(); if (memberAccessArgument != null) { additionalArguments.Add(memberAccessArgument); } additionalArguments.AddRange(GetAdditionalArguments(invocationSyntax.ArgumentList)); return(CreateMethodCall(invocationSyntax, methodSymbol, targetExpression, additionalArguments.ToArray())); }
private IEnumerable <Instruction> CreateFunctionCall(string methodIdentifier, SyntaxNode syntaxNode, UcfgExpression assignedTo, params UcfgExpression[] arguments) { if (syntaxNode is ObjectCreationExpressionSyntax) { throw new UcfgException("Expecting this method not to be called for nodes of type 'ObjectCreationExpressionSyntax'."); } if (arguments.Length == 0 && methodIdentifier != UcfgBuiltInMethodId.EntryPoint) { throw new UcfgException($"Every UCFG expression except {UcfgBuiltInMethodId.EntryPoint} must have at least " + "one argument. " + $"Identifier: {methodIdentifier}, " + $"File: {syntaxNode.GetLocation()?.GetLineSpan().Path ?? "{unknown}" } " + $"Line: {syntaxNode.GetLocation()?.GetLineSpan().StartLinePosition}"); } expressionService.Associate(syntaxNode, assignedTo); var instruction = new Instruction { Assigncall = new AssignCall { Location = syntaxNode.GetUcfgLocation(), MethodId = methodIdentifier } }; IList <Instruction> newInstructions = new List <Instruction>(); if (methodIdentifier == UcfgBuiltInMethodId.Identity) { instruction.Assigncall.Args.AddRange(arguments.Select(a => a.Expression)); } else { var processedArgs = ProcessInstructionArguments(arguments, newInstructions); instruction.Assigncall.Args.AddRange(processedArgs); } assignedTo.ApplyAsTarget(instruction); newInstructions.Add(instruction); return(newInstructions); }
private IEnumerable <Instruction> CreateNewObject(ObjectCreationExpressionSyntax syntaxNode, IMethodSymbol ctorSymbol, UcfgExpression callTarget) { expressionService.Associate(syntaxNode, callTarget); var instruction = new Instruction { NewObject = new NewObject { Location = syntaxNode.GetUcfgLocation(), Type = expressionService.CreateClassName(ctorSymbol.ContainingType).Expression.Classname.Classname } }; callTarget.ApplyAsTarget(instruction); return(new[] { instruction }); }
private IEnumerable <Instruction> ProcessGenericName(GenericNameSyntax genericName) { var namedTypeSymbol = GetSymbol <INamedTypeSymbol>(genericName); UcfgExpression target = null; if (namedTypeSymbol != null) { target = namedTypeSymbol.IsStatic ? expressionService.CreateClassName(namedTypeSymbol) : UcfgExpression.This; } var ucfgExpression = expressionService.Create(genericName, namedTypeSymbol, target); expressionService.Associate(genericName, ucfgExpression); return(NoInstructions); }
public ElementAccessExpression(ISymbol symbol, UcfgExpression target) : base(symbol, null, target) { }
private static bool IsTemporaryVariableRequired(UcfgExpression methodArgumentExpression) { return(methodArgumentExpression is UcfgExpression.FieldAccessExpression); }
public IEnumerable <Instruction> CreateArraySetCall(SyntaxNode syntaxNode, ITypeSymbol nodeTypeSymbol, UcfgExpression target, UcfgExpression value) { return(CreateFunctionCall(UcfgBuiltInMethodId.ArraySet, syntaxNode, expressionService.CreateVariable(nodeTypeSymbol), target, value)); }
private IEnumerable <Instruction> CreateMethodCall(SyntaxNode syntaxNode, IMethodSymbol methodSymbol, UcfgExpression target, params UcfgExpression[] additionalArguments) { if (target is UcfgExpression.ConstantExpression) { expressionService.Associate(syntaxNode, target); return(NoInstructions); } return(CreateFunctionCall(methodSymbol.ToUcfgMethodId(), syntaxNode, expressionService.CreateVariable(methodSymbol.ReturnType), new[] { target }.Concat(additionalArguments).ToArray())); }
public IEnumerable <Instruction> CreateIdCall(SyntaxNode syntaxNode, UcfgExpression to, UcfgExpression value) { return(CreateFunctionCall(UcfgBuiltInMethodId.Identity, syntaxNode, to, value)); }
public IEnumerable <Instruction> CreateAnnotationCall(SyntaxNode syntaxNode, UcfgExpression.VariableExpression to, UcfgExpression value) { return(CreateFunctionCall(UcfgBuiltInMethodId.Annotation, syntaxNode, to, value)); }
public IEnumerable <Instruction> CreateConcatCall(SyntaxNode syntaxNode, ITypeSymbol nodeTypeSymbol, UcfgExpression left, UcfgExpression right) { return(CreateFunctionCall(UcfgBuiltInMethodId.Concatenation, syntaxNode, expressionService.CreateVariable(nodeTypeSymbol), left, right)); }
public PropertyAccessExpression(IPropertySymbol propertySymbol, SyntaxNode node, UcfgExpression target) : base(propertySymbol, node, target) { GetMethodSymbol = propertySymbol.GetMethod; SetMethodSymbol = propertySymbol.SetMethod; }
public MethodAccessExpression(IMethodSymbol methodSymbol, SyntaxNode node, UcfgExpression target) : base(methodSymbol, node, target) { }
public void Associate(SyntaxNode syntaxNode, UcfgExpression expression) => cache[syntaxNode.RemoveParentheses()] = expression;
public UcfgExpression CreateArrayAccess(ISymbol symbol, UcfgExpression targetExpression) => new UcfgExpression.ElementAccessExpression(symbol, targetExpression);
private IEnumerable <Instruction> CreateNewArray(ArrayCreationExpressionSyntax syntaxNode, IArrayTypeSymbol arrayTypeSymbol, UcfgExpression callTarget) { expressionService.Associate(syntaxNode, callTarget); var instruction = new Instruction { NewObject = new NewObject { Location = syntaxNode.GetUcfgLocation(), Type = arrayTypeSymbol.ToDisplayString() } }; callTarget.ApplyAsTarget(instruction); return(new[] { instruction }); }
public MemberAccessExpression(ISymbol symbol, SyntaxNode node, UcfgExpression target) : base(symbol, node) { Target = target; }