private static bool IsCandidateForRemoval(BaseMethodDeclarationSyntax methodOrConstructor, SemanticModel semanticModel) { if (methodOrConstructor.Modifiers.Any(m => m.ValueText == "partial" || m.ValueText == "override") || !methodOrConstructor.ParameterList.Parameters.Any() || methodOrConstructor.Body == null) return false; var method = methodOrConstructor as MethodDeclarationSyntax; if (method != null) { if (method.ExplicitInterfaceSpecifier != null) return false; var methodSymbol = semanticModel.GetDeclaredSymbol(method); if (methodSymbol == null) return false; var typeSymbol = methodSymbol.ContainingType; if (typeSymbol.AllInterfaces.SelectMany(i => i.GetMembers()) .Any(member => methodSymbol.Equals(typeSymbol.FindImplementationForInterfaceMember(member)))) return false; if (IsEventHandlerLike(method, semanticModel)) return false; } else { var constructor = methodOrConstructor as ConstructorDeclarationSyntax; if (constructor != null) { if (IsSerializationConstructor(constructor, semanticModel)) return false; } else { return false; } } return true; }
/// <summary> /// A position is inside a body if it is inside the block or expression /// body. /// /// A position is considered to be inside a block if it is on or after /// the open brace and strictly before the close brace. A position is /// considered to be inside an expression body if it is on or after /// the '=>' and strictly before the semicolon. /// </summary> internal static bool IsInBody(int position, BaseMethodDeclarationSyntax method) { var exprOpt = method.GetExpressionBodySyntax(); return IsInExpressionBody(position, exprOpt, method.SemicolonToken) || IsInBlock(position, method.Body); }
public BaseMethodDeclarationTranslation(BaseMethodDeclarationSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { ParameterList = syntax.ParameterList.Get<ParameterListTranslation>(this); Modifiers = syntax.Modifiers.Get(this); Body = syntax.Body.Get<BlockTranslation>(this); SemicolonToken = syntax.SemicolonToken.Get(this); }
internal static bool IsInMethodDeclaration(int position, BaseMethodDeclarationSyntax methodDecl) { Debug.Assert(methodDecl != null); var body = methodDecl.Body; SyntaxToken lastToken = body == null ? methodDecl.SemicolonToken : body.CloseBraceToken; return IsBeforeToken(position, methodDecl, lastToken); }
/// <summary> /// Constructor. /// </summary> /// <param name="context">AnalysisContext</param> /// <param name="method">BaseMethodDeclarationSyntax</param> /// <param name="parameterTypes">ITypeSymbols</param> private MethodSummary(AnalysisContext context, BaseMethodDeclarationSyntax method, IDictionary<int, ISet<ITypeSymbol>> parameterTypes) { this.Id = MethodSummary.IdCounter++; this.AnalysisContext = context; this.SemanticModel = context.Compilation.GetSemanticModel(method.SyntaxTree); this.Method = method; this.SideEffectsInfo = new MethodSideEffectsInfo(this); this.ResolveMethodParameterTypes(parameterTypes); }
public static bool IsNoCompile(this SemanticModel model, BaseMethodDeclarationSyntax syntax) { foreach (var attrListSyntax in syntax.AttributeLists) { foreach (var attr in attrListSyntax.Attributes) { var type = model.GetTypeInfo(attr); if (type.Type.IsSameType(nameof(JavaScript), nameof(NoCompileAttribute))) return true; } } return false; }
public bool CanBeMadeStatic(BaseMethodDeclarationSyntax method) { if (method.Modifiers.Any(SyntaxKind.StaticKeyword) || method.Body == null || !method.Body.ChildNodes().Any()) { return false; } var bodyNodes = method.Body.ChildNodes(); var dataflow = _model.AnalyzeDataFlow(bodyNodes.First(), bodyNodes.Last()); var hasThisReference = dataflow.DataFlowsIn .Any(x => x.Kind == SymbolKind.Parameter && x.Name == SyntaxFactory.Token(SyntaxKind.ThisKeyword).ToFullString()); return !hasThisReference; }
private static void RegisterActionForDestructor(CodeFixContext context, SyntaxNode root, BaseMethodDeclarationSyntax method) { context.RegisterCodeFix( CodeAction.Create( TitleRemoveDestructor, c => { var newRoot = root.RemoveNode( method, SyntaxRemoveOptions.KeepNoTrivia); return Task.FromResult(context.Document.WithSyntaxRoot(newRoot)); }, TitleRemoveDestructor), context.Diagnostics); }
/// <summary> /// Constructor. /// </summary> /// <param name="method">BaseMethodDeclarationSyntax</param> /// <param name="machine">StateMachine</param> /// <param name="state">MachineState</param> /// <param name="payload">ISymbol</param> internal TraceInfo(BaseMethodDeclarationSyntax method, StateMachine machine, MachineState state, ISymbol payload) { this.ErrorTrace = new List<ErrorTraceStep>(); this.CallTrace = new List<CallTraceStep>(); if (method == null) { this.Method = null; } else if (method is MethodDeclarationSyntax) { this.Method = (method as MethodDeclarationSyntax).Identifier.ValueText; } else if (method is ConstructorDeclarationSyntax) { this.Method = (method as ConstructorDeclarationSyntax).Identifier.ValueText; } if (machine == null) { this.Machine = null; } else { this.Machine = machine.Name; } if (state == null) { this.State = null; } else { this.State = state.Name; } if (payload == null) { this.Payload = null; } else { this.Payload = payload.Name; } }
/// <summary> /// A position is inside a body if it is inside the block or expression /// body. /// /// A position is considered to be inside a block if it is on or after /// the open brace and strictly before the close brace. A position is /// considered to be inside an expression body if it is on or after /// the '=>' and strictly before the semicolon. /// </summary> internal static bool IsInBody(int position, BaseMethodDeclarationSyntax method) { ArrowExpressionClauseSyntax expressionBodyOpt = null; switch (method.Kind) { case SyntaxKind.ConversionOperatorDeclaration: expressionBodyOpt = ((ConversionOperatorDeclarationSyntax)method).ExpressionBody; break; case SyntaxKind.OperatorDeclaration: expressionBodyOpt = ((OperatorDeclarationSyntax)method).ExpressionBody; break; case SyntaxKind.MethodDeclaration: expressionBodyOpt = ((MethodDeclarationSyntax)method).ExpressionBody; break; default: break; } return IsInExpressionBody(position, expressionBodyOpt, method.SemicolonToken) || IsInBlock(position, method.Body); }
public IEnumerable<ParameterSyntax> GetUnusedParameters(BaseMethodDeclarationSyntax method) { if (method.ParameterList.Parameters.Count == 0 || method.Body == null || !method.Body.ChildNodes().Any()) { return new ParameterSyntax[0]; } var bodyNodes = method.Body.ChildNodes(); var dataflow = _model.AnalyzeDataFlow(bodyNodes.First(), bodyNodes.Last()); var usedParameterNames = dataflow.DataFlowsIn .Where(x => x.Kind == SymbolKind.Parameter) .Select(x => x.Name) .AsArray(); var unusedParameters = method.ParameterList.Parameters .Where(p => !usedParameterNames.Contains(p.Identifier.ValueText)) .AsArray(); return unusedParameters; }
private static async Task<Document> ConvertToExpressionBodiedMemberAsync( Document document, BaseMethodDeclarationSyntax declaration, CancellationToken cancellationToken) { var body = declaration.Body; var returnStatement = body.Statements[0] as ReturnStatementSyntax; var arrowExpression = SyntaxFactory.ArrowExpressionClause(returnStatement.Expression); var newDeclaration = declaration; newDeclaration = ((dynamic)newDeclaration) .WithBody(null) .WithExpressionBody(arrowExpression) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); newDeclaration = newDeclaration.WithAdditionalAnnotations(Formatter.Annotation); return await ReplaceNodeAsync(document, declaration, newDeclaration, cancellationToken); }
private void AppendParameters(BaseMethodDeclarationSyntax syntax, StringBuilder builder) { builder.Append("("); var parameterList = syntax.ParameterList; if (parameterList != null) { var parameters = parameterList.Parameters; Func<ParameterSyntax, string> selector = parameters.Any() ? new Func<ParameterSyntax, string>(TypeNameSelector) : x => string.Empty; var parameterNames = string.Join(", ", parameters.Select(selector).Where(x => !string.IsNullOrWhiteSpace(x))); builder.Append(parameterNames); } builder.Append(")"); }
private VirtualTreePoint GetEndPoint(SourceText text, BaseMethodDeclarationSyntax node, EnvDTE.vsCMPart part) { int endPosition; switch (part) { case EnvDTE.vsCMPart.vsCMPartName: case EnvDTE.vsCMPart.vsCMPartAttributes: case EnvDTE.vsCMPart.vsCMPartHeader: case EnvDTE.vsCMPart.vsCMPartWhole: case EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter: case EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes: throw Exceptions.ThrowENotImpl(); case EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter: if (node.AttributeLists.Count == 0) { throw Exceptions.ThrowEFail(); } endPosition = node.AttributeLists.Last().GetLastToken().Span.End; break; case EnvDTE.vsCMPart.vsCMPartWholeWithAttributes: endPosition = node.Span.End; break; case EnvDTE.vsCMPart.vsCMPartNavigate: if (node.Body != null && !node.Body.CloseBraceToken.IsMissing) { return GetBodyEndPoint(text, node.Body.CloseBraceToken); } else { switch (node.Kind()) { case SyntaxKind.MethodDeclaration: endPosition = ((MethodDeclarationSyntax)node).Identifier.Span.End; break; case SyntaxKind.ConstructorDeclaration: endPosition = ((ConstructorDeclarationSyntax)node).Identifier.Span.End; break; case SyntaxKind.DestructorDeclaration: endPosition = ((DestructorDeclarationSyntax)node).Identifier.Span.End; break; case SyntaxKind.ConversionOperatorDeclaration: endPosition = ((ConversionOperatorDeclarationSyntax)node).ImplicitOrExplicitKeyword.Span.End; break; case SyntaxKind.OperatorDeclaration: endPosition = ((OperatorDeclarationSyntax)node).OperatorToken.Span.End; break; default: endPosition = node.GetFirstTokenAfterAttributes().Span.End; break; } } break; case EnvDTE.vsCMPart.vsCMPartBody: if (node.Body == null || node.Body.OpenBraceToken.IsMissing || node.Body.CloseBraceToken.IsMissing) { throw Exceptions.ThrowEFail(); } return GetBodyEndPoint(text, node.Body.CloseBraceToken); default: throw Exceptions.ThrowEInvalidArg(); } return new VirtualTreePoint(node.SyntaxTree, text, endPosition); }
public override IMethodSymbol GetDeclaredSymbol(BaseMethodDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { // Can't define method inside member. return null; }
internal static bool IsInParameterList(int position, BaseMethodDeclarationSyntax methodDecl) { var parameterList = methodDecl.ParameterList; return(IsBeforeToken(position, parameterList, parameterList.CloseParenToken)); }
private VirtualTreePoint GetStartPoint(SourceText text, BaseMethodDeclarationSyntax node, EnvDTE.vsCMPart part) { int startPosition; switch (part) { case EnvDTE.vsCMPart.vsCMPartName: case EnvDTE.vsCMPart.vsCMPartAttributes: case EnvDTE.vsCMPart.vsCMPartWhole: case EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter: case EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes: throw Exceptions.ThrowENotImpl(); case EnvDTE.vsCMPart.vsCMPartHeader: startPosition = node.GetFirstTokenAfterAttributes().SpanStart; break; case EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter: if (node.AttributeLists.Count == 0) { throw Exceptions.ThrowEFail(); } goto case EnvDTE.vsCMPart.vsCMPartWholeWithAttributes; case EnvDTE.vsCMPart.vsCMPartWholeWithAttributes: startPosition = node.GetFirstToken().SpanStart; break; case EnvDTE.vsCMPart.vsCMPartNavigate: if (node.Body != null && !node.Body.OpenBraceToken.IsMissing) { var line = text.Lines.GetLineFromPosition(node.SpanStart); var indentation = line.GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(GetTabSize(text)); return GetBodyStartPoint(text, node.Body.OpenBraceToken, node.Body.CloseBraceToken, indentation); } else { switch (node.Kind()) { case SyntaxKind.MethodDeclaration: startPosition = ((MethodDeclarationSyntax)node).Identifier.SpanStart; break; case SyntaxKind.ConstructorDeclaration: startPosition = ((ConstructorDeclarationSyntax)node).Identifier.SpanStart; break; case SyntaxKind.DestructorDeclaration: startPosition = ((DestructorDeclarationSyntax)node).Identifier.SpanStart; break; case SyntaxKind.ConversionOperatorDeclaration: startPosition = ((ConversionOperatorDeclarationSyntax)node).ImplicitOrExplicitKeyword.SpanStart; break; case SyntaxKind.OperatorDeclaration: startPosition = ((OperatorDeclarationSyntax)node).OperatorToken.SpanStart; break; default: startPosition = node.GetFirstTokenAfterAttributes().SpanStart; break; } } break; case EnvDTE.vsCMPart.vsCMPartBody: if (node.Body == null || node.Body.OpenBraceToken.IsMissing || node.Body.CloseBraceToken.IsMissing) { throw Exceptions.ThrowEFail(); } return GetBodyStartPoint(text, node.Body.OpenBraceToken); default: throw Exceptions.ThrowEInvalidArg(); } return new VirtualTreePoint(node.SyntaxTree, text, startPosition); }
/// <summary> /// Constructor. /// </summary> /// <param name="method">Method</param> /// <param name="invocation">Invocation</param> internal CallTraceStep(BaseMethodDeclarationSyntax method, ExpressionSyntax invocation) { this.Method = method; this.Invocation = invocation; }
private bool CompareMethodDeclarations( BaseMethodDeclarationSyntax oldMethod, BaseMethodDeclarationSyntax newMethod, SyntaxNode newNodeParent, CodeModelEventQueue eventQueue) { Debug.Assert(oldMethod != null && newMethod != null); if (!StringComparer.Ordinal.Equals(CodeModelService.GetName(oldMethod), CodeModelService.GetName(newMethod))) { var change = CompareRenamedDeclarations( CompareParameters, oldMethod.ParameterList.Parameters.AsReadOnlyList(), newMethod.ParameterList.Parameters.AsReadOnlyList(), oldMethod, newMethod, newNodeParent, eventQueue); if (change == DeclarationChange.NameOnly) { EnqueueChangeEvent(newMethod, newNodeParent, CodeModelEventType.Rename, eventQueue); } return false; } else { bool same = true; if (!CompareModifiers(oldMethod, newMethod)) { same = false; EnqueueChangeEvent(newMethod, newNodeParent, CodeModelEventType.Unknown, eventQueue); } if (!CompareTypes(GetReturnType(oldMethod), GetReturnType(newMethod))) { same = false; EnqueueChangeEvent(newMethod, newNodeParent, CodeModelEventType.TypeRefChange, eventQueue); } same &= CompareChildren( CompareAttributeLists, oldMethod.AttributeLists.AsReadOnlyList(), newMethod.AttributeLists.AsReadOnlyList(), newMethod, CodeModelEventType.Unknown, eventQueue); same &= CompareChildren( CompareParameters, oldMethod.ParameterList.Parameters.AsReadOnlyList(), newMethod.ParameterList.Parameters.AsReadOnlyList(), newMethod, CodeModelEventType.SigChange, eventQueue); return same; } }
internal sealed override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel) { position = CheckAndAdjustPosition(position); var model = this.GetMemberModel(position); if (model != null) { return model.TryGetSpeculativeSemanticModelForMethodBodyCore(parentModel, position, method, out speculativeModel); } speculativeModel = null; return false; }
private static void HandleBaseMethodDeclaration( SyntaxNodeAnalysisContext context, BaseMethodDeclarationSyntax baseMethodDeclarationSyntax) { if (baseMethodDeclarationSyntax.ParameterList == null || baseMethodDeclarationSyntax.ParameterList.IsMissing || !baseMethodDeclarationSyntax.ParameterList.Parameters.Any()) { return; } var lastParameter = baseMethodDeclarationSyntax.ParameterList .Parameters .Last(); if (!baseMethodDeclarationSyntax.ParameterList.CloseParenToken.IsMissing) { CheckIfLocationOfLastArgumentOrParameterAndCloseTokenAreTheSame(context, lastParameter, baseMethodDeclarationSyntax.ParameterList.CloseParenToken); } }
/// <summary> /// A position is inside a body if it is inside the block or expression /// body. /// /// A position is considered to be inside a block if it is on or after /// the open brace and strictly before the close brace. A position is /// considered to be inside an expression body if it is on or after /// the '=>' and strictly before the semicolon. /// </summary> internal static bool IsInBody(int position, BaseMethodDeclarationSyntax method) => IsInBody(position, method.Body, method.GetExpressionBodySyntax(), method.SemicolonToken);
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel) { speculativeModel = null; return false; }
private static void HandleBaseMethodDeclaration( SyntaxNodeAnalysisContext context, BaseMethodDeclarationSyntax baseMethodDeclarationSyntax) { var parameterListSyntax = baseMethodDeclarationSyntax.ParameterList; if (parameterListSyntax != null && !parameterListSyntax.Parameters.Any()) { if (!parameterListSyntax.OpenParenToken.IsMissing && !parameterListSyntax.CloseParenToken.IsMissing) { CheckIfLocationOfOpenAndCloseTokensAreTheSame(context, parameterListSyntax.OpenParenToken, parameterListSyntax.CloseParenToken); } } }
/// <summary> /// Given a base method declaration syntax, get the corresponding method symbol. /// </summary> /// <param name="declarationSyntax">The syntax node that declares a method.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The symbol that was declared.</returns> /// <remarks> /// NOTE: We have no GetDeclaredSymbol overloads for subtypes of BaseMethodDeclarationSyntax as all of them return a MethodSymbol. /// </remarks> public override IMethodSymbol GetDeclaredSymbol(BaseMethodDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken)) { return (IMethodSymbol)GetDeclaredMemberSymbol(declarationSyntax); }
private string GetFunctionPrototype(BaseMethodDeclarationSyntax node, IMethodSymbol symbol, PrototypeFlags flags) { if ((flags & PrototypeFlags.Signature) != 0) { if (flags != PrototypeFlags.Signature) { // vsCMPrototypeUniqueSignature can't be combined with anything else. throw Exceptions.ThrowEInvalidArg(); } // The unique signature is simply the node key. return GetNodeKey(node).Name; } var builder = new StringBuilder(); AppendFunctionPrototype(builder, symbol, flags, GetName(node)); return builder.ToString(); }
private SyntaxNode RegisterMethodLikeDeclarationCodeFix(SyntaxNode syntaxRoot, BaseMethodDeclarationSyntax node, IndentationOptions indentationOptions) { return this.ReformatElement(syntaxRoot, node, node.Body.OpenBraceToken, node.Body.CloseBraceToken, indentationOptions); }
/// <summary> /// Get a SemanticModel object that is associated with a method body that did not appear in this source code. /// Given <paramref name="position"/> must lie within an existing method body of the Root syntax node for this SemanticModel. /// Locals and labels declared within this existing method body are not considered to be in scope of the speculated method body. /// </summary> /// <param name="position">A character position used to identify a declaration scope and accessibility. This /// character position must be within the FullSpan of the Root syntax node in this SemanticModel and must be /// within the FullSpan of a Method body within the Root syntax node.</param> /// <param name="method">A syntax node that represents a parsed method declaration. This method should not be /// present in the syntax tree associated with this object, but must have identical signature to the method containing /// the given <paramref name="position"/> in this SemanticModel.</param> /// <param name="speculativeModel">A SemanticModel object that can be used to inquire about the semantic /// information associated with syntax nodes within <paramref name="method"/>.</param> /// <returns>Flag indicating whether a speculative semantic model was created.</returns> /// <exception cref="ArgumentException">Throws this exception if the <paramref name="method"/> node is contained any SyntaxTree in the current Compilation</exception> /// <exception cref="ArgumentNullException">Throws this exception if <paramref name="method"/> is null.</exception> /// <exception cref="InvalidOperationException">Throws this exception if this model is a speculative semantic model, i.e. <see cref="SemanticModel.IsSpeculativeSemanticModel"/> is true. /// Chaining of speculative semantic model is not supported.</exception> public bool TryGetSpeculativeSemanticModelForMethodBody(int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel) { CheckModelAndSyntaxNodeToSpeculate(method); return TryGetSpeculativeSemanticModelForMethodBodyCore((SyntaxTreeSemanticModel)this, position, method, out speculativeModel); }
private TypeSyntax GetReturnType(BaseMethodDeclarationSyntax method) { if (method is MethodDeclarationSyntax) { return ((MethodDeclarationSyntax)method).ReturnType; } else if (method is OperatorDeclarationSyntax) { return ((OperatorDeclarationSyntax)method).ReturnType; } // TODO(DustinCa): What about conversion operators? How does the legacy code base handle those? return null; }
internal abstract bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel);
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, BaseMethodDeclarationSyntax method, out SemanticModel speculativeModel) { // CONSIDER: Do we want to ensure that speculated method and the original method have identical signatures? return GetSpeculativeSemanticModelForMethodBody(parentModel, position, method.Body, out speculativeModel); }
/// <summary> /// Given a base method declaration syntax, get the corresponding method symbol. /// </summary> /// <param name="declarationSyntax">The syntax node that declares a method.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The symbol that was declared.</returns> /// <remarks> /// NOTE: We have no GetDeclaredSymbol overloads for subtypes of BaseMethodDeclarationSyntax as all of them return a MethodSymbol. /// </remarks> public abstract IMethodSymbol GetDeclaredSymbol(BaseMethodDeclarationSyntax declarationSyntax, CancellationToken cancellationToken = default(CancellationToken));