public SingleTypeOrValueTuple Build(string?mockMemberName = null) { mockMemberName ??= string.Empty; int count = Items.Count; SingleTypeOrValueTuple.Entry[] entries = new SingleTypeOrValueTuple.Entry[Items.Count]; if (count > 0) { if (count > 1) { var uniquifier = new Uniquifier(new[] { mockMemberName }); for (int i = 0; i < count; i++) { var item = Items[i]; string name = item.OriginalName; name = name == mockMemberName ? name + "_" : name; if (IsNameValidForPosition(name, i)) { entries[i] = new SingleTypeOrValueTuple.Entry( item.OriginalName, item.Type, item.IsReturnValue, uniquifier.GetUniqueName(name)); } } for (int i = 0; i < count; i++) { var item = Items[i]; string name = item.OriginalName; name = name == mockMemberName ? name + "_" : name; if (!IsNameValidForPosition(name, i)) { entries[i] = new SingleTypeOrValueTuple.Entry( item.OriginalName, item.Type, item.IsReturnValue, uniquifier.GetUniqueName(name + "_")); } } } else { var item = Items[0]; string name = item.OriginalName; name = name == mockMemberName ? name + "_" : name; entries[0] = new SingleTypeOrValueTuple.Entry(item.OriginalName, item.Type, item.IsReturnValue, name); } } return(new SingleTypeOrValueTuple(entries)); }
private static string?FindArglistParameterName(IMethodSymbol symbol) { if (symbol.IsVararg) { var uniquifier = new Uniquifier(symbol.Parameters.Select(a => a.Name)); return(uniquifier.GetUniqueName("arglist")); } return(null); }
private MemberDeclarationSyntax MockSetVirtualMethod() { var uniquifier = new Uniquifier(Symbol.Parameters.Select(p => p.Name)); var parameterList = F.SeparatedList(Symbol.Parameters.Select(a => F.Parameter(F.Identifier(a.Name)).WithType(TypesForSymbols.ParseTypeName(a.Type, a.NullableOrOblivious())))) .Add(F.Parameter(F.Identifier(uniquifier.GetUniqueName("value"))).WithType(ValueTypeSyntax)); return(F.MethodDeclaration(F.PredefinedType(F.Token(SyntaxKind.VoidKeyword)), F.Identifier(MemberMockName)) .WithModifiers(F.TokenList(F.Token(SyntaxKind.ProtectedKeyword), F.Token(SyntaxKind.VirtualKeyword))) .WithParameterList(F.ParameterList(parameterList)) .WithBody(F.Block(ThrowMockMissingStatement("VirtualIndexerSet")))); }
private MocklisTypesForSymbols(SemanticModel semanticModel, ClassDeclarationSyntax classDeclaration, MocklisSymbols mocklisSymbols, INamedTypeSymbol classSymbol, IMethodSymbol methodSymbol, bool nullableContextEnabled) { _semanticModel = semanticModel; _classDeclaration = classDeclaration; _mocklisSymbols = mocklisSymbols; _typeParameterNameSubstitutions = new Dictionary <string, string>(); _nullableContextEnabled = nullableContextEnabled; Uniquifier t = new Uniquifier(classSymbol.TypeParameters.Select(tp => tp.Name)); foreach (var methodTypeParameter in methodSymbol.TypeParameters) { string uniqueName = t.GetUniqueName(methodTypeParameter.Name); _typeParameterNameSubstitutions[methodTypeParameter.Name] = uniqueName; } }
protected MemberDeclarationSyntax ExplicitInterfaceMember() { var baseReturnType = Symbol.ReturnsVoid ? F.PredefinedType(F.Token(SyntaxKind.VoidKeyword)) : TypesForSymbols.ParseTypeName(Symbol.ReturnType, Symbol.ReturnTypeIsNullableOrOblivious()); var returnType = baseReturnType; if (Symbol.ReturnsByRef) { returnType = F.RefType(returnType); } else if (Symbol.ReturnsByRefReadonly) { returnType = F.RefType(returnType).WithReadOnlyKeyword(F.Token(SyntaxKind.ReadOnlyKeyword)); } var mockedMethod = ExplicitInterfaceMemberMethodDeclaration(returnType); var memberMockInstance = ExplicitInterfaceMemberMemberMockInstance(); ExpressionSyntax invocation = F.InvocationExpression( F.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, memberMockInstance, F.IdentifierName("Call"))) .WithExpressionsAsArgumentList(ParametersType.BuildArgumentListWithOriginalNames()); // look at the return parameters. If we don't have any we can just make the call. // if we only have one and that's the return value, we can just return it. if (ReturnValuesType.Count == 0 || ReturnValuesType.Count == 1 && ReturnValuesType[0].IsReturnValue) { if (Symbol.ReturnsByRef || Symbol.ReturnsByRefReadonly) { invocation = TypesForSymbols.WrapByRef(invocation, baseReturnType); } mockedMethod = mockedMethod.WithExpressionBody(F.ArrowExpressionClause(invocation)) .WithSemicolonToken(F.Token(SyntaxKind.SemicolonToken)); } // if we only have one and that's not a return value, we can just assign it to the out or ref parameter it corresponds to. else if (ReturnValuesType.Count == 1) { mockedMethod = mockedMethod.WithBody(F.Block(F.ExpressionStatement(F.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, F.IdentifierName(ReturnValuesType[0].OriginalName), invocation)))); } else { // if we have more than one, put it in a temporary variable. (consider name clashes with method parameter names) var x = new Uniquifier(Symbol.Parameters.Select(m => m.Name)); string tmp = x.GetUniqueName("tmp"); var statements = new List <StatementSyntax> { F.LocalDeclarationStatement(F.VariableDeclaration(F.IdentifierName("var")).WithVariables( F.SingletonSeparatedList(F.VariableDeclarator(F.Identifier(tmp)).WithInitializer(F.EqualsValueClause(invocation))))) }; // then for any out or ref parameters, set their values from the temporary variable. foreach (var rv in ReturnValuesType.Where(a => !a.IsReturnValue)) { statements.Add(F.ExpressionStatement(F.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, F.IdentifierName(rv.OriginalName), F.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, F.IdentifierName(tmp), F.IdentifierName(rv.TupleSafeName))))); } // finally, if there is a 'proper' return type, return the corresponding value from the temporary variable. foreach (var rv in ReturnValuesType.Where(a => a.IsReturnValue)) { ExpressionSyntax memberAccess = F.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, F.IdentifierName(tmp), F.IdentifierName(rv.TupleSafeName)); if (Symbol.ReturnsByRef || Symbol.ReturnsByRefReadonly) { memberAccess = TypesForSymbols.WrapByRef(memberAccess, baseReturnType); } statements.Add(F.ReturnStatement(memberAccess)); } mockedMethod = mockedMethod.WithBody(F.Block(statements)); } return(mockedMethod); }