// Todo: Refactor using something smarter than string match. In the future use Roslyn private static bool ExpressionContainsExecuteInvocations(InvocationExpressionSyntax invocation) { var invocationString = invocation.ToFullString(); return(invocationString.Contains("ExecuteAsync()", StringComparison.InvariantCultureIgnoreCase) || invocationString.Contains("Execute()", StringComparison.InvariantCultureIgnoreCase)); }
public override Microsoft.CodeAnalysis.SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) { var expression = node.Expression; InvocationExpressionSyntax newNode = node; if (_targetPatternRegEx.Match(node.Expression.ToString()).Success) { // We are looking for Invocations like this // // <something>.Execute{NonQuery,Reader,Scalar}([CommandBehavior.CloseConnection]) // // e.g. // dbCMD.ExecuteReader(CommandBehavior.CloseConnection) // objCMD.ExecuteNonQuery(CommandBehavior.CloseConnection) var simpleMemberAccessExpression = node.ChildNodes().First(); var firstIdentifier = simpleMemberAccessExpression.ChildNodes().First(); var lastIdentifer = simpleMemberAccessExpression.ChildNodes().Last(); var argumentList = node.ArgumentList.Arguments.ToString(); List <SyntaxTrivia> newTrivia = new List <SyntaxTrivia>(); string existingLeadingTrivia = node.GetLeadingTrivia().ToString(); string existingLeadingTriviaFull = node.GetLeadingTrivia().ToFullString(); string existingTrailingTrivia = node.GetTrailingTrivia().ToString(); string existingTrailingTriviaFull = node.GetTrailingTrivia().ToFullString(); if (VNCCA.Helpers.VB.IsOnLineByItself(node)) { string startOfLineWhiteSpace = existingLeadingTrivia.Replace(System.Environment.NewLine, ""); newTrivia.Add(SyntaxFactory.CommentTrivia(existingLeadingTriviaFull)); var newExpression = SyntaxFactory.ParseExpression(string.Format("DAL.Helpers.{0}({1}{2})", lastIdentifer, firstIdentifier, argumentList.Length > 0 ? ", " + argumentList : "")); newNode = (InvocationExpressionSyntax)newExpression.WithTriviaFrom(node); RecordReplacementAndContext(node, node.ToString(), newNode.ToString()); } else { Messages.AppendLine(String.Format("node: >{0}< >{1}< Is NOT OnLineByItself()", node.ToString(), node.ToFullString())); newNode = node; } } else { newNode = node; } return(base.VisitInvocationExpression(newNode)); }
public override void VisitInvocationExpression(InvocationExpressionSyntax node) { if (node.ToFullString().Contains("RandomInUnitSphere")) { } if (node.Expression is IdentifierNameSyntax ins) { SymbolInfo symbolInfo = _discoverer.Compilation.GetSemanticModel(node.SyntaxTree).GetSymbolInfo(ins); ISymbol symbol = symbolInfo.Symbol; if (symbol == null && symbolInfo.CandidateSymbols.Length == 1) { symbol = symbolInfo.CandidateSymbols[0]; } if (symbol == null) { throw new ShaderGenerationException($"A member reference could not be identified: {node.Expression}"); } string containingType = symbol.ContainingType.ToDisplayString(); string methodName = symbol.Name; _children.Add(new TypeAndMethodName() { TypeName = containingType, MethodName = methodName }); } else if (node.Expression is MemberAccessExpressionSyntax maes) { SymbolInfo methodSymbol = _discoverer.Compilation.GetSemanticModel(maes.SyntaxTree).GetSymbolInfo(maes); ISymbol symbol = methodSymbol.Symbol; if (symbol == null && methodSymbol.CandidateSymbols.Length == 1) { symbol = methodSymbol.CandidateSymbols[0]; } if (symbol == null) { throw new ShaderGenerationException($"A member reference could not be identified: {node.Expression}"); } if (symbol is IMethodSymbol ims) { string containingType = Utilities.GetFullMetadataName(ims.ContainingType); string methodName = ims.MetadataName; _children.Add(new TypeAndMethodName() { TypeName = containingType, MethodName = methodName }); } } else { throw new NotImplementedException(); } base.VisitInvocationExpression(node); }
static SyntaxNode Nop = SyntaxFactory.ParseExpression(""); // I'm sure there's something smarter than this... public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) { string text = node.ToFullString().Trim(); if (text.StartsWith("this.OnPropertyChang")) // bit of a hack... { return(Nop); } return(base.VisitInvocationExpression(node)); }
// Todo: Refactor using something smarter than string match. In the future use Roslyn private static bool ExpressionContainsExecuteInvocations(InvocationExpressionSyntax invocation) { var invocationString = invocation.ToFullString(); if (invocationString.Contains("ExecuteAsync()") || invocationString.Contains("Execute()")) { return(true); } return(false); }
public override string VisitInvocationExpression(InvocationExpressionSyntax node) { if (node.Expression is IdentifierNameSyntax ins) { InvocationParameterInfo[] parameterInfos = GetParameterInfos(node.ArgumentList); SymbolInfo symbolInfo = GetModel(node).GetSymbolInfo(ins); string type = symbolInfo.Symbol.ContainingType.ToDisplayString(); string method = symbolInfo.Symbol.Name; return(_backend.FormatInvocation(_setName, type, method, parameterInfos)); } else if (node.Expression is MemberAccessExpressionSyntax maes) { SymbolInfo methodSymbol = GetModel(maes).GetSymbolInfo(maes); if (methodSymbol.Symbol is IMethodSymbol ims) { string containingType = Utilities.GetFullMetadataName(ims.ContainingType); string methodName = ims.MetadataName; List <InvocationParameterInfo> pis = new List <InvocationParameterInfo>(); if (ims.IsExtensionMethod) { string identifier = null; // Extension method invocation, ie: swizzle: if (maes.Expression is MemberAccessExpressionSyntax subExpression) { identifier = Visit(subExpression); } else if (maes.Expression is IdentifierNameSyntax identNameSyntax) { identifier = Visit(identNameSyntax); } Debug.Assert(identifier != null); // Might need FullTypeName here too. pis.Add(new InvocationParameterInfo() { Identifier = identifier }); } pis.AddRange(GetParameterInfos(node.ArgumentList)); return(_backend.FormatInvocation(_setName, containingType, methodName, pis.ToArray())); } throw new NotImplementedException(); } else { string message = "Function calls must be made through an IdentifierNameSyntax or a MemberAccessExpressionSyntax."; message += Environment.NewLine + "This node used a " + node.Expression.GetType().Name; message += Environment.NewLine + node.ToFullString(); throw new NotImplementedException(message); } }
// TODO: well, we probably have the same info later on, with MemberAccessExpression etc. public override void VisitInvocationExpression(InvocationExpressionSyntax node) { var expr = node.Expression; // var argList = node.ArgumentList; var nl = OurLine.NewLine(LineKind.Decl, "InvocationExpression"); OurLine.AddEssentialInfo(ref nl, "expression:" + expr.ToString()); nl.Source = node.ToFullString(); nl.ParentKind = node.Parent.RawKind; nl.RawKind = node.RawKind; LogCommand(nl); base.VisitInvocationExpression(node); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); Diagnostic diagnostic = context.Diagnostics.First(); TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; // Order of iterating the list matters, which is why we use arrays InvocationExpressionSyntax[] declarationList = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType <InvocationExpressionSyntax>().ToArray(); if (declarationList.Length == 0) { return; } string methodStr = "Slice("; string propertyStr = ".Span."; string skipAlreadyFixed = propertyStr + methodStr; // Find the invocation expression identified by the diagnostic. InvocationExpressionSyntax declaration = null; for (int i = 0; i < declarationList.Length; i++) { InvocationExpressionSyntax decl = declarationList[i]; string str = decl.ToFullString(); int index = str.LastIndexOf(methodStr); if (index != -1 && (index < propertyStr.Length || !str.Substring(index - propertyStr.Length).StartsWith(skipAlreadyFixed))) { declaration = decl; break; } } Debug.Assert(declaration != null); // Register a code action that will invoke the fix. context.RegisterCodeFix( CodeAction.Create( title: title, createChangedDocument: c => SwapMethodCalls(context.Document, declaration, c), equivalenceKey: title), diagnostic); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); Diagnostic diagnostic = context.Diagnostics.First(); TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; // Order of iterating the list matters, which is why we use arrays InvocationExpressionSyntax[] declarationList = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType <InvocationExpressionSyntax>().ToArray(); if (declarationList.Length == 0) { return; } // Find the invocation expression identified by the diagnostic. InvocationExpressionSyntax declaration = null; for (int i = 0; i < declarationList.Length; i++) { InvocationExpressionSyntax decl = declarationList[i]; if (decl.ToFullString().Contains("AsSpan()")) { declaration = decl; break; } } Debug.Assert(declaration != null); // Register a code action that will invoke the fix. context.RegisterCodeFix( CodeAction.Create( title: title, createChangedDocument: c => CollapseMethodCalls(context.Document, declaration, c), equivalenceKey: title), diagnostic); }
/// <summary> /// Warn user if fluent command chain not ending with Execute or ExecuteAsync /// </summary> /// <param name="syntaxTree">The parsed syntax tree</param> /// <param name="compilation">Compilated code</param> private static void WarnIfExecuteIsMissing(SyntaxTree syntaxTree, CSharpCompilation compilation, ILogger logger) { var semModel = compilation.GetSemanticModel(syntaxTree); var invocationExpressions = syntaxTree.GetRoot().DescendantNodes().OfType <InvocationExpressionSyntax>(); var linesReported = new List <int>(); foreach (var invocationExpression in invocationExpressions) { var symbol = (IMethodSymbol?)semModel?.GetSymbolInfo(invocationExpression).Symbol; if (symbol is null) { continue; } if (string.IsNullOrEmpty(symbol?.Name) || ExecuteWarningOnInvocationNames.Contains(symbol?.Name) == false) { // The invocation name is empty or not in list of invocations // that needs to be closed with Execute or ExecuteAsync continue; } // Now find top invocation to match whole expression InvocationExpressionSyntax topInvocationExpression = invocationExpression; if (symbol is not null && symbol.ContainingType.Name == "NetDaemonApp") { var disableLogging = false; var symbolName = symbol.Name; SyntaxNode?parentInvocationExpression = invocationExpression.Parent; while (parentInvocationExpression is not null) { if (parentInvocationExpression is MethodDeclarationSyntax) { if (ExpressionContainsDisableLogging((MethodDeclarationSyntax)parentInvocationExpression)) { disableLogging = true; } } if (parentInvocationExpression is InvocationExpressionSyntax) { var parentSymbol = (IMethodSymbol?)semModel?.GetSymbolInfo(invocationExpression).Symbol; if (parentSymbol?.Name == symbolName) { topInvocationExpression = (InvocationExpressionSyntax)parentInvocationExpression; } } parentInvocationExpression = parentInvocationExpression.Parent; } // Now when we have the top InvocationExpression, // lets check for Execute and ExecuteAsync if (ExpressionContainsExecuteInvocations(topInvocationExpression) == false && disableLogging == false) { var x = syntaxTree.GetLineSpan(topInvocationExpression.Span); if (linesReported.Contains(x.StartLinePosition.Line) == false) { logger.LogError($"Missing Execute or ExecuteAsync in {syntaxTree.FilePath} ({x.StartLinePosition.Line + 1},{x.StartLinePosition.Character + 1}) near {topInvocationExpression.ToFullString().Trim()}"); linesReported.Add(x.StartLinePosition.Line); } } } } }
public override Microsoft.CodeAnalysis.SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) { //Microsoft.CodeAnalysis.SyntaxNode newInvocation = null; var expression = node.Expression; InvocationExpressionSyntax newInvocationExpression = null; if (expression.ToString() == _pattern) { try { List <SyntaxTrivia> newTrivia = new List <SyntaxTrivia>(); string existingLeadingTrivia = node.GetLeadingTrivia().ToString(); string existingLeadingTriviaFull = node.GetLeadingTrivia().ToFullString(); string existingTrailingTrivia = node.GetTrailingTrivia().ToString(); string existingTrailingTriviaFull = node.GetTrailingTrivia().ToFullString(); // Verify this expression is on line by itself if (VNCCA.Helpers.VB.IsOnLineByItself(node)) { // HACK(crhodes) // Figure out how to get Helpers to work here. Messages.AppendLine(String.Format("Commenting out {0} Method:({1,-35}) {2}", VNCCA.Helpers.VB.GetContainingContext(node, _configurationOptions), VNCCA.Helpers.VB.GetContainingMethodName(node), node.ToString())); string startOfLineWhiteSpace = existingLeadingTrivia.Replace(System.Environment.NewLine, ""); newTrivia.Add(SyntaxFactory.CommentTrivia(existingLeadingTriviaFull)); newTrivia.Add(SyntaxFactory.CommentTrivia(VNCCA.Helpers.VB.MultiLineComment(_comment, startOfLineWhiteSpace))); newTrivia.Add(SyntaxFactory.CommentTrivia("' ")); newInvocationExpression = node.WithLeadingTrivia(newTrivia); } else { Messages.AppendLine(String.Format("node: >{0}< >{1}< Is NOT OnLineByItself", node.ToString(), node.ToFullString())); newInvocationExpression = node; } } catch (Exception ex) { Messages.AppendLine(string.Format("Ex:{0} InnerEx:{1}", ex.ToString(), ex.InnerException.ToString())); } } else { newInvocationExpression = node; } return(newInvocationExpression); }
public static void Go(OutputWriter writer, InvocationExpressionSyntax invocationExpression) { var symbolInfo = TypeProcessor.GetSymbolInfo(invocationExpression); var expressionSymbol = TypeProcessor.GetSymbolInfo(invocationExpression.Expression); var symbol = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.FirstOrDefault(); // Resolution error if (symbol == null) { writer.WriteLine("/*" + invocationExpression.ToFullString() + " //SharpNative Failed To Get Symbol */"); } var methodSymbol = symbol.OriginalDefinition.As <IMethodSymbol>().UnReduce(); var memberReferenceExpressionOpt = invocationExpression.Expression as MemberAccessExpressionSyntax; var firstParameter = true; var extensionNamespace = methodSymbol.IsExtensionMethod ? methodSymbol.ContainingNamespace.FullNameWithDot() + methodSymbol.ContainingType.FullName() : null; //null means it's not an extension method, non-null means it is string methodName; string typeParameters = null; ExpressionSyntax subExpressionOpt; if (expressionSymbol.Symbol is IEventSymbol) { methodName = "Invoke"; } else if (methodSymbol.MethodKind == MethodKind.DelegateInvoke) { methodName = null; } else { methodName = OverloadResolver.MethodName(methodSymbol); } if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface || Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol)) { /* methodName = * Regex.Replace(TypeProcessor.ConvertType(methodSymbol.ContainingType.OriginalDefinition) * .RemoveFromStartOfString(methodSymbol.ContainingNamespace + ".Namespace.") + "_" + * methodName, * @" ?!\(.*?\)", string.Empty);*/ if (methodSymbol.ContainingType.ContainingType != null) { methodName = methodName.RemoveFromStartOfString(methodSymbol.ContainingType.ContainingType.Name + "."); } } var interfaceMethods = methodSymbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(methodName)).ToArray(); ISymbol interfaceMethod = interfaceMethods.FirstOrDefault( o => methodSymbol.ContainingType.FindImplementationForInterfaceMember(o) == methodSymbol); // if (interfaceMethod == null) // { // //TODO: fix this for virtual method test 7, seems roslyn cannot deal with virtual // // overrides of interface methods ... so i'll provide a kludge // if (!method.Modifiers.Any(SyntaxKind.NewKeyword)) // interfaceMethod = interfaceMethods.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, methodSymbol)); // } if (interfaceMethod != null) // && CompareMethods(interfaceMethod ,methodSymbol)) { { //This is an interface method //TO if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array) { writer.Write(""); } else { /* var typenameI = * Regex.Replace( * TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true), * @" ?!\(.*?\)", string.Empty); * //TODO: we should be able to get the original interface name, or just remove all generics from this * if (typenameI.Contains('.')) * typenameI = typenameI.SubstringAfterLast('.'); * writer.Write(typenameI + "_");*/ } } var containingType = interfaceMethod == null ? methodSymbol.ContainingType : interfaceMethod.ContainingType; bool isVirtualGeneric = methodSymbol.IsGenericMethod && (methodSymbol.IsVirtual || methodSymbol.ContainingType.TypeKind == TypeKind.Interface) && !containingType.IsAssignableFrom(Context.Instance.Type); // !(invocationExpression.Expression is BaseExpressionSyntax); if (isVirtualGeneric) { methodName = TypeProcessor.ConvertType(containingType, false, false, false).Replace(".", "_") + "_" + methodName; } if (methodSymbol.MethodKind == MethodKind.DelegateInvoke) { subExpressionOpt = invocationExpression.Expression; } else if (memberReferenceExpressionOpt != null) { if (memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax) { subExpressionOpt = null; } else { subExpressionOpt = memberReferenceExpressionOpt.Expression; } } else { subExpressionOpt = null; } //When the code specifically names generic arguments, include them in the method name ... dmd needs help with inference, so we give it the types anyway if (methodSymbol.IsGenericMethod) { //return TryConvertType(named) + (named.TypeKind == TypeKind.Struct && o.ConstraintTypes.Any(k => k.TypeKind == //TypeKind.Interface) ? ".__Boxed_" : ""); var named = ((IMethodSymbol)symbol); typeParameters = "!(" + named.TypeArguments.Select(o => TypeProcessor.GetGenericParameterType(named.TypeParameters[named.TypeArguments.IndexOf(o)], o)).Aggregate((a, b) => a + ", " + b) + ")"; // typeParameters = "!( " + // string.Join(", ", // ((IMethodSymbol) symbol).TypeArguments.Select(r => TypeProcessor.ConvertType(r) )) + // " )"; } //Determine if it's an extension method called in a non-extension way. In this case, just pretend it's not an extension method if (extensionNamespace != null && subExpressionOpt != null && TypeProcessor.GetTypeInfo(subExpressionOpt).ConvertedType.ToString() == methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.FullName()) { extensionNamespace = null; } var memberType = memberReferenceExpressionOpt == null ? null : TypeProcessor.GetTypeInfo(memberReferenceExpressionOpt.Expression).Type; var isNullableEnum = memberType != null && (memberType.Name == "Nullable" && memberType.ContainingNamespace.FullName() == "System") && memberType.As <INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum; // if (isNullableEnum && methodSymbol.Name == "ToString") // { // extensionNamespace = null; //override Translations.xml for nullable enums. We want them to convert to the enum's ToString method // methodName = "toString"; // } //Invocation on basics should come from boxing the basic then calling on the boxed type, unless static var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType() && methodSymbol.IsStatic; //&& methodSymbol.ContainingType!=Context.Instance.Type; //If we are currently working on a basic type e.g. in corlib, don't alter the code //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification string instanceName = null; if (extensionNamespace != null || directInvocationOnBasics) { if (extensionNamespace == null) { extensionNamespace = TypeProcessor.ConvertType(methodSymbol.ContainingType, true, false); // methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.Name; //memberType.ContainingNamespace.FullName() +"."+ memberType.Name; } if (!isVirtualGeneric) { writer.Write(extensionNamespace); if (methodName != null) { methodName = WriteIdentifierName.TransformIdentifier(methodName); // if (symbolInfo.Symbol.ContainingType != Context.Instance.Type) writer.Write("."); writer.Write(methodName); } } else { writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); if (subExpressionOpt != null) { firstParameter = false; Core.Write(writer, subExpressionOpt); } } else { if (memberReferenceExpressionOpt != null) { } if (subExpressionOpt != null) { if (!isVirtualGeneric) { WriteMemberAccessExpression.WriteMember(writer, subExpressionOpt); // if (!(subExpressionOpt is BaseExpressionSyntax)) // { // if (methodName != null && methodSymbol.IsStatic) // writer.Write("."); // else // { if (methodSymbol.MethodKind != MethodKind.DelegateInvoke) { writer.Write("."); } } else { instanceName = WriteMemberAccessExpression.WriteMemberToString(subExpressionOpt); } // } // } // writer.Write("."); } else if (methodSymbol.IsStatic && extensionNamespace == null) { if (methodSymbol.ContainingType != Context.Instance.Type) { var str = TypeProcessor.ConvertType(methodSymbol.ContainingType); if (str == "Array_T") { // Array is the only special case, otherwise generics have to be specialized to access static members str = "Array"; } writer.Write(str); // writer.Write(methodSymbol.ContainingNamespace.FullNameWithDot()); // writer.Write(WriteType.TypeName(methodSymbol.ContainingType)); writer.Write("."); } } if (methodSymbol.MethodKind != MethodKind.DelegateInvoke) { var declaringSyntaxReferences = methodSymbol.DeclaringSyntaxReferences.Select(j => j.GetSyntax()) .OfType <MethodDeclarationSyntax>(); var methodDeclarationSyntaxs = declaringSyntaxReferences as MethodDeclarationSyntax[] ?? declaringSyntaxReferences.ToArray(); var any = methodDeclarationSyntaxs.Any(); if (any && methodDeclarationSyntaxs.FirstOrDefault() .As <MethodDeclarationSyntax>() .Modifiers.Any(SyntaxKind.NewKeyword)) { //TODO: this means that new is not supported on external libraries // //why doesnt roslyn give me this information ? //methodName += "_"; //Not needed anymore :) } if (any && methodDeclarationSyntaxs.FirstOrDefault() .As <MethodDeclarationSyntax>() .Modifiers.Any(SyntaxKind.NewKeyword)) { // if (symbolInfo.Symbol.ContainingType != Context.Instance.Type) writer.Write(WriteIdentifierName.TransformIdentifier(methodSymbol.ContainingType.Name, methodSymbol.ContainingType) + "."); } methodName = WriteIdentifierName.TransformIdentifier(methodName); writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); } bool inParams = false; bool foundParamsArray = false; var arguments = invocationExpression.ArgumentList.Arguments; ITypeSymbol typeSymbol = null; bool isOverloaded = methodSymbol.ContainingType.GetMembers(methodSymbol.Name).OfType <IMethodSymbol>().Any(j => j.TypeParameters == methodSymbol.TypeParameters && ParameterMatchesWithRefOutIn(methodSymbol, j)); WriteArguments(writer, invocationExpression, arguments, firstParameter, inParams, methodSymbol, foundParamsArray, typeSymbol, isOverloaded, symbol, instanceName); }
private static string For(InvocationExpressionSyntax invocation) { invocation = invocation.WithoutLeadingTrivia(); return($"{invocation.ToFullString()}".Trim()); }
public static void Go(OutputWriter writer, InvocationExpressionSyntax invocationExpression) { var symbolInfo = TypeProcessor.GetSymbolInfo(invocationExpression); var expressionSymbol = TypeProcessor.GetSymbolInfo(invocationExpression.Expression); var symbol = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.FirstOrDefault(); // Resolution error if (symbol == null) { writer.WriteLine("/*" + invocationExpression.ToFullString() +" //SharpNative Failed To Get Symbol */"); } var methodSymbol = symbol.OriginalDefinition.As<IMethodSymbol>().UnReduce(); var memberReferenceExpressionOpt = invocationExpression.Expression as MemberAccessExpressionSyntax; var firstParameter = true; var extensionNamespace = methodSymbol.IsExtensionMethod ? methodSymbol.ContainingNamespace.FullNameWithDot() + methodSymbol.ContainingType.FullName() : null; //null means it's not an extension method, non-null means it is string methodName; string typeParameters = null; ExpressionSyntax subExpressionOpt; if (expressionSymbol.Symbol is IEventSymbol) { methodName = "Invoke"; } else if (methodSymbol.MethodKind == MethodKind.DelegateInvoke) methodName = null; else methodName = OverloadResolver.MethodName(methodSymbol); if (methodSymbol.ContainingType.TypeKind == TypeKind.Interface || Equals(methodSymbol.ContainingType.FindImplementationForInterfaceMember(methodSymbol), methodSymbol)) { /* methodName = Regex.Replace(TypeProcessor.ConvertType(methodSymbol.ContainingType.OriginalDefinition) .RemoveFromStartOfString(methodSymbol.ContainingNamespace + ".Namespace.") + "_" + methodName, @" ?!\(.*?\)", string.Empty);*/ if (methodSymbol.ContainingType.ContainingType != null) methodName = methodName.RemoveFromStartOfString(methodSymbol.ContainingType.ContainingType.Name + "."); } var interfaceMethods = methodSymbol.ContainingType.AllInterfaces.SelectMany( u => u.GetMembers(methodName)).ToArray(); ISymbol interfaceMethod = interfaceMethods.FirstOrDefault( o => methodSymbol.ContainingType.FindImplementationForInterfaceMember(o) == methodSymbol); // if (interfaceMethod == null) // { // //TODO: fix this for virtual method test 7, seems roslyn cannot deal with virtual // // overrides of interface methods ... so i'll provide a kludge // if (!method.Modifiers.Any(SyntaxKind.NewKeyword)) // interfaceMethod = interfaceMethods.FirstOrDefault(k => CompareMethods(k as IMethodSymbol, methodSymbol)); // } if (interfaceMethod != null) // && CompareMethods(interfaceMethod ,methodSymbol)) { { //This is an interface method //TO if (methodSymbol.ContainingType.SpecialType == SpecialType.System_Array) writer.Write(""); else { /* var typenameI = Regex.Replace( TypeProcessor.ConvertType(interfaceMethod.ContainingType.ConstructedFrom, true), @" ?!\(.*?\)", string.Empty); //TODO: we should be able to get the original interface name, or just remove all generics from this if (typenameI.Contains('.')) typenameI = typenameI.SubstringAfterLast('.'); writer.Write(typenameI + "_");*/ } } var containingType = interfaceMethod == null ? methodSymbol.ContainingType : interfaceMethod.ContainingType; bool isVirtualGeneric = methodSymbol.IsGenericMethod && (methodSymbol.IsVirtual || methodSymbol.ContainingType.TypeKind == TypeKind.Interface) && !containingType.IsAssignableFrom(Context.Instance.Type);// !(invocationExpression.Expression is BaseExpressionSyntax); if (isVirtualGeneric) methodName = TypeProcessor.ConvertType(containingType,false,false,false).Replace(".", "_") + "_" + methodName; if (methodSymbol.MethodKind == MethodKind.DelegateInvoke) subExpressionOpt = invocationExpression.Expression; else if (memberReferenceExpressionOpt != null) { if (memberReferenceExpressionOpt.Expression is PredefinedTypeSyntax) subExpressionOpt = null; else subExpressionOpt = memberReferenceExpressionOpt.Expression; } else subExpressionOpt = null; //When the code specifically names generic arguments, include them in the method name ... dmd needs help with inference, so we give it the types anyway if (methodSymbol.IsGenericMethod) { //return TryConvertType(named) + (named.TypeKind == TypeKind.Struct && o.ConstraintTypes.Any(k => k.TypeKind == //TypeKind.Interface) ? ".__Boxed_" : ""); var named = ((IMethodSymbol)symbol); typeParameters = "!(" + named.TypeArguments.Select(o => TypeProcessor.GetGenericParameterType(named.TypeParameters[named.TypeArguments.IndexOf(o)], o)).Aggregate((a, b) => a + ", " + b) + ")"; // typeParameters = "!( " + // string.Join(", ", // ((IMethodSymbol) symbol).TypeArguments.Select(r => TypeProcessor.ConvertType(r) )) + // " )"; } //Determine if it's an extension method called in a non-extension way. In this case, just pretend it's not an extension method if (extensionNamespace != null && subExpressionOpt != null && TypeProcessor.GetTypeInfo(subExpressionOpt).ConvertedType.ToString() == methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.FullName()) extensionNamespace = null; var memberType = memberReferenceExpressionOpt == null ? null : TypeProcessor.GetTypeInfo(memberReferenceExpressionOpt.Expression).Type; var isNullableEnum = memberType != null && (memberType.Name == "Nullable" && memberType.ContainingNamespace.FullName() == "System") && memberType.As<INamedTypeSymbol>().TypeArguments.Single().TypeKind == TypeKind.Enum; // if (isNullableEnum && methodSymbol.Name == "ToString") // { // extensionNamespace = null; //override Translations.xml for nullable enums. We want them to convert to the enum's ToString method // methodName = "toString"; // } //Invocation on basics should come from boxing the basic then calling on the boxed type, unless static var directInvocationOnBasics = methodSymbol.ContainingType.IsBasicType() && methodSymbol.IsStatic; //&& methodSymbol.ContainingType!=Context.Instance.Type; //If we are currently working on a basic type e.g. in corlib, don't alter the code //Extension methods in Dlang are straightforward, although this could lead to clashes without qualification string instanceName =null; if (extensionNamespace != null || directInvocationOnBasics) { if (extensionNamespace == null) { extensionNamespace = TypeProcessor.ConvertType(methodSymbol.ContainingType, true, false); // methodSymbol.ContainingNamespace.FullName() + "." + methodSymbol.ContainingType.Name; //memberType.ContainingNamespace.FullName() +"."+ memberType.Name; } if (!isVirtualGeneric) { writer.Write(extensionNamespace); if (methodName != null) { methodName = WriteIdentifierName.TransformIdentifier(methodName); // if (symbolInfo.Symbol.ContainingType != Context.Instance.Type) writer.Write("."); writer.Write(methodName); } } else { writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); if (subExpressionOpt != null) { firstParameter = false; Core.Write(writer, subExpressionOpt); } } else { if (memberReferenceExpressionOpt != null) { } if (subExpressionOpt != null) { if (!isVirtualGeneric) { WriteMemberAccessExpression.WriteMember(writer, subExpressionOpt); // if (!(subExpressionOpt is BaseExpressionSyntax)) // { // if (methodName != null && methodSymbol.IsStatic) // writer.Write("."); // else // { if (methodSymbol.MethodKind != MethodKind.DelegateInvoke) writer.Write("."); } else { instanceName = WriteMemberAccessExpression.WriteMemberToString(subExpressionOpt); } // } // } // writer.Write("."); } else if (methodSymbol.IsStatic && extensionNamespace == null) { if (methodSymbol.ContainingType != Context.Instance.Type) { var str = TypeProcessor.ConvertType(methodSymbol.ContainingType); if (str == "Array_T") // Array is the only special case, otherwise generics have to be specialized to access static members str = "Array"; writer.Write(str); // writer.Write(methodSymbol.ContainingNamespace.FullNameWithDot()); // writer.Write(WriteType.TypeName(methodSymbol.ContainingType)); writer.Write("."); } } if (methodSymbol.MethodKind != MethodKind.DelegateInvoke) { var declaringSyntaxReferences = methodSymbol.DeclaringSyntaxReferences.Select(j => j.GetSyntax()) .OfType<MethodDeclarationSyntax>(); var methodDeclarationSyntaxs = declaringSyntaxReferences as MethodDeclarationSyntax[] ?? declaringSyntaxReferences.ToArray(); var any = methodDeclarationSyntaxs.Any(); if (any && methodDeclarationSyntaxs.FirstOrDefault() .As<MethodDeclarationSyntax>() .Modifiers.Any(SyntaxKind.NewKeyword)) { //TODO: this means that new is not supported on external libraries // //why doesnt roslyn give me this information ? //methodName += "_"; //Not needed anymore :) } if (any && methodDeclarationSyntaxs.FirstOrDefault() .As<MethodDeclarationSyntax>() .Modifiers.Any(SyntaxKind.NewKeyword)) { // if (symbolInfo.Symbol.ContainingType != Context.Instance.Type) writer.Write(WriteIdentifierName.TransformIdentifier(methodSymbol.ContainingType.Name,methodSymbol.ContainingType) + "."); } methodName = WriteIdentifierName.TransformIdentifier(methodName); writer.Write(methodName); } WriteTypeParameters(writer, typeParameters, invocationExpression); writer.Write("("); } bool inParams = false; bool foundParamsArray = false; var arguments = invocationExpression.ArgumentList.Arguments; ITypeSymbol typeSymbol = null; bool isOverloaded = methodSymbol.ContainingType.GetMembers(methodSymbol.Name).OfType<IMethodSymbol>().Any(j => j.TypeParameters == methodSymbol.TypeParameters && ParameterMatchesWithRefOutIn(methodSymbol, j)); WriteArguments(writer, invocationExpression, arguments, firstParameter, inParams, methodSymbol, foundParamsArray, typeSymbol, isOverloaded, symbol,instanceName); }
public override Microsoft.CodeAnalysis.SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) { var expression = node.Expression; InvocationExpressionSyntax newInvocationExpression = node; // We are looking for Invocations like this // // <something>.Fill(<argument list>) // // e.g. // objDA.Fill(objDS, strTableName) // objDataAdaptor.Fill(objDataTable) if (_targetPatternRegEx.Match(node.Expression.ToString()).Success) { var simpleMemberAccessExpression = node.ChildNodes().First(); var firstIdentifier = simpleMemberAccessExpression.ChildNodes().First(); var lastIdentifer = simpleMemberAccessExpression.ChildNodes().Last(); var argumentList = node.ArgumentList.Arguments.ToString(); List <SyntaxTrivia> newTrivia = new List <SyntaxTrivia>(); string existingLeadingTrivia = node.GetLeadingTrivia().ToString(); string existingLeadingTriviaFull = node.GetLeadingTrivia().ToFullString(); string existingTrailingTrivia = node.GetTrailingTrivia().ToString(); string existingTrailingTriviaFull = node.GetTrailingTrivia().ToFullString(); if (VNCCA.Helpers.VB.IsOnLineByItself(node)) { string startOfLineWhiteSpace = existingLeadingTrivia.Replace(System.Environment.NewLine, ""); newTrivia.Add(SyntaxFactory.CommentTrivia(existingLeadingTriviaFull)); // TODO(crhodes) // NB. lastIdentifier should always be Fill. May want to put a check in. var newExpression = SyntaxFactory.ParseExpression(string.Format("DAL.Helpers.{0}({1}{2})", lastIdentifer, firstIdentifier, argumentList.Length > 0 ? ", " + argumentList : "")); newInvocationExpression = (InvocationExpressionSyntax)newExpression.WithTriviaFrom(node); RecordReplacementAndContext(node, node.ToString(), newInvocationExpression.ToString()); } else { Messages.AppendLine(String.Format("node: >{0}< >{1}< Is NOT OnLineByItself()", node.ToString(), node.ToFullString())); newInvocationExpression = node; } } else { newInvocationExpression = node; } return(base.VisitInvocationExpression(newInvocationExpression)); }
//public WrapSQLCallsInDebug2(string TargetInvocationExpression, string NewInvocationExpression) //{ // _targetInvocationExpression = TargetInvocationExpression; // _newInvocationExpression = NewInvocationExpression; //} public override Microsoft.CodeAnalysis.SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node) { if (TargetPattern == null) { return(node); } //Microsoft.CodeAnalysis.SyntaxNode newInvocation = null; var expression = node.Expression; //InvocationExpressionSyntax newInvocationExpression = null; InvocationExpressionSyntax newInvocationExpression = node; //var newExpression = SyntaxFactory.IdentifierName(_newInvocationExpression); // Decide if want to use RegEx here. if (expression.ToString() == TargetPattern) { var location = node.GetLocation(); var startLine = location.GetLineSpan().StartLinePosition.Line; var endLine = location.GetLineSpan().EndLinePosition.Line; var simpleMemberAccessExpression = node.ChildNodes().First(); var firstIdentifier = simpleMemberAccessExpression.ChildNodes().First(); var lastIdentifer = simpleMemberAccessExpression.ChildNodes().Last(); //Dim dbTicks as Long = Log.Debug2("Execution Start", LOG_CATEGORY) //dbReader = dbCmd.ExecuteReader() //Log.Trace(String.Format("Execution End: strSQL:{({0})", strSQL), LOG_CATEGORY, dbTicks) //LocalDeclarationStatementSyntax declareVariable = GetDeclareString("myString"); LocalDeclarationStatementSyntax logStart = GetLogStartSyntax(); InvocationExpressionSyntax logEnd = GetLogEndSyntax(); List <Microsoft.CodeAnalysis.SyntaxNode> newBeforeNodes = new List <Microsoft.CodeAnalysis.SyntaxNode>(); newBeforeNodes.Add(logStart); List <Microsoft.CodeAnalysis.SyntaxNode> newAfterNodes = new List <Microsoft.CodeAnalysis.SyntaxNode>(); newAfterNodes.Add(logEnd); List <SyntaxTrivia> newTrivia = new List <SyntaxTrivia>(); string existingLeadingTrivia = node.GetLeadingTrivia().ToString(); string existingLeadingTriviaFull = node.GetLeadingTrivia().ToFullString(); string existingTrailingTrivia = node.GetTrailingTrivia().ToString(); string existingTrailingTriviaFull = node.GetTrailingTrivia().ToFullString(); // Verify this expression is on line by itself if (VNCCA.Helpers.VB.IsOnLineByItself(node)) { string startOfLineWhiteSpace = existingLeadingTrivia.Replace(System.Environment.NewLine, ""); newTrivia.Add(SyntaxFactory.CommentTrivia(existingLeadingTriviaFull)); //newTrivia.Add(SyntaxFactory.CommentTrivia(VNCCA.Helpers.VB.MultiLineComment(_comment, startOfLineWhiteSpace))); //newTrivia.Add(SyntaxFactory.CommentTrivia("' ")); var newExpression = SyntaxFactory.ParseExpression(string.Format("DAL.Helpers.{0}({1})", lastIdentifer, firstIdentifier)); newInvocationExpression = (InvocationExpressionSyntax)newExpression.WithTriviaFrom(node); //newInvocationExpression = node.WithLeadingTrivia(newTrivia); } else { Messages.AppendLine(String.Format("node: >{0}< >{1}< Is NOT OnLineByItself", node.ToString(), node.ToFullString())); newInvocationExpression = node; } //try //{ // var root = node.SyntaxTree.GetRoot(); // var nodeParent = node.Parent; // var nodeParentParent = nodeParent.Parent; // var newSomething = root.InsertNodesAfter(node, newAfterNodes); //} //catch (Exception ex) //{ //} //try //{ // //var newSomething2 = node.InsertNodesAfter() //} //catch (Exception ex) //{ //} //newInvocationExpression = node.WithExpression(newExpression); //newInvocationExpression = node.InsertNodesBefore(node, newBeforeNodes); //try //{ // //newInvocationExpression = node.InsertNodesAfter(node.Parent, newAfterNodes); // node.R // newInvocationExpression = node.WithExpression(logEnd); //} //catch (Exception ex) //{ //} //try //{ // newBeforeNodes.Add(node); // newBeforeNodes.Add(logEnd); // newInvocationExpression = node.ReplaceNode(node.Parent, newBeforeNodes); // //newInvocationExpression = node.InsertNodesAfter(node, newAfterNodes); //} //catch (Exception ex) //{ //} //newInvocationExpression = newInvocationExpression.InsertNodesAfter(node, newAfterNodes); RecordMatchAndContext(node, node.ToString()); //Messages.AppendLine(string.Format("Found: >{0}<\n>{1}<\nLocation: >{2}< \nstart:({3}) end:({4})", // expression.ToString(), // node.ToFullString(), // location.ToString(), // startLine, endLine)); //PerformedReplacement = true; } else { newInvocationExpression = node; } return(base.VisitInvocationExpression(newInvocationExpression)); }