Func <Expression, bool> GetChecker(Expression expression, IList <IdentifierExpression> identifiers) { // TODO: This only works for simple cases. IList <IMember> members; IList <IVariable> locals; var identifierResolveResults = identifiers.Select(identifier => context.Resolve(identifier)).ToList(); SplitResolveResults(identifierResolveResults, out members, out locals); if (expression is InvocationExpression || expression is ObjectCreateExpression) { return(node => { if (node is InvocationExpression || node is ObjectCreateExpression) { // We don't know what these might do, so assume it will change the initializer return true; } var binaryOperator = node as BinaryOperatorExpression; if (binaryOperator != null) { var resolveResult = context.Resolve(binaryOperator) as OperatorResolveResult; if (resolveResult == null) { return false; } // Built-in operators are ok, user defined ones not so much return resolveResult.UserDefinedOperatorMethod != null; } return IsConflictingAssignment(node, identifiers, members, locals); }); } else if (expression is IdentifierExpression) { var initializerDependsOnMembers = identifierResolveResults.Any(result => result is MemberResolveResult); var initializerDependsOnReferenceType = identifierResolveResults.Any(result => result.Type.IsReferenceType == true); return(node => { if ((node is InvocationExpression || node is ObjectCreateExpression) && (initializerDependsOnMembers || initializerDependsOnReferenceType)) { // Anything can happen... return true; } var binaryOperator = node as BinaryOperatorExpression; if (binaryOperator != null) { var resolveResult = context.Resolve(binaryOperator) as OperatorResolveResult; if (resolveResult == null) { return false; } return resolveResult.UserDefinedOperatorMethod != null; } return IsConflictingAssignment(node, identifiers, members, locals); }); } return(node => false); }
void HandlePotentialWrite(Expression expression) { var variableResolveResult = ctx.Resolve(expression) as LocalResolveResult; if (variableResolveResult == null) { return; } variableWritten |= variableResolveResult.Equals(parameter); }
bool IsSafeExpression(Expression expression, BaseSemanticModel context) { var components = expression.DescendantsAndSelf; foreach (var c in components) { if (c is AssignmentExpression) { return(false); } else if (c is UnaryOperatorExpression) { var ope = ((UnaryOperatorExpression)c).Operator; if (ope == UnaryOperatorType.Decrement || ope == UnaryOperatorType.Increment || ope == UnaryOperatorType.PostDecrement || ope == UnaryOperatorType.PostIncrement) { return(false); } } else if (c is IdentifierExpression) { var result = context.Resolve(c); if (result.IsError) { return(false); } if (!(result is LocalResolveResult)) { return(false); } if ((((LocalResolveResult)result).IsParameter)) { return(false); } } } return(true); }
static IType GetReturnType(BaseSemanticModel context, AstNode currentFunction) { var resolveResult = context.Resolve(currentFunction); return(resolveResult.IsError ? null : resolveResult.Type); }