public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var classNode = (ClassDeclarationSyntax) node; if (classNode.BaseListOpt == null) return null; var walker = new MilSyntaxWalker(); walker.Visit((SyntaxNode) document.GetSyntaxTree(cancellationToken).Root); var allCommandHandlersInProject = walker.CommandHandlers; if (!allCommandHandlersInProject.Any() && !allCommandHandlersInProject.Contains(node)) return null; var dupes = walker.CommandHandlers.SelectMany(x => x.BaseListOpt.Types).FindDuplicates(); if (!dupes.Any()) { var desc = "{0} is implemented by multiple handlers:{1}{2}"; var issues = new List<CodeIssue>(); foreach (var dupe in dupes) { var listing = FormatHandlerListing(dupe.GetClassName(), allCommandHandlersInProject.ToDictionary(x => x, syntax => syntax.BaseListOpt.Types.OfType<GenericNameSyntax>())); var text = string.Format(desc, dupe, Environment.NewLine, string.Join(Environment.NewLine, listing)); issues.Add(new CodeIssue(CodeIssue.Severity.Warning, classNode.Identifier.FullSpan, text)); } return issues; } return null; //if (allCommandHandlersInProject.Contains(node as ClassDeclarationSyntax)) //{ // return new CodeIssue[] { new CodeIssue(CodeIssue.Severity.Warning, node.FullSpan, "Command Handler detected") }; //} }
public FixSpellingCodeAction(IDocument document, CommonSyntaxNode syntaxNode, string oldIdentifier, string newIdentifier) { this.Document = document; this.Node = syntaxNode; this.OldIdentifier = oldIdentifier; this.NewIdentifier = newIdentifier; }
public IList<DeclaredItemDocument> DoVisit(ISemanticModel model, CommonSyntaxNode node) { this.model = model as SemanticModel; this.declaredItems = new List<DeclaredItemDocument>(); Visit(node as SyntaxNode); return this.declaredItems; }
public IEnumerable <SyntaxClassification> ClassifyNode(IDocument document, CommonSyntaxNode syntax, CancellationToken cancellationToken) { // If this node is a field declaration, return syntax classifications for the // identifier token of each field name. // // For example, "x" and "y" would be classified in the following code: // // class C // { // int x, y; // } if (syntax is FieldDeclarationSyntax) { var field = (FieldDeclarationSyntax)syntax; return(from v in field.Declaration.Variables select new SyntaxClassification(v.Identifier.Span, fieldClassification)); } // If this node is an identifier, use the binding API to retrieve its symbol and return a // syntax classification for the node if that symbol is a field. if (syntax is IdentifierNameSyntax) { var semanticModel = document.GetSemanticModel(cancellationToken); var symbol = semanticModel.GetSemanticInfo(syntax).Symbol; if (symbol != null && symbol.Kind == CommonSymbolKind.Field) { return(new[] { new SyntaxClassification(syntax.Span, fieldClassification) }); } } return(null); }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var solution = document.Project.Solution; var newExpression = node as ObjectCreationExpressionSyntax; var initializer = newExpression.Initializer; var types = newExpression.Type; var name = types.ToString(); var symbols = solution.FindSymbols(name).ToList(); yield break; // foreach (var token in tokens) // { // var tokenText = token.ToString(); // // if (tokenText.Contains("new")) // { // var issueDescription = string.Format("'{0}' contains the letter 'a'", tokenText); // yield return new CodeIssue(CodeIssueKind.Warning, token.Span, issueDescription); // } // } }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { LoadKnownPure(); var methodCall = node as InvocationExpressionSyntax;//Must be method call Debug.Assert(methodCall != null); if (!(methodCall.Parent is ExpressionStatementSyntax))//Method call must be the outermost in a statement yield break; var semanticModel = document.GetSemanticModel(); var symbol = semanticModel.GetSemanticInfo(methodCall.Expression).Symbol as IMethodSymbol; if (symbol == null)//Symbol for method unavailable yield break; if (knownPureFunctions.Contains(GetMethodNameCecilStyle(symbol)) || symbol.GetAttributes().Any(attr => attr.AttributeClass.Name == "PureAttribute")) { var issueDescription = string.Format("Call to pure method '{0}' used as a statement.", symbol); yield return new CodeIssue(CodeIssue.Severity.Warning, methodCall.Span, issueDescription); } var typeSymbol = symbol.ContainingType; if (typeSymbol.GetAttributes().Any(attr => attr.AttributeClass.Name == "PureAttribute")) { var issueDescription = string.Format("Call to method '{0}' on pure type '{1}' used as a statement.", symbol.Name, typeSymbol); yield return new CodeIssue(CodeIssue.Severity.Warning, methodCall.Span, issueDescription); } }
internal SyntaxTransporter(CommonSyntaxNode node) { if (node is CSharp.SyntaxNode) { SourceLanguage = LanguageNames.CSharp; } else { SourceLanguage = LanguageNames.VisualBasic; } SyntaxStream = new MemoryStream(); var rootNode = GetRootNode(node); if (rootNode != null) { if (SourceLanguage == LanguageNames.CSharp) { var csharpRootNode = (CSharp.SyntaxNode)rootNode; csharpRootNode.SerializeTo(SyntaxStream); } else { var vbRootNode = (VisualBasic.SyntaxNode)rootNode; vbRootNode.SerializeTo(SyntaxStream); } } ItemSpan = node.Span; ItemKind = node.GetKind(SourceLanguage); ItemCategory = SyntaxCategory.SyntaxNode; }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var declaration = node as VariableDeclarationSyntax; var loop = node as ForEachStatementSyntax; var model = document.GetSemanticModel(); var assume = Assumptions.All; if (declaration != null) { foreach (var r in GetSimplifications(declaration, model, assume, cancellationToken)) { yield return new CodeIssue( CodeIssue.Severity.Warning, r.SuggestedSpan ?? declaration.Type.Span, "Type of local variable can be infered.", new[] { r.AsCodeAction(document) }); } } else if (loop != null) { foreach (var r in GetSimplifications(loop, model, assume, cancellationToken)) { yield return new CodeIssue( CodeIssue.Severity.Warning, r.SuggestedSpan ?? loop.Type.Span, "Type of loop variable can be infered.", new[] { r.AsCodeAction(document) }); } } }
private SpellingIssue IdentifyIssues(string word, IDocument document, SyntaxToken identifier, CommonSyntaxNode node, ParallelLoopState state, SpellingIssue dummy) { bool found = WordLookupService.SearchExact(word.ToLower()); if (found) return (SpellingIssue)null; var suggestions = WordLookupService.Search(word.ToLower()) .Select(m => char.IsUpper(identifier.ValueText[0]) ? (char.ToUpper(m[0]) + m.Substring(1)) : m) .ToList(); var actions = new List<ICodeAction>(); foreach (var suggestion in suggestions) { actions.Add(new FixSpellingCodeAction(document, node, identifier.ValueText, identifier.ValueText.Replace(word, suggestion))); } var spanStart = identifier.Span.Start + identifier.ValueText.IndexOf(word, StringComparison.InvariantCultureIgnoreCase); var span = new TextSpan(spanStart, word.Length); return new SpellingIssue(span, word, actions); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var parameterSyntax = (ParameterSyntax)node; var parentMethodBody = parameterSyntax.GetParentMethodBody(); if (parentMethodBody == null) // abstract/interface/extern yield break; var model = document.GetSemanticModel(cancellationToken); var parentMethod = parameterSyntax.Parent.Parent as BaseMethodDeclarationSyntax; if (parentMethod != null && parentMethod.SignatureIsRequiredToSatisfyExternalDependency(document, cancellationToken)) yield break; var dataFlow = model.AnalyzeDataFlow(parentMethodBody); if (!dataFlow.Succeeded) yield break; var parameterSymbol = model.GetDeclaredSymbol(node, cancellationToken); bool isUsed = dataFlow.ReadInside.Contains(parameterSymbol) || dataFlow.WrittenInside.Contains(parameterSymbol); if (!isUsed) yield return new CodeIssue(CodeIssueKind.Unnecessary, node.Span, string.Format("{0} is not used.", parameterSymbol.Name)); }
public Issue( ErrorCode errorCode, CommonSyntaxNode syntaxNode, ISymbol symbol) { #region Input validtion if (!Enum.IsDefined(typeof(ErrorCode), errorCode)) { throw new ArgumentException("errorCode is not defined.", "errorCode"); } if (syntaxNode == null) { throw new ArgumentNullException("syntaxNode"); } if (symbol == null) { throw new ArgumentNullException("symbol"); } #endregion _errorCode = errorCode; _description = DescriptionResolver.GetDescription(errorCode); _syntaxNode = syntaxNode; _symbol = symbol; _location = syntaxNode.GetLocation(); _sourceLineNumber = GetSourceLineNumber(); _sourceLineText = GetSourceLineText(_sourceLineNumber); _sourceFileName = GetSourceFileName(); }
protected override bool TryInitializeExplicitInterfaceState( IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken, out CommonSyntaxToken identifierToken, out IPropertySymbol propertySymbol, out INamedTypeSymbol typeToGenerateIn) { var propertyDeclaration = (PropertyDeclarationSyntax)node; identifierToken = propertyDeclaration.Identifier; if (propertyDeclaration.ExplicitInterfaceSpecifier != null) { var semanticModel = document.GetSemanticModel(cancellationToken); propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken) as IPropertySymbol; if (propertySymbol != null && !propertySymbol.ExplicitInterfaceImplementations.Any()) { var info = semanticModel.GetTypeInfo(propertyDeclaration.ExplicitInterfaceSpecifier.Name, cancellationToken); typeToGenerateIn = info.Type as INamedTypeSymbol; return(typeToGenerateIn != null); } } identifierToken = default(CommonSyntaxToken); propertySymbol = null; typeToGenerateIn = null; return(false); }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { LoadKnownPure(); var methodCall = node as InvocationExpressionSyntax; //Must be method call Debug.Assert(methodCall != null); if (!(methodCall.Parent is ExpressionStatementSyntax)) //Method call must be the outermost in a statement { yield break; } var semanticModel = document.GetSemanticModel(); var symbol = semanticModel.GetSemanticInfo(methodCall.Expression).Symbol as IMethodSymbol; if (symbol == null) //Symbol for method unavailable { yield break; } if (knownPureFunctions.Contains(GetMethodNameCecilStyle(symbol)) || symbol.GetAttributes().Any(attr => attr.AttributeClass.Name == "PureAttribute")) { var issueDescription = string.Format("Call to pure method '{0}' used as a statement.", symbol); yield return(new CodeIssue(CodeIssue.Severity.Warning, methodCall.Span, issueDescription)); } var typeSymbol = symbol.ContainingType; if (typeSymbol.GetAttributes().Any(attr => attr.AttributeClass.Name == "PureAttribute")) { var issueDescription = string.Format("Call to method '{0}' on pure type '{1}' used as a statement.", symbol.Name, typeSymbol); yield return(new CodeIssue(CodeIssue.Severity.Warning, methodCall.Span, issueDescription)); } }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken = new CancellationToken()) { var variable = node as VariableDeclarationSyntax; if (variable != null) { var nodes = variable.ChildNodes().Where(x => x.Kind == SyntaxKind.VariableDeclarator); foreach (var syntaxNode in nodes) { var fullVariableName = syntaxNode.GetFirstToken().ValueText; var wordsInVariableName = fullVariableName.SplitToWords(); if (wordsInVariableName != null) { var correctSpelling = CheckAndCorrectSpelling(wordsInVariableName); if (correctSpelling != null) { yield return(new CodeIssue(CodeIssue.Severity.Info, syntaxNode.GetFirstToken().Span, "Possible Typo ?\nMaybe you meant : " + correctSpelling)); } } } } }
public IEnumerable<SyntaxClassification> ClassifyNode(IDocument document, CommonSyntaxNode syntax, CancellationToken cancellationToken) { // If this node is a field declaration, return syntax classifications for the // identifier token of each field name. // // For example, "x" and "y" would be classified in the following code: // // class C // { // int x, y; // } if (syntax is FieldDeclarationSyntax) { var field = (FieldDeclarationSyntax)syntax; return from v in field.Declaration.Variables select new SyntaxClassification(v.Identifier.Span, fieldClassification); } // If this node is an identifier, use the binding API to retrieve its symbol and return a // syntax classification for the node if that symbol is a field. if (syntax is IdentifierNameSyntax) { var semanticModel = document.GetSemanticModel(cancellationToken); var symbol = semanticModel.GetSemanticInfo(syntax).Symbol; if (symbol != null && symbol.Kind == CommonSymbolKind.Field) { return new[] { new SyntaxClassification(syntax.Span, fieldClassification) }; } } return null; }
private SpellingIssue IdentifyIssues(string word, IDocument document, SyntaxToken identifier, CommonSyntaxNode node, ParallelLoopState state, SpellingIssue dummy) { bool found = WordLookupService.SearchExact(word.ToLower()); if (found) { return((SpellingIssue)null); } var suggestions = WordLookupService.Search(word.ToLower()) .Select(m => char.IsUpper(identifier.ValueText[0]) ? (char.ToUpper(m[0]) + m.Substring(1)) : m) .ToList(); var actions = new List <ICodeAction>(); foreach (var suggestion in suggestions) { actions.Add(new FixSpellingCodeAction(document, node, identifier.ValueText, identifier.ValueText.Replace(word, suggestion))); } var spanStart = identifier.Span.Start + identifier.ValueText.IndexOf(word, StringComparison.InvariantCultureIgnoreCase); var span = new TextSpan(spanStart, word.Length); return(new SpellingIssue(span, word, actions)); }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { ExpressionStatementSyntax expressionStatement; PostfixUnaryExpressionSyntax postFixExpression; PrefixUnaryExpressionSyntax prefixExpression; ISymbol mutatedSymbol; if ((expressionStatement = node as ExpressionStatementSyntax) != null) { mutatedSymbol = GetMutatedSymbol(document, cancellationToken, expressionStatement); } else if ((postFixExpression = node as PostfixUnaryExpressionSyntax) != null) { mutatedSymbol = GetMutatedSymbol(document, cancellationToken, postFixExpression); } else if ((prefixExpression = node as PrefixUnaryExpressionSyntax) != null) { mutatedSymbol = GetMutatedSymbol(document, cancellationToken, prefixExpression); } else { throw new ArgumentException("Unhandled node type."); } if (mutatedSymbol != null && mutatedSymbol.Kind == CommonSymbolKind.Parameter && ((ParameterSymbol)mutatedSymbol).RefKind == RefKind.None) { yield return(new CodeIssue(CodeIssueKind.Warning, node.Span, "Do not mutate the values of parameters.")); } }
public IList <DeclaredItemDocument> DoVisit(ISemanticModel model, CommonSyntaxNode node) { this.model = model as SemanticModel; this.declaredItems = new List <DeclaredItemDocument>(); Visit(node as SyntaxNode); return(this.declaredItems); }
/// <summary> /// Gets a document location from a tree node. /// </summary> /// <param name="tree">The tree.</param> /// <param name="node">The node.</param> /// <returns>A new document location.</returns> internal static DocumentLocation FromTreeNode(CommonSyntaxTree tree, CommonSyntaxNode node) { if (tree == null || node == null) return Default; return FromSpan(tree.GetLineSpan(node.Span, true)); }
public override Task <ConflictInfoCollection> GetDataAsync() { // TFS binaries not loaded. Hasty exit. if (!this.EditingSession.SCCServiceReady) { return(null); } CommonSyntaxNode syntaxNode = this.MethodIdentifier.SyntaxNode; this.MethodIdentifier.SyntaxNodeChanged += this.OnSyntaxNodeChanged; return(this.Run <ConflictInfoCollection>(token => { return Task.Run <ConflictInfoCollection>(() => { IEnumerable <ConflictInfo> conflicts = this.EditingSession.GetConflicts(); if (conflicts != null) { // Get the conflicts that intersect with this method. FileLinePositionSpan syntaxNodeFileLineSpan = syntaxNode.SyntaxTree.GetLineSpan(syntaxNode.FullSpan, false); Span syntaxNodeLineSpan = new Span(syntaxNodeFileLineSpan.StartLinePosition.Line, syntaxNodeFileLineSpan.EndLinePosition.Line - syntaxNodeFileLineSpan.StartLinePosition.Line); IEnumerable <ConflictInfo> conflictsWithinNode = conflicts.Where(c => c.IntersectsWith(syntaxNodeLineSpan)); if (conflictsWithinNode.Any()) { return new ConflictInfoCollection(conflictsWithinNode, this.EditingSession.LatestVersion); } } return null; }); })); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var solution = document.Project.Solution; var newExpression = node as ObjectCreationExpressionSyntax; var initializer = newExpression.Initializer; var types = newExpression.Type; var name = types.ToString(); var symbols = solution.FindSymbols(name).ToList(); yield break; // foreach (var token in tokens) // { // var tokenText = token.ToString(); // // if (tokenText.Contains("new")) // { // var issueDescription = string.Format("'{0}' contains the letter 'a'", tokenText); // yield return new CodeIssue(CodeIssueKind.Warning, token.Span, issueDescription); // } // } }
private static SyntaxToken[] GetIdentifiers(CommonSyntaxNode node) { VariableDeclaratorSyntax variableDeclarator; // includes fields BaseTypeDeclarationSyntax typeDeclaration; MethodDeclarationSyntax methodDeclaration; NamespaceDeclarationSyntax namespaceDeclaration; EnumMemberDeclarationSyntax enumMemberDeclaration; PropertyDeclarationSyntax propertyDeclaration; EventDeclarationSyntax eventDeclaration; ParameterSyntax parameterSyntax; SyntaxToken[] identifiers; if ((variableDeclarator = node as VariableDeclaratorSyntax) != null) { identifiers = new[] { variableDeclarator.Identifier } } ; else if ((parameterSyntax = node as ParameterSyntax) != null) { identifiers = new[] { parameterSyntax.Identifier } } ; else if ((propertyDeclaration = node as PropertyDeclarationSyntax) != null) { identifiers = new[] { propertyDeclaration.Identifier } } ; else if ((typeDeclaration = node as BaseTypeDeclarationSyntax) != null) { identifiers = new[] { typeDeclaration.Identifier } } ; else if ((methodDeclaration = node as MethodDeclarationSyntax) != null) { identifiers = new[] { methodDeclaration.Identifier } } ; else if ((enumMemberDeclaration = node as EnumMemberDeclarationSyntax) != null) { identifiers = new[] { enumMemberDeclaration.Identifier } } ; else if ((eventDeclaration = node as EventDeclarationSyntax) != null) { identifiers = new[] { eventDeclaration.Identifier } } ; else if ((namespaceDeclaration = node as NamespaceDeclarationSyntax) != null) { identifiers = namespaceDeclaration.Name.ChildNodes().OfType <IdentifierNameSyntax>() .Select(i => i.Identifier).ToArray(); } else { throw new ArgumentException("Unhandled node."); } return(identifiers); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { initialize(document); // Add the new record to the history component. GhostFactorComponents.historyComponent.UpdateActiveDocument(document); return GhostFactorComponents.RefactoringCodeIssueComputerComponent.GetCodeIssues(document, (SyntaxNode) node); }
internal void DoVisit(ISemanticModel semanticModel, CommonSyntaxNode token, TokenParameter parameter, TokenKind searchTokenKind, Action <int> symbolFoundDelegate) { this.semanticModel = semanticModel; this.symbolFoundDelegate = symbolFoundDelegate; this.parameter = parameter; this.searchTokenKind = searchTokenKind; Visit(token); }
internal void DoVisit(ISemanticModel semanticModel, CommonSyntaxNode token, TokenParameter parameter, TokenKind searchTokenKind, Action<int> symbolFoundDelegate) { this.semanticModel = semanticModel as SemanticModel; this.symbolFoundDelegate = symbolFoundDelegate; this.parameter = parameter; this.searchTokenKind = searchTokenKind; Visit(token as SyntaxNode); }
// explicit interface implementation void ISyntaxValidator.Validate(CommonSyntaxNode node, CommonSyntaxTree tree, CompilationResult result) { _currentTree = tree; _currentNode = node; _currentResult = result; Validate(node as T, tree, result); }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var model = document.GetSemanticModel(cancellationToken); var symbol = (MethodSymbol)model.GetDeclaredSymbol(node, cancellationToken); if (symbol.MethodKind == MethodKind.StaticConstructor) { yield break; } var entryPoint = model.Compilation.GetEntryPoint(cancellationToken); if (symbol.Equals(entryPoint)) { yield break; } var callers = symbol.FindCallers(document.Project.Solution, cancellationToken); if (callers.Any()) { yield break; } var interfaceMembers = symbol.FindImplementedInterfaceMembers(document.Project.Solution, cancellationToken); if (interfaceMembers.Any(im => !im.IsDeclaredInSource() || im.IsExternallyVisible())) { yield break; } var implementations = interfaceMembers.SelectMany(im => im.FindImplementations(document.Project.Solution, cancellationToken)); if (implementations.Any(impl => impl.IsExternallyVisible())) { yield break; } if (symbol.FindImplementations(document.Project.Solution, cancellationToken).Any(impl => impl.IsExternallyVisible())) { yield break; } if (symbol.IsExternallyVisible()) { yield break; } if (symbol.OverriddenMethod != null && (!symbol.OverriddenMethod.IsDeclaredInSource() || symbol.OverriddenMethod.IsExternallyVisible())) { yield break; } yield return(new CodeIssue(CodeIssueKind.Unnecessary, node.Span, string.Format("{0} is never called.", symbol.Name), new RemoveMethodCodeAction(document, (BaseMethodDeclarationSyntax)node))); }
private void TraverseThroughAllTheProjectFiles(TokenParameter parameter, IFindReferenceProgress findReferenceProgressListener, Func <string, string, ISemanticModel, CommonSyntaxNode, bool> visitorAction) { findReferenceProgressListener.OnFindReferenceStarted(); var projectCodeDirectory = new DirectoryInfo(this.applicationConfigurationProvider.GetProjectSourceCodePath(parameter.Username, parameter.Project)); var solutionPath = FindSolutionPath(parameter.Username, parameter.Project); if (solutionPath == null) { findReferenceProgressListener.OnFindReferenceCompleted(0); return; } findReferenceProgressListener.OnFindReferenceInProgress(); var workspace = Roslyn.Services.Workspace.LoadSolution(solutionPath); var currentFilePath = Path.Combine(projectCodeDirectory.FullName, parameter.Path.Replace(@"/", @"\")); var solution = workspace.CurrentSolution; foreach (var project in solution.Projects) { try { bool processingCompleted = false; if (!project.HasDocuments) { continue; } foreach (var document in project.Documents) { var documentSemanticModel = document.GetSemanticModel(); var findReferenceSyntaxtWalker = new FindReferenceSyntaxWalker(); CommonSyntaxNode syntaxRoot = null; if (documentSemanticModel.SyntaxTree.TryGetRoot(out syntaxRoot)) { var documentRelativePath = new Uri(projectCodeDirectory.FullName + Path.DirectorySeparatorChar).MakeRelativeUri(new Uri(document.FilePath)).ToString(); processingCompleted = visitorAction(document.Name, documentRelativePath, documentSemanticModel, syntaxRoot); if (processingCompleted) { break; } } } if (processingCompleted) { break; } } catch (Exception ex) { this.logger.Error(ex, "An error has occured while loading the project {0}", project.Name); } } }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var methodNode = (MethodDeclarationSyntax)node; if (methodNode.Attributes != null) { var model = document.GetSemanticModel(); var operationContractType = typeof(OperationContractAttribute); var operationSyntax = ( from attribute in methodNode.Attributes from syntax in attribute.Attributes let attributeType = model.GetTypeInfo(syntax).Type where attributeType != null && attributeType.Name == operationContractType.Name && attributeType.ContainingAssembly.Name == operationContractType.Assembly.GetName().Name from argument in syntax.ArgumentList.Arguments where ( argument.NameEquals.Identifier.GetText() == "IsOneWay" && argument.Expression.Kind == SyntaxKind.TrueLiteralExpression) select new { syntax, argument }).FirstOrDefault(); if (operationSyntax != null) { var returnType = model.GetTypeInfo(methodNode.ReturnType).Type; if (returnType != null && returnType.SpecialType != SpecialType.System_Void) { return(new[] { new CodeIssue(CodeIssue.Severity.Error, methodNode.ReturnType.Span, "One-way WCF operations must return System.Void.", new ICodeAction[] { new OneWayOperationReturnVoidCodeAction( document, methodNode.ReturnType), new OneWayOperationMakeIsOneWayFalseCodeAction( document, operationSyntax.argument) }) }); } } } return(null); }
/// <summary> /// Gets a document location from a tree node. /// </summary> /// <param name="tree">The tree.</param> /// <param name="node">The node.</param> /// <returns>A new document location.</returns> internal static DocumentLocation FromTreeNode(CommonSyntaxTree tree, CommonSyntaxNode node) { if (tree == null || node == null) { return(Default); } return(FromSpan(tree.GetLineSpan(node.Span, true))); }
public override void Visit(CommonSyntaxNode node) { var validator = _provider.ResolveImport(node.GetType()); if (validator != null) validator.Validate(node, CurrentTree, _result); base.Visit(node); }
public MyCodeAction(ICodeActionEditFactory editFactory, IDocument document, CommonSyntaxNode node) { _editFactory = editFactory; _document = document; _node = node; Description = "Replace 'a' with 'b'"; Icon = null; }
public AddThrowCodeAction(CodeActionEdit editFactory, IDocument document, CommonSyntaxNode node) { _editFactory = editFactory; _document = document; _node = (CatchClauseSyntax)node; Description = "please throw the exception if you can't handle it"; Icon = null; }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var statement = (IfStatementSyntax)node; var model = document.GetSemanticModel(); var newStatement = statement.DropEmptyBranchesIfApplicable(Assumptions.All, model); if (newStatement == statement) return null; var r = new ReadyCodeAction("Omit useless code", document, statement, () => newStatement); return r.CodeIssues1(CodeIssue.Severity.Warning, statement.IfKeyword.Span, "Useless branch"); }
public override void Visit(CommonSyntaxNode node) { var validator = _provider.ResolveImport(node.GetType()); if (validator != null) { validator.Validate(node, CurrentTree, _result); } base.Visit(node); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var forLoop = (ForEachStatementSyntax)node; var model = document.GetSemanticModel(); var simplifications = GetSimplifications(forLoop, model, Assumptions.All, cancellationToken); return simplifications.Select(e => new CodeIssue( CodeIssue.Severity.Warning, forLoop.ForEachKeyword.Span, "Single execution of 'for each' loop body is sufficient.", new[] { e.AsCodeAction(document) })); }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var methodNode = (MethodDeclarationSyntax)node; // Code Complexity var nodes = methodNode.DescendantNodes(); var totalCount = nodes.Count(); var switchSectionCount = nodes.OfType <SwitchSectionSyntax>().Count(); var loopCount = (nodes.OfType <ForEachStatementSyntax>().Count() + nodes.OfType <WhileStatementSyntax>().Count() + nodes.OfType <ForStatementSyntax>().Count()); var ifCount = nodes.OfType <IfStatementSyntax>().Count(); var elseifCount = nodes.OfType <ElseClauseSyntax>() .Where(x => typeof(IfStatementSyntax).IsAssignableFrom(x.Statement.GetType())) .Count(); var switchBranchs = switchSectionCount; var loopBranchs = loopCount * 2; var conditionalBranchs = ifCount * 2 - elseifCount; var complexity = switchBranchs + loopBranchs + conditionalBranchs; var message = string.Format("{0} complexity: {1} switch branchs, {2} for/foreach/while branchs, {3} if/else branchs, {4} total nodes", complexity, switchBranchs, loopBranchs, conditionalBranchs, totalCount); if (complexity < 10) { yield return(new CodeIssue(CodeIssueKind.Info, methodNode.Identifier.Span, message)); } else { yield return(new CodeIssue(CodeIssueKind.Warning, methodNode.Identifier.Span, message)); } // Code Length var methodLineSpan = methodNode.SyntaxTree.GetLineSpan(methodNode.Body.Span, true); var startLine = methodLineSpan.StartLinePosition.Line + 1; var endLine = methodLineSpan.EndLinePosition.Line + 1; var numberOfLines = endLine - startLine + 1; var msg = string.Format("Line {0} to line {1}: {2} total lines", startLine, endLine, numberOfLines); if (numberOfLines < 30) { yield return(new CodeIssue(CodeIssueKind.Info, methodNode.Identifier.Span, msg)); } else { yield return(new CodeIssue(CodeIssueKind.Warning, methodNode.Identifier.Span, msg)); } }
// If lazy is true then treeview items are populated on-demand. In other words, when lazy is true // the children for any given item are only populated when the item is selected. If lazy is // false then the entire tree is populated at once (and this can result in bad performance when // displaying large trees). public void DisplaySyntaxNode(CommonSyntaxNode node, string language, bool lazy = true) { if (node != null && !string.IsNullOrEmpty(language)) { SourceLanguage = language; IsLazy = lazy; SyntaxTree = node.SyntaxTree; AddNode(null, node); legendButton.Visibility = Visibility.Visible; } }
public static IEnumerable <CommonSyntaxNodeOrToken> Resolve(CommonSyntaxNode root, SyntaxAnnotation annotation) { Contract.ThrowIfNull(root); Contract.ThrowIfNull(annotation); var result = new List <CommonSyntaxNodeOrToken>(); var resolver = new NodeOrTokenResolver(annotation); resolver.Visit(root, result); return(result); }
public override void Visit(CommonSyntaxNode node, List <CommonSyntaxTrivia> results) { // if it doesnt have annotations, don't even bother to go in. var baseNode = (IBaseSyntaxNodeExt)node; if (!baseNode.HasAnnotations) { return; } base.Visit(node, results); }
public CodeRefactoring GetRefactoring(IDocument document, TextSpan textSpan, CancellationToken cancellationToken) { string newName = "newVariableName"; SyntaxNode root = (SyntaxNode)document.GetSyntaxRoot(cancellationToken); SyntaxToken token = root.FindToken(textSpan.Start, findInsideTrivia: true); // Verify is the selected token an identifier if (token.Kind == SyntaxKind.IdentifierToken && token.Span.Start <= textSpan.End && textSpan.End <= token.Span.End) { ISemanticModel model = document.GetSemanticModel(cancellationToken); ISymbol symbol = null; CommonSyntaxNode parentNode = token.Parent; // Local variable node-reference can be either IdentifierName node or VariableDeclarator node if (parentNode is IdentifierNameSyntax) { CommonSymbolInfo symbolInfo = model.GetSymbolInfo(parentNode, cancellationToken); symbol = symbolInfo.Symbol; } else if (parentNode is VariableDeclaratorSyntax) { symbol = model.GetDeclaredSymbol(parentNode, cancellationToken); } if (symbol == null) { return(null); } // Verify is the symbol of local variable kind if (symbol.Kind != CommonSymbolKind.Local) { return(null); } // Verify is there any other local variable of the same name IList <ISymbol> visibleSymbols = model.LookupSymbols(token.Span.Start, name: newName, container: symbol.ContainingType); bool isNameReserved = visibleSymbols .Any(otherSymbol => (otherSymbol.Kind == CommonSymbolKind.Local || otherSymbol.Kind == CommonSymbolKind.Parameter) && !otherSymbol.Equals(symbol)); if (!isNameReserved) { return(new CodeRefactoring( new[] { new RenameLocalAction(document, token, symbol, newName) }, token.Span)); } } return(null); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var invocation = (InvocationExpressionSyntax)node; var model = document.GetSemanticModel(); var simplifications = GetSimplifications(invocation, model, cancellationToken); return simplifications.Select(e => new CodeIssue( CodeIssue.Severity.Warning, invocation.ArgumentList.Span, "Filter can be inlined into fold.", new[] { e.AsCodeAction(document) })); }
public IEnumerable <CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { ISemanticModel model = document.GetSemanticModel(cancellationToken); ObjectCreationExpressionSyntax expression = (ObjectCreationExpressionSyntax)node; // Note: Do NOT use HasDiagnostics, as this expression obviously DOES produce errors (type is not known yet) TypeSyntax typeSyntax = expression.Type; CommonTypeInfo typeInfo = model.GetTypeInfo(typeSyntax, cancellationToken); TypeSymbol typeSymbol = (TypeSymbol)typeInfo.Type; if (typeSymbol == null) { yield break; } // Check if this is an unrecognized symbol if (typeSymbol.Kind == SymbolKind.ErrorType) { string className = string.Empty; // TODO: extract container info and propose solutions // Considers: // new A.B.C() -> namespace A.B { class C {} } // Extract top-level name // Considers: // new A.B.C<int,float>() -> C if (typeSyntax.Kind == SyntaxKind.IdentifierName) { className = typeSyntax.GetText(); } else if (typeSyntax.Kind == SyntaxKind.GenericName) { GenericNameSyntax genericName = (GenericNameSyntax)typeSyntax; className = genericName.Identifier.GetText(); } else if (typeSyntax.Kind == SyntaxKind.QualifiedName) { QualifiedNameSyntax qualifiedName = (QualifiedNameSyntax)typeSyntax; className = qualifiedName.Right.GetText(); } yield return(new CodeIssue(CodeIssue.Severity.Info, expression.Span, String.Format("Generate class `{0}'", className), new GenerateClassFromUsageAction(document, expression, className))); } yield break; }
public void TestNoIssue <T, Node>(String code, TextSpan textSpan) where T : ICodeIssueProvider, new() where Node : CommonSyntaxNode { CreateWorkspace(code); CommonSyntaxNode node = document.GetSyntaxRoot().FindToken(textSpan.Start).Parent.FirstAncestorOrSelf <Node>(); ICodeIssueProvider codeIssueProvider = new T(); IEnumerable <CodeIssue> codeIssues = codeIssueProvider.GetIssues(document, node, cancellationToken); Assert.AreEqual(0, codeIssues.Count()); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { if (node.Kind == (int)SyntaxKind.VariableDeclarator) { var nodeText = node.GetText(); if (nodeText.Contains('a')) { var issueDescription = string.Format("'{0}' contains the letter 'a'", nodeText); yield return new CodeIssue(CodeIssue.Severity.Warning, node.Span, issueDescription, new MyCodeAction(editFactory, document, node)); } } }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var declaration = (LocalDeclarationStatementSyntax)node; var model = document.GetSemanticModel(); var assume = Assumptions.All; foreach (var r in GetSimplifications(declaration, model, assume, cancellationToken)) { yield return new CodeIssue( CodeIssue.Severity.Warning, r.SuggestedSpan ?? declaration.Declaration.Type.Span, "Scope of local variable can be reduced.", new[] { r.AsCodeAction(document) }); } }
private CommonSyntaxNode FindArgumentListRecursive(CommonSyntaxNode node) { if (node == null) { return(null); } if (node.Kind == GetArgumentListCode()) { return(node); } return(FindArgumentListRecursive(node.Parent)); }
// If lazy is true then treeview items are populated on-demand. In other words, when lazy is true // the children for any given item are only populated when the item is selected. If lazy is // false then the entire tree is populated at once (and this can result in bad performance when // displaying large trees). public void DisplaySyntaxNode(CommonSyntaxNode node, string language, bool lazy = true) { if (node != null && !string.IsNullOrEmpty(language)) { SourceLanguage = language; IsLazy = lazy; SyntaxTree = node.SyntaxTree; AddNode(root, node); if (SyntaxTreeLoaded != null && node != null) { SyntaxTreeLoaded(this, new SyntaxLoadedArgs(node)); } } }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var ifStatement = node as IfStatementSyntax; if (ifStatement == null || ifStatement.Else != null) return null; var trueBlock = ifStatement.Statement as BlockSyntax; if (trueBlock == null) return null; if (trueBlock.Statements.Count != 1) return null; if (!trueBlock.IsGuaranteedToJumpOut()) return null; var r = new ReadyCodeAction("Remove unnecessary braces", document, trueBlock, () => trueBlock.Statements.Single()); return new[] { new CodeIssue(CodeIssue.Severity.Warning, trueBlock.OpenBraceToken.Span, "Unnecessary braces", new[] { r }) }; }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var typeSyntax = (TypeSyntax)node; if (!typeSyntax.IsVar) yield break; ISemanticModel semanticModel = document.GetSemanticModel(); ITypeSymbol variableType = semanticModel.GetSemanticInfo(typeSyntax).Type; if (variableType is ErrorTypeSymbol) yield break; yield return new CodeIssue(CodeIssue.Severity.Info, typeSyntax.Span, new ICodeAction[] { new ReplaceVarByConcreteAction(editFactory, document, typeSyntax) }); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var typedNode = (ClassDeclarationSyntax) node; if (!typedNode.BaseList.Types.Any(x => x.GetFirstToken().ValueText == "ApiController")) yield break; var methods = typedNode.Members.OfType<MethodDeclarationSyntax>(). Where(x => (x.Identifier.ValueText.StartsWith("Post") || x.AttributeLists.Any(a => a.Attributes.Any(s => s.Name.ToString() == "HttpPost"))) && x.ReturnType.GetType().IsAssignableFrom(typeof(PredefinedTypeSyntax)) && ((PredefinedTypeSyntax)x.ReturnType).Keyword.Kind == SyntaxKind.VoidKeyword); foreach (var method in methods) { yield return new CodeIssue(CodeIssueKind.Warning, method.ReturnType.Span, "Consider returning a 201 Status Code", new CodeAction(document, method)); } }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var model = document.GetSemanticModel(); var b = (BinaryExpressionSyntax)node; var actions = GetSimplifications(b, model, Assumptions.All, cancellationToken) .Select(e => e.AsCodeAction(document)) .ToArray(); if (actions.Length == 0) yield break; yield return new CodeIssue( CodeIssue.Severity.Warning, b.OperatorToken.Span, "Boolean operation can be simplified.", actions); }
private CommonSyntaxNode GetRootNode(CommonSyntaxToken token) { CommonSyntaxNode rootNode = null; if (token.SyntaxTree != null) { rootNode = token.SyntaxTree.GetRoot(); } else { rootNode = GetRootNode(token.Parent); } return(rootNode); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var model = document.GetSemanticModel(); var ternaryNode = (ConditionalExpressionSyntax)node; var actions = GetSimplifications(ternaryNode, model, Assumptions.All, cancellationToken) .Select(e => e.AsCodeAction(document)) .ToArray(); if (actions.Length == 0) yield break; yield return new CodeIssue( CodeIssue.Severity.Warning, ternaryNode.QuestionToken.Span, "Conditional expression simplifies into boolean expression.", actions); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { CommonSyntaxTree syntaxTree = document.GetSyntaxTree(); SemanticModel semanticModel = (SemanticModel) document.GetSemanticModel(); AnalysisResult result = _engine.Analyze(syntaxTree, semanticModel); if (!result.Success) { foreach (Issue issue in result.Issues) { yield return new CodeIssue(CodeIssueKind.Error, issue.SyntaxNode.Span, issue.Description); } } }
public static string GetKind(this CommonSyntaxNode node, string language) { var kind = string.Empty; if (language == LanguageNames.CSharp) { kind = ((CSharp.SyntaxKind)node.Kind).ToString(); } else { kind = ((VisualBasic.SyntaxKind)node.Kind).ToString(); } return(kind); }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var assume = Assumptions.All; var c = (StatementSyntax)node; if (!(c.Parent is BlockSyntax)) { if (c is EmptyStatementSyntax) return null; if (c is BlockSyntax && c.Statements().None()) return null; } if (c.HasSideEffects(document.TryGetSemanticModel(), assume) != false) return null; return new[] { new CodeIssue(CodeIssue.Severity.Warning, c.Span, "Statement without any effect", new[] { new ReadyCodeAction( "Remove Unnecessary Statement", document, c, () => c.Parent is BlockSyntax ? null : Syntax.EmptyStatement())})}; }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { editFactory = new CodeActionEdit(document); if (node.Kind == (int)SyntaxKind.CatchClause) { var CatchNode = (Roslyn.Compilers.CSharp.CatchClauseSyntax)node; if (CatchNode.Block.Statements.Count == 0 ) { var issueDescription = "Ouch! Do you really want to leave this CatchBlock empty? "; yield return new CodeIssue(CodeIssueKind.Error, node.Span, issueDescription, new AddThrowCodeAction(editFactory, document, node)); } } }
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken) { var methodDeclaration = (MethodDeclarationSyntax)node; if (methodDeclaration.AttributeLists.Any(a => a.Attributes.Any(at => at.Name.ToString() == "Fact")) && !methodDeclaration.Identifier.ToString().IsUnderscoreCase()) // Not already underscore case { return new[] { new CodeIssue(CodeIssueKind.Warning, methodDeclaration.Identifier.Span, "Convert to underscore_case", new CodeAction(document, methodDeclaration)) }; } return null; }