public static InvocationExpressionSyntax CreateInvocationExpression(ExpressionSyntax sourceExpression, SimpleNameSyntax methodName, ArgumentListSyntax argumentList) => SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, sourceExpression, methodName), argumentList);
protected override BoundExpression BindRangeVariable(SimpleNameSyntax node, RangeVariableSymbol qv, DiagnosticBag diagnostics) { Debug.Assert(!qv.IsTransparent); BoundExpression translation; ImmutableArray<string> path; if (_rangeVariableMap.TryGetValue(qv, out path)) { if (path.IsEmpty) { // the range variable maps directly to a use of the parameter of that name var value = base.parameterMap[qv.Name]; Debug.Assert(value.Count == 1); translation = new BoundParameter(node, value.Single()) { WasCompilerGenerated = true }; } else { // if the query variable map for this variable is non empty, we always start with the current // lambda's first parameter, which is a transparent identifier. Debug.Assert(base.lambdaSymbol.Parameters[0].Name.StartsWith(transparentIdentifierPrefix)); translation = new BoundParameter(node, base.lambdaSymbol.Parameters[0]) { WasCompilerGenerated = true }; for (int i = path.Length - 1; i >= 0; i--) { var nextField = path[i]; translation = SelectField(node, translation, nextField, diagnostics); translation.WasCompilerGenerated = true; } } return new BoundRangeVariable(node, qv, translation, translation.Type); } return base.BindRangeVariable(node, qv, diagnostics); }
private BoundExpression SelectField(SimpleNameSyntax node, BoundExpression receiver, string name, DiagnosticBag diagnostics) { var receiverType = receiver.Type as NamedTypeSymbol; if ((object)receiverType == null || !receiverType.IsAnonymousType) { // We only construct transparent query variables using anonymous types, so if we're trying to navigate through // some other type, we must have some hinky query API where the types don't match up as expected. // We should report this as an error of some sort. // TODO: DevDiv #737822 - reword error message and add test. var info = new CSDiagnosticInfo(ErrorCode.ERR_UnsupportedTransparentIdentifierAccess, name, receiver.ExpressionSymbol ?? receiverType); Error(diagnostics, info, node); return new BoundBadExpression( node, LookupResultKind.Empty, ImmutableArray.Create<Symbol>(receiver.ExpressionSymbol), ImmutableArray.Create<BoundNode>(receiver), new ExtendedErrorTypeSymbol(this.Compilation, "", 0, info)); } LookupResult lookupResult = LookupResult.GetInstance(); LookupOptions options = LookupOptions.MustBeInstance; HashSet<DiagnosticInfo> useSiteDiagnostics = null; LookupMembersWithFallback(lookupResult, receiver.Type, name, 0, ref useSiteDiagnostics, basesBeingResolved: null, options: options); diagnostics.Add(node, useSiteDiagnostics); var result = BindMemberOfType(node, node, name, 0, receiver, default(SeparatedSyntaxList<TypeSyntax>), default(ImmutableArray<TypeSymbol>), lookupResult, BoundMethodGroupFlags.None, diagnostics); result.WasCompilerGenerated = true; lookupResult.Free(); return result; }
private static IMethodSymbol GetCallerMethodSymbol(SemanticModel semanticModel, SimpleNameSyntax name, int argumentsCount) { var symbolInfo = semanticModel.GetSymbolInfo(name); return symbolInfo.Symbol as IMethodSymbol ?? symbolInfo .CandidateSymbols .OfType<IMethodSymbol>() .FirstOrDefault(s => s.Parameters.Length == argumentsCount + 1); }
private static bool OtherMethodExists(InvocationExpressionSyntax invocation, SimpleNameSyntax nameToCheck, SemanticModel semanticModel) { var otherExpression = ((MemberAccessExpressionSyntax)invocation.Expression).WithName(nameToCheck).WithAdditionalAnnotations(speculativeAnnotation); var statement = invocation.FirstAncestorOrSelfThatIsAStatement(); var otherStatement = statement.ReplaceNode(invocation.Expression, otherExpression); SemanticModel speculativeModel; if (!semanticModel.TryGetSpeculativeSemanticModel(statement.SpanStart, otherStatement, out speculativeModel)) return false; var otherInvocationSymbol = speculativeModel.GetSymbolInfo(speculativeModel.SyntaxTree.GetRoot().GetAnnotatedNodes(speculativeAnnotationDescription).First()); return otherInvocationSymbol.Symbol != null; }
private bool IsReference(SimpleNameSyntax name) { if (name.Identifier.ValueText != _variableDeclarator.Identifier.ValueText) { return false; } var symbol = _semanticModel.GetSymbolInfo(name).Symbol; return symbol != null && symbol.Equals(_localSymbol); }
private static Task<Document> GetTransformedDocumentAsync(Document document, SyntaxNode root, SimpleNameSyntax node) { var qualifiedExpression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpressionSyntax, node.WithoutTrivia().WithoutFormatting()) .WithTriviaFrom(node) .WithoutFormatting(); var newSyntaxRoot = root.ReplaceNode(node, qualifiedExpression); return Task.FromResult(document.WithSyntaxRoot(newSyntaxRoot)); }
public static TypeNameText From(SimpleNameSyntax syntax) { var identifier = syntax.Identifier.Text; var typeArgs = string.Empty; var genericName = syntax as GenericNameSyntax; if (genericName != null && genericName.TypeArgumentList != null) { var count = genericName.TypeArgumentList.Arguments.Count; identifier = $"\"{identifier}`{count}\""; typeArgs = "<" + string.Join(",", genericName.TypeArgumentList.Arguments) + ">"; } return new TypeNameText { Identifier = identifier, TypeArguments = typeArgs }; }
private static bool IsSelectingADifferentMethod(IEnumerable<SyntaxNode> childNodes, SimpleNameSyntax methodName, SyntaxTree tree, IMethodSymbol methodSymbol, ExpressionSyntax invocationExpression, Compilation compilation) { var parameterExpressions = GetParameterExpressions(childNodes); var firstArgument = parameterExpressions.FirstOrDefault(); var argumentList = CreateArgumentListSyntaxFrom(parameterExpressions.Skip(1)); var newInvocationStatement = CreateInvocationExpression(firstArgument, methodName, argumentList) .WithAdditionalAnnotations(introduceExtensionMethodAnnotation); var extensionMethodNamespaceUsingDirective = SyntaxFactory.UsingDirective(methodSymbol.ContainingNamespace.ToNameSyntax()); var speculativeRootWithExtensionMethod = tree.GetCompilationUnitRoot() .ReplaceNode(invocationExpression, newInvocationStatement) .AddUsings(extensionMethodNamespaceUsingDirective); var speculativeModel = compilation.ReplaceSyntaxTree(tree, speculativeRootWithExtensionMethod.SyntaxTree) .GetSemanticModel(speculativeRootWithExtensionMethod.SyntaxTree); var speculativeInvocationStatement = speculativeRootWithExtensionMethod.SyntaxTree.GetCompilationUnitRoot().GetAnnotatedNodes(introduceExtensionMethodAnnotation).Single() as InvocationExpressionSyntax; var speculativeExtensionMethodSymbol = speculativeModel.GetSymbolInfo(speculativeInvocationStatement.Expression).Symbol as IMethodSymbol; var speculativeNonExtensionFormOfTheMethodSymbol = speculativeExtensionMethodSymbol?.GetConstructedReducedFrom(); return speculativeNonExtensionFormOfTheMethodSymbol == null || !speculativeNonExtensionFormOfTheMethodSymbol.Equals(methodSymbol); }
private static bool IsSelectingADifferentMethod(IEnumerable<SyntaxNode> childNodes, SimpleNameSyntax methodName, SyntaxTree tree, IMethodSymbol methodSymbol, ExpressionSyntax invocationExpression, Compilation compilation) { var parameterExpressions = GetParameterExpressions(childNodes); var firstArgument = parameterExpressions.FirstOrDefault(); var argumentList = CreateArgumentListSyntaxFrom(parameterExpressions.Skip(1)); var newInvocationStatement = CreateInvocationExpression(firstArgument, methodName, argumentList) .WithAdditionalAnnotations(introduceExtensionMethodAnnotation); var extensionMethodNamespaceUsingDirective = SyntaxFactory.UsingDirective(methodSymbol.ContainingNamespace.ToNameSyntax()); var speculativeRootWithExtensionMethod = tree.GetCompilationUnitRoot() .ReplaceNode(invocationExpression, newInvocationStatement) .AddUsings(extensionMethodNamespaceUsingDirective); var speculativeTree = speculativeRootWithExtensionMethod.SyntaxTree; var speculativeTreeOptions = (CSharpParseOptions)speculativeTree.Options; var speculativeTreeWithCorrectLanguageVersion = speculativeTree.WithRootAndOptions(speculativeRootWithExtensionMethod, speculativeTreeOptions.WithLanguageVersion(((CSharpParseOptions)tree.Options).LanguageVersion)); var speculativeModel = compilation.ReplaceSyntaxTree(tree, speculativeTreeWithCorrectLanguageVersion) .GetSemanticModel(speculativeTreeWithCorrectLanguageVersion); var speculativeInvocationStatement = speculativeTreeWithCorrectLanguageVersion.GetCompilationUnitRoot().GetAnnotatedNodes(introduceExtensionMethodAnnotation).Single() as InvocationExpressionSyntax; var speculativeExtensionMethodSymbol = speculativeModel.GetSymbolInfo(speculativeInvocationStatement.Expression).Symbol as IMethodSymbol; var speculativeNonExtensionFormOfTheMethodSymbol = speculativeExtensionMethodSymbol?.GetConstructedReducedFrom(); return speculativeNonExtensionFormOfTheMethodSymbol == null || speculativeNonExtensionFormOfTheMethodSymbol.ToString() != methodSymbol.ToString();//can't compare equality, as speculative symbol might be different }
private bool IsInvocationWithDynamicArguments(SimpleNameSyntax originalSimpleName, SemanticModel semanticModel) { var invocationExpression = originalSimpleName.Ancestors().OfType<InvocationExpressionSyntax>().FirstOrDefault(); // Check to see if this is the invocation Expression we wanted to work with if (invocationExpression != null && invocationExpression.Expression.GetLastToken() == originalSimpleName.GetLastToken()) { if (invocationExpression.ArgumentList != null) { foreach (var argument in invocationExpression.ArgumentList.Arguments) { if (argument != null && argument.Expression != null) { var typeinfo = semanticModel.GetTypeInfo(argument.Expression); if (typeinfo.Type != null && typeinfo.Type.TypeKind == TypeKind.Dynamic) { return true; } } } } } return false; }
private ExpressionSyntax VisitSimpleName(SimpleNameSyntax rewrittenSimpleName, SimpleNameSyntax originalSimpleName) { _cancellationToken.ThrowIfCancellationRequested(); // if this is "var", then do not process further if (originalSimpleName.IsVar) { return rewrittenSimpleName; } var identifier = rewrittenSimpleName.Identifier; ExpressionSyntax newNode = rewrittenSimpleName; var isInsideCref = originalSimpleName.AncestorsAndSelf(ascendOutOfTrivia: true).Any(n => n is CrefSyntax); //// //// 1. if this identifier is an alias, we'll expand it here and replace the node completely. //// if (!SyntaxFacts.IsAliasQualifier(originalSimpleName)) { var aliasInfo = _semanticModel.GetAliasInfo(originalSimpleName, _cancellationToken); if (aliasInfo != null) { var aliasTarget = aliasInfo.Target; if (aliasTarget.IsNamespace() && ((INamespaceSymbol)aliasTarget).IsGlobalNamespace) { return rewrittenSimpleName; } // if the enclosing expression is a typeof expression that already contains open type we cannot // we need to insert an open type as well. var typeOfExpression = originalSimpleName.GetAncestor<TypeOfExpressionSyntax>(); if (typeOfExpression != null && IsTypeOfUnboundGenericType(_semanticModel, typeOfExpression)) { aliasTarget = ((INamedTypeSymbol)aliasTarget).ConstructUnboundGenericType(); } // the expanded form replaces the current identifier name. var replacement = FullyQualifyIdentifierName( aliasTarget, newNode, originalSimpleName, replaceNode: true, isInsideCref: isInsideCref, omitLeftHandSide: false) .WithAdditionalAnnotations(Simplifier.Annotation); // We replace the simple name completely, so we can't continue and rename the token // with a RenameLocationAnnotation. // There's also no way of removing annotations, so we just add a DoNotRenameAnnotation. if (replacement.Kind() == SyntaxKind.AliasQualifiedName) { var qualifiedReplacement = (AliasQualifiedNameSyntax)replacement; var newIdentifier = identifier.CopyAnnotationsTo(qualifiedReplacement.Name.Identifier); if (_annotationForReplacedAliasIdentifier != null) { newIdentifier = newIdentifier.WithAdditionalAnnotations(_annotationForReplacedAliasIdentifier); } var aliasAnnotationInfo = AliasAnnotation.Create(aliasInfo.Name); newIdentifier = newIdentifier.WithAdditionalAnnotations(aliasAnnotationInfo); replacement = replacement.ReplaceNode( qualifiedReplacement.Name, qualifiedReplacement.Name.WithIdentifier(newIdentifier)); replacement = newNode.CopyAnnotationsTo(replacement); var firstReplacementToken = replacement.GetFirstToken(true, false, true, true); var firstOriginalToken = originalSimpleName.GetFirstToken(true, false, true, true); SyntaxToken tokenWithLeadingWhitespace; if (TryAddLeadingElasticTriviaIfNecessary(firstReplacementToken, firstOriginalToken, out tokenWithLeadingWhitespace)) { replacement = replacement.ReplaceToken(firstOriginalToken, tokenWithLeadingWhitespace); } replacement = AppendElasticTriviaIfNecessary(replacement, originalSimpleName); return replacement; } if (replacement.Kind() == SyntaxKind.QualifiedName) { var qualifiedReplacement = (QualifiedNameSyntax)replacement; var newIdentifier = identifier.CopyAnnotationsTo(qualifiedReplacement.Right.Identifier); if (_annotationForReplacedAliasIdentifier != null) { newIdentifier = newIdentifier.WithAdditionalAnnotations(_annotationForReplacedAliasIdentifier); } var aliasAnnotationInfo = AliasAnnotation.Create(aliasInfo.Name); newIdentifier = newIdentifier.WithAdditionalAnnotations(aliasAnnotationInfo); replacement = replacement.ReplaceNode( qualifiedReplacement.Right, qualifiedReplacement.Right.WithIdentifier(newIdentifier)); replacement = newNode.CopyAnnotationsTo(replacement); replacement = AppendElasticTriviaIfNecessary(replacement, originalSimpleName); return replacement; } if (replacement.IsKind(SyntaxKind.IdentifierName)) { var identifierReplacement = (IdentifierNameSyntax)replacement; var newIdentifier = identifier.CopyAnnotationsTo(identifierReplacement.Identifier); if (_annotationForReplacedAliasIdentifier != null) { newIdentifier = newIdentifier.WithAdditionalAnnotations(_annotationForReplacedAliasIdentifier); } var aliasAnnotationInfo = AliasAnnotation.Create(aliasInfo.Name); newIdentifier = newIdentifier.WithAdditionalAnnotations(aliasAnnotationInfo); replacement = replacement.ReplaceToken(identifier, newIdentifier); replacement = newNode.CopyAnnotationsTo(replacement); replacement = AppendElasticTriviaIfNecessary(replacement, originalSimpleName); return replacement; } throw new NotImplementedException(); } } var symbol = _semanticModel.GetSymbolInfo(originalSimpleName.Identifier).Symbol; if (symbol == null) { return newNode; } var typeArgumentSymbols = TypeArgumentSymbolsPresentInName(originalSimpleName); var omitLeftSideOfExpression = false; // Check to see if the type Arguments in the resultant Symbol is recursively defined. if (IsTypeArgumentDefinedRecursive(symbol, typeArgumentSymbols, enterContainingSymbol: true)) { if (symbol.ContainingSymbol.Equals(symbol.OriginalDefinition.ContainingSymbol) && symbol.Kind == SymbolKind.Method && ((IMethodSymbol)symbol).IsStatic) { if (IsTypeArgumentDefinedRecursive(symbol, typeArgumentSymbols, enterContainingSymbol: false)) { return newNode; } else { omitLeftSideOfExpression = true; } } else { return newNode; } } if (IsInvocationWithDynamicArguments(originalSimpleName, _semanticModel)) { return newNode; } //// //// 2. If it's an attribute, make sure the identifier matches the attribute's class name. //// if (originalSimpleName.GetAncestor<AttributeSyntax>() != null) { if (symbol.IsConstructor() && symbol.ContainingType?.IsAttribute() == true) { symbol = symbol.ContainingType; var name = symbol.Name; Debug.Assert(name.StartsWith(originalSimpleName.Identifier.ValueText, StringComparison.Ordinal)); // if the user already used the Attribute suffix in the attribute, we'll maintain it. if (identifier.ValueText == name && name.EndsWith("Attribute", StringComparison.Ordinal)) { identifier = identifier.WithAdditionalAnnotations(SimplificationHelpers.DontSimplifyAnnotation); } identifier = identifier.CopyAnnotationsTo(SyntaxFactory.VerbatimIdentifier(identifier.LeadingTrivia, name, name, identifier.TrailingTrivia)); } } //// //// 3. Always try to escape keyword identifiers //// identifier = TryEscapeIdentifierToken(identifier, originalSimpleName, _semanticModel).WithAdditionalAnnotations(Simplifier.Annotation); if (identifier != rewrittenSimpleName.Identifier) { switch (newNode.Kind()) { case SyntaxKind.IdentifierName: case SyntaxKind.GenericName: newNode = ((SimpleNameSyntax)newNode).WithIdentifier(identifier); break; default: throw new NotImplementedException(); } } var parent = originalSimpleName.Parent; // do not complexify further for location where only simple names are allowed if (parent is MemberDeclarationSyntax || parent is MemberBindingExpressionSyntax || originalSimpleName.GetAncestor<NameEqualsSyntax>() != null || (parent is MemberAccessExpressionSyntax && parent.Kind() != SyntaxKind.SimpleMemberAccessExpression) || ((parent.Kind() == SyntaxKind.SimpleMemberAccessExpression || parent.Kind() == SyntaxKind.NameMemberCref) && originalSimpleName.IsRightSideOfDot()) || (parent.Kind() == SyntaxKind.QualifiedName && originalSimpleName.IsRightSideOfQualifiedName()) || (parent.Kind() == SyntaxKind.AliasQualifiedName)) { return TryAddTypeArgumentToIdentifierName(newNode, symbol); } //// //// 4. If this is a standalone identifier or the left side of a qualified name or member access try to fully qualify it //// // we need to treat the constructor as type name, so just get the containing type. if (symbol.IsConstructor() && (parent.Kind() == SyntaxKind.ObjectCreationExpression || parent.Kind() == SyntaxKind.NameMemberCref)) { symbol = symbol.ContainingType; } // if it's a namespace or type name, fully qualify it. if (symbol.Kind == SymbolKind.NamedType || symbol.Kind == SymbolKind.Namespace) { var replacement = FullyQualifyIdentifierName( (INamespaceOrTypeSymbol)symbol, newNode, originalSimpleName, replaceNode: false, isInsideCref: isInsideCref, omitLeftHandSide: omitLeftSideOfExpression) .WithAdditionalAnnotations(Simplifier.Annotation); replacement = AppendElasticTriviaIfNecessary(replacement, originalSimpleName); return replacement; } // if it's a member access, we're fully qualifying the left side and make it a member access. if (symbol.Kind == SymbolKind.Method || symbol.Kind == SymbolKind.Field || symbol.Kind == SymbolKind.Property) { if (symbol.IsStatic || originalSimpleName.IsParentKind(SyntaxKind.NameMemberCref) || _semanticModel.SyntaxTree.IsNameOfContext(originalSimpleName.SpanStart, _semanticModel, _cancellationToken)) { newNode = FullyQualifyIdentifierName( symbol, newNode, originalSimpleName, replaceNode: false, isInsideCref: isInsideCref, omitLeftHandSide: omitLeftSideOfExpression); } else { if (!IsPropertyNameOfObjectInitializer(originalSimpleName)) { ExpressionSyntax left; // Assumption here is, if the enclosing and containing types are different then there is inheritance relationship if (_semanticModel.GetEnclosingNamedType(originalSimpleName.SpanStart, _cancellationToken) != symbol.ContainingType) { left = SyntaxFactory.BaseExpression(); } else { left = SyntaxFactory.ThisExpression(); } var identifiersLeadingTrivia = newNode.GetLeadingTrivia(); newNode = TryAddTypeArgumentToIdentifierName(newNode, symbol); newNode = newNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)newNode.WithLeadingTrivia(null)) .WithLeadingTrivia(identifiersLeadingTrivia)); } } } var result = newNode.WithAdditionalAnnotations(Simplifier.Annotation); result = AppendElasticTriviaIfNecessary(result, originalSimpleName); return result; }
private IList<ISymbol> TypeArgumentSymbolsPresentInName(SimpleNameSyntax simpleName) { List<ISymbol> typeArgumentSymbols = new List<ISymbol>(); var typeArgumentListSyntax = simpleName.DescendantNodesAndSelf().Where(n => n is TypeArgumentListSyntax); foreach (var typeArgumentList in typeArgumentListSyntax) { var castedTypeArgument = (TypeArgumentListSyntax)typeArgumentList; foreach (var typeArgument in castedTypeArgument.Arguments) { var symbol = _semanticModel.GetSymbolInfo(typeArgument).Symbol; if (symbol != null && !typeArgumentSymbols.Contains(symbol)) { typeArgumentSymbols.Add(symbol); } } } return typeArgumentSymbols; }
private static CompilationUnitSyntax ReplaceStaticCallWithExtionMethodCall(CompilationUnitSyntax root, InvocationExpressionSyntax staticInvocationExpression, ExpressionSyntax sourceExpression, SimpleNameSyntax methodName, ArgumentListSyntax argumentList) { var extensionInvocationExpression = CallExtensionMethodAsExtensionAnalyzer.CreateInvocationExpression(sourceExpression, methodName, argumentList) .WithLeadingTrivia(staticInvocationExpression.GetLeadingTrivia()); return root.ReplaceNode(staticInvocationExpression, extensionInvocationExpression); }
public SimpleNameTranslation(SimpleNameSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { }
private static bool OtherMethodExists(InvocationExpressionSyntax invocation, SimpleNameSyntax nameToCheck, SemanticModel semanticModel) { var otherExpression = CreateExpressionWithNewName(invocation, nameToCheck); var statement = invocation.FirstAncestorOrSelfThatIsAStatement(); SemanticModel speculativeModel; if (statement != null) { var otherStatement = statement.ReplaceNode(invocation.Expression, otherExpression); if (!semanticModel.TryGetSpeculativeSemanticModel(statement.SpanStart, otherStatement, out speculativeModel)) return false; } else { var arrow = (ArrowExpressionClauseSyntax)invocation.FirstAncestorOfKind(SyntaxKind.ArrowExpressionClause); if (arrow == null) return false; var otherArrow = arrow.ReplaceNode(invocation.Expression, otherExpression); if (!semanticModel.TryGetSpeculativeSemanticModel(arrow.SpanStart, otherArrow, out speculativeModel)) return false; } var symbol = speculativeModel.GetSymbolInfo(speculativeModel.SyntaxTree.GetRoot().GetAnnotatedNodes(speculativeAnnotationDescription).First()).Symbol; return symbol != null; }
private static bool IsExplicitDelegateInvocation(IMethodSymbol symbol, SimpleNameSyntax invokedMethodName) { var isDynamicInvocation = symbol.MethodKind == MethodKind.Ordinary && symbol.Name == "DynamicInvoke" && symbol.ReceiverType.OriginalDefinition.Is(KnownType.System_Delegate); if (isDynamicInvocation) { return true; } return symbol.MethodKind == MethodKind.DelegateInvoke && invokedMethodName.Identifier.ValueText == "Invoke"; }
SyntaxNode ConvertIdentifier(SimpleNameSyntax originalNode, SimpleNameSyntax withConvertedDescendants) { return SyntaxFactory.ParseName(originalNode.ToFullString().Replace("CSharp", "VB")); }
public static ExpressionSyntax CreateExpressionWithNewName(InvocationExpressionSyntax invocation, SimpleNameSyntax nameToCheck) { var otherExpression = invocation.Expression.IsKind(SyntaxKind.MemberBindingExpression) ? (ExpressionSyntax)((MemberBindingExpressionSyntax)invocation.Expression).WithName(nameToCheck).WithAdditionalAnnotations(speculativeAnnotation) //avoid this, already checked before: if (invocation.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)): : ((MemberAccessExpressionSyntax)invocation.Expression).WithName(nameToCheck).WithAdditionalAnnotations(speculativeAnnotation); return otherExpression; }
private static InvocationExpressionSyntax TryReduceExtensionMethod(InvocationExpressionSyntax node, SemanticModel semanticModel, InvocationExpressionSyntax rewrittenNode, SimpleNameSyntax expressionName) { var targetSymbol = semanticModel.GetSymbolInfo(expressionName); if (targetSymbol.Symbol != null && targetSymbol.Symbol.Kind == SymbolKind.Method) { var targetMethodSymbol = (IMethodSymbol)targetSymbol.Symbol; if (!targetMethodSymbol.IsReducedExtension()) { var argumentList = node.ArgumentList; var noOfArguments = argumentList.Arguments.Count; if (noOfArguments > 0) { MemberAccessExpressionSyntax newMemberAccess = null; var invocationExpressionNodeExpression = node.Expression; if (node.Expression.CSharpKind() == SyntaxKind.SimpleMemberAccessExpression) { newMemberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, argumentList.Arguments.ElementAt(0).Expression, ((MemberAccessExpressionSyntax)invocationExpressionNodeExpression).OperatorToken, ((MemberAccessExpressionSyntax)invocationExpressionNodeExpression).Name); } else if (node.Expression.CSharpKind() == SyntaxKind.IdentifierName) { newMemberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, argumentList.Arguments.ElementAt(0).Expression, (IdentifierNameSyntax)invocationExpressionNodeExpression.WithLeadingTrivia()); } else if (node.Expression.CSharpKind() == SyntaxKind.GenericName) { newMemberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, argumentList.Arguments.ElementAt(0).Expression, (GenericNameSyntax)invocationExpressionNodeExpression.WithLeadingTrivia()); } else { Debug.Assert(false, "The expression kind is not MemberAccessExpression or IdentifierName or GenericName to be converted to Member Access Expression for Ext Method Reduction"); } if (newMemberAccess == null) { return node; } // Preserve Trivia newMemberAccess = newMemberAccess.WithLeadingTrivia(node.GetLeadingTrivia()); // Below removes the first argument // we need to reuse the separators to maintain existing formatting & comments in the arguments itself var newArguments = SyntaxFactory.SeparatedList<ArgumentSyntax>(argumentList.Arguments.GetWithSeparators().AsEnumerable().Skip(2)); var rewrittenArgumentList = argumentList.WithArguments(newArguments); var candidateRewrittenNode = SyntaxFactory.InvocationExpression(newMemberAccess, rewrittenArgumentList); var oldSymbol = semanticModel.GetSymbolInfo(node).Symbol; var newSymbol = semanticModel.GetSpeculativeSymbolInfo( node.SpanStart, candidateRewrittenNode, SpeculativeBindingOption.BindAsExpression).Symbol; if (oldSymbol != null && newSymbol != null) { if (newSymbol.Kind == SymbolKind.Method && oldSymbol.Equals(((IMethodSymbol)newSymbol).GetConstructedReducedFrom())) { rewrittenNode = candidateRewrittenNode; } } } } } return rewrittenNode; }
private static void HandleIdentifierNameImpl(SyntaxNodeAnalysisContext context, SimpleNameSyntax nameExpression) { if (nameExpression == null) { return; } if (!HasThis(nameExpression)) { return; } SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(nameExpression, context.CancellationToken); ImmutableArray<ISymbol> symbolsToAnalyze; if (symbolInfo.Symbol != null) { symbolsToAnalyze = ImmutableArray.Create(symbolInfo.Symbol); } else if (symbolInfo.CandidateReason == CandidateReason.MemberGroup) { // analyze the complete set of candidates, and use 'this.' if it applies to all symbolsToAnalyze = symbolInfo.CandidateSymbols; } else { return; } foreach (ISymbol symbol in symbolsToAnalyze) { if (symbol is ITypeSymbol) { return; } if (symbol.IsStatic) { return; } if (!(symbol.ContainingSymbol is ITypeSymbol)) { // covers local variables, parameters, etc. return; } IMethodSymbol methodSymbol = symbol as IMethodSymbol; if (methodSymbol != null && methodSymbol.MethodKind == MethodKind.Constructor) { return; } // This is a workaround for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1501 and can // be removed when the underlying bug in roslyn is resolved if (nameExpression.Parent is MemberAccessExpressionSyntax) { var parentSymbol = context.SemanticModel.GetSymbolInfo(nameExpression.Parent, context.CancellationToken).Symbol as IFieldSymbol; if (parentSymbol != null && parentSymbol.IsStatic && parentSymbol.ContainingType.Name == symbol.Name) { return; } } // End of workaround } // Prefix local calls with this context.ReportDiagnostic(Diagnostic.Create(Descriptor, nameExpression.GetLocation())); }
private bool IsPropertyNameOfObjectInitializer(SimpleNameSyntax identifierName) { SyntaxNode currentNode = identifierName; SyntaxNode parent = identifierName; while (parent != null) { if (parent.Kind() == SyntaxKind.ObjectInitializerExpression) { return currentNode.Kind() == SyntaxKind.SimpleAssignmentExpression && object.Equals(((AssignmentExpressionSyntax)currentNode).Left, identifierName); } else if (parent is ExpressionSyntax) { currentNode = parent; parent = parent.Parent; continue; } else { return false; } } return false; }
private static bool IsJoinRangeVariableInLeftKey(SimpleNameSyntax node) { for (CSharpSyntaxNode parent = node.Parent; parent != null; parent = parent.Parent) { if (parent.Kind() == SyntaxKind.JoinClause) { var join = parent as JoinClauseSyntax; if (join.LeftExpression.Span.Contains(node.Span) && join.Identifier.ValueText == node.Identifier.ValueText) return true; } } return false; }
private static bool IsInJoinRightKey(SimpleNameSyntax node) { // TODO: refine this test to check if the identifier is the name of a range // variable of the enclosing query. for (CSharpSyntaxNode parent = node.Parent; parent != null; parent = parent.Parent) { if (parent.Kind() == SyntaxKind.JoinClause) { var join = parent as JoinClauseSyntax; if (join.RightExpression.Span.Contains(node.Span)) return true; } } return false; }
private static string GetSimpleTypeName(SimpleNameSyntax name) { return name.Identifier.ValueText; }
private MethodDeclarationSyntax CreateKeyValueMethod(MetaField field, IdentifierNameSyntax methodName, SimpleNameSyntax collectionMutationMethodName) { var paramsArrayMethod = CreateMethodStarter(methodName.Identifier, field) .WithParameterList(SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList( new ParameterSyntax[] { SyntaxFactory.Parameter(KeyParameterName.Identifier).WithType(GetFullyQualifiedSymbolName(field.ElementKeyType)), SyntaxFactory.Parameter(ValueParameterName.Identifier).WithType(GetFullyQualifiedSymbolName(field.ElementValueType)), }))); paramsArrayMethod = this.AddMethodBody( paramsArrayMethod, field, receiver => SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, receiver, collectionMutationMethodName), SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new ArgumentSyntax[] { SyntaxFactory.Argument(KeyParameterName), SyntaxFactory.Argument(ValueParameterName), })))); return paramsArrayMethod; }
private static bool AddSimpleName(SimpleNameSyntax simpleName, List<string> parts) { if (!simpleName.IsKind(SyntaxKind.IdentifierName)) { return false; } parts.Add(simpleName.Identifier.ValueText); return true; }
private MethodDeclarationSyntax CreateParamsElementArrayMethod(MetaField field, IdentifierNameSyntax methodName, SimpleNameSyntax collectionMutationMethodName, bool passThroughChildSync = false) { var paramsArrayMethod = CreateMethodStarter(methodName.Identifier, field) .WithParameterList(CreateParamsElementArrayParameters(field)); var lambdaParameter = SyntaxFactory.Parameter(SyntaxFactory.Identifier("v")); var argument = passThroughChildSync ? (ExpressionSyntax)Syntax.EnumerableExtension( SyntaxFactory.IdentifierName(nameof(Enumerable.Select)), ValuesParameterName, SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Argument(Syntax.ThisDot(SyncImmediateChildToCurrentVersionMethodName))))) : ValuesParameterName; paramsArrayMethod = this.AddMethodBody( paramsArrayMethod, field, receiver => SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, receiver, collectionMutationMethodName), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Argument(argument))))); return paramsArrayMethod; }
private static void HandleIdentifierNameImpl(SyntaxNodeAnalysisContext context, SimpleNameSyntax nameExpression) { if (nameExpression == null) { return; } if (!HasThis(nameExpression)) { return; } SymbolInfo symbolInfo = context.SemanticModel.GetSymbolInfo(nameExpression, context.CancellationToken); ImmutableArray<ISymbol> symbolsToAnalyze; if (symbolInfo.Symbol != null) { symbolsToAnalyze = ImmutableArray.Create(symbolInfo.Symbol); } else if (symbolInfo.CandidateReason == CandidateReason.MemberGroup) { // analyze the complete set of candidates, and use 'this.' if it applies to all symbolsToAnalyze = symbolInfo.CandidateSymbols; } else { return; } foreach (ISymbol symbol in symbolsToAnalyze) { if (symbol is ITypeSymbol) { return; } if (symbol.IsStatic) { return; } if (!(symbol.ContainingSymbol is ITypeSymbol)) { // covers local variables, parameters, etc. return; } IMethodSymbol methodSymbol = symbol as IMethodSymbol; if (methodSymbol != null && methodSymbol.MethodKind == MethodKind.Constructor) { return; } } // Prefix local calls with this context.ReportDiagnostic(Diagnostic.Create(Descriptor, nameExpression.GetLocation())); }
private MethodDeclarationSyntax CreateSingleElementMethod(MetaField field, IdentifierNameSyntax methodName, SimpleNameSyntax collectionMutationMethodName, bool passThroughChildSync = false, IdentifierNameSyntax elementParameterName = null, ITypeSymbol elementType = null) { elementParameterName = elementParameterName ?? ValueParameterName; var paramsArrayMethod = CreateMethodStarter(methodName.Identifier, field) .WithParameterList(SyntaxFactory.ParameterList(SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Parameter(elementParameterName.Identifier) .WithType(GetFullyQualifiedSymbolName(elementType ?? field.ElementType))))); var argument = passThroughChildSync ? (ExpressionSyntax)SyntaxFactory.InvocationExpression( Syntax.ThisDot(SyncImmediateChildToCurrentVersionMethodName), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(elementParameterName)))) : elementParameterName; paramsArrayMethod = this.AddMethodBody( paramsArrayMethod, field, receiver => SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, receiver, collectionMutationMethodName), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Argument(argument))))); return paramsArrayMethod; }