private static bool IsParenthesizedExprActuallyCastToNodePath(SemanticModel semanticModel, SyntaxNode currentNode) { // (NodePath)$$ which is detected as a parenthesized expression rather than a cast if (!(currentNode is ParenthesizedExpressionSyntax parenthesizedExpression)) { return(false); } if (!(parenthesizedExpression.Expression is IdentifierNameSyntax identifierNameSyntax)) { return(false); } var typeInfo = semanticModel.GetTypeInfo(identifierNameSyntax).Type; return(typeInfo != null && RoslynUtils.TypeIsNodePath(typeInfo)); }
private static bool IsPathConstructorArgumentOfNodePath(SyntaxNode syntaxRoot, SemanticModel semanticModel, SyntaxNode currentNode, int position) { // new NodePath($$) for NodePath(string) ctor if (!(currentNode is ArgumentListSyntax argumentList && currentNode.Parent is ObjectCreationExpressionSyntax objectCreation)) { return(false); } var previousToken = syntaxRoot.FindToken(position - 1); if (previousToken != argumentList.OpenParenToken) { return(false); } if (argumentList.Arguments.Count > 1) { return(false); // The NodePath constructor we are looking for has only one parameter } int index = RoslynUtils.GetArgumentListIndex(argumentList, previousToken); var info = semanticModel.GetSymbolInfo(objectCreation.Type); if (!(info.Symbol is INamedTypeSymbol type)) { return(false); } if (type.TypeKind == TypeKind.Delegate) { return(false); } if (!RoslynUtils.TypeIsNodePath(type)) { return(false); } var constructors = type.InstanceConstructors.Where(m => m.Parameters.Length == 1); var types = RoslynUtils.InferTypeInArgument(index, constructors.Select(m => m.Parameters), argumentOpt: null); return(types.Any(RoslynUtils.TypeIsString)); }