/// <summary> /// Checks the placement of brackets within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); XmlDocument contents = new XmlDocument(); XmlNode root = contents.CreateElement("StyleCopCsParserObjectModel"); contents.AppendChild(root); CsDocument csdocument = document.AsCsDocument(); this.ProcessCodeUnit(csdocument, root); // Get the location where the output file should be stored. string testOutputDirectory = (string)this.Core.HostTag; if (string.IsNullOrEmpty(testOutputDirectory)) { throw new InvalidOperationException("The HostTag has not been properly set in StyleCopCore."); } // Save the output to the file. string outputFileLocation = Path.Combine( testOutputDirectory, Path.GetFileNameWithoutExtension(document.SourceCode.Path) + "ObjectModelResults.xml"); contents.Save(outputFileLocation); }
/// <summary> /// Writes the final document back to the source. /// </summary> /// <param name="document">The document to write.</param> /// <param name="exception">Returns an exception if the write operation fails.</param> /// <returns>Returns true if the document was written successfully; false otherwise.</returns> public override bool Write(ICodeDocument document, out Exception exception) { Param.RequireNotNull(document, "document"); exception = null; try { using (StreamWriter writer = new StreamWriter(this.path)) { document.Write(writer); writer.Flush(); } return(true); } catch (UnauthorizedAccessException ex) { exception = ex; } catch (IOException ex) { exception = ex; } return(false); }
/// <summary> /// Checks the methods within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); /* // Get the autoupdate setting. string flag = null; if (document.File.Project.LocalSettings != null) { flag = document.File.Project.LocalSettings.GetProperty("ParamCheckAutomatic"); if (flag == null && document.File.Project.GlobalSettings != null) { flag = document.File.Project.GlobalSettings.GetProperty("ParamCheckAutomatic"); } } this.autoUpdate = (flag != null && flag == "1"); */ // Analyze the document. CsDocument csdocument = (CsDocument)document; if (csdocument.RootElement != null && !csdocument.RootElement.Generated) { this.ProcessElement(csdocument, csdocument.RootElement); } }
/// <summary> /// Checks the order of the elements within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (csdocument != null) { // Get the value of the GeneratedCodeElementOrder property. bool checkGeneratedCode = OrderingRules.GeneratedCodeElementOrderDefaultValueProperty; if (document.Settings != null) { BooleanProperty setting = this.GetSetting(document.Settings, OrderingRules.GeneratedCodeElementOrderProperty) as BooleanProperty; if (setting != null) { checkGeneratedCode = setting.Value; } // Check the rest of the elements. this.ProcessElements(csdocument, checkGeneratedCode); } this.CheckUsingDirectiveOrder(csdocument); } }
/// <summary> /// Runs the analyzers against the given document. /// </summary> /// <param name="document">The document to analyze.</param> /// <param name="parser">The parser that created the document.</param> /// <param name="analyzers">The analyzers to run against the document.</param> /// <param name="passNumber">The current pass number.</param> /// <returns>Returns true if analysis was run, or false if analysis was delayed until the next pass.</returns> private bool TestAndRunAnalyzers( ICodeDocument document, SourceParser parser, IEnumerable <SourceAnalyzer> analyzers, int passNumber) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parser, "parser"); Param.Ignore(analyzers); Param.Ignore(passNumber); if (analyzers == null) { return(true); } // Determine whether any of the analyzers wish to delay parsing until the next pass. bool delay = false; foreach (SourceAnalyzer analyzer in analyzers) { if (!this.data.RunContext.AutoFix) { if (analyzer.DelayAnalysis(document, passNumber)) { delay = true; break; } } } if (!delay) { this.RunAnalyzers(document, parser, analyzers); } return(!delay); }
/// <summary> /// Runs the list of analyzers against the given document. /// </summary> /// <param name="document">The document to analyze.</param> /// <param name="parser">The parser that created the document.</param> /// <param name="analyzers">The list of analyzsers to run against the document.</param> private void RunAnalyzers( ICodeDocument document, SourceParser parser, IEnumerable <SourceAnalyzer> analyzers) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parser, "parser"); Param.Ignore(analyzers, "analyzers"); if (analyzers != null) { if (parser.SkipAnalysisForDocument(document)) { this.data.Core.SignalOutput( MessageImportance.Normal, string.Format(CultureInfo.CurrentCulture, "Skipping {0}...", document.SourceCode.Name)); } else { // Loop through each of the analyzers attached to the parser. foreach (SourceAnalyzer analyzer in analyzers) { // Make sure the user hasn't cancelled us. if (this.data.Core.Cancel) { break; } // Only run the analyzers associated with the current parser. if (analyzer.Parser == parser) { SourceParser.ClearAnalyzerTags(document); try { // Check whether we are running in auto-fix mode, in which case we should call the // AutoFixDocument method on analyzers that support it. Otherwise, we are simply running // the rules and we should call the AnalyzeDocument method instead. if (this.data.RunContext.AutoFix) { analyzer.AutoFixDocument(document); } else { analyzer.AnalyzeDocument(document); } } catch (System.Exception) { string details = string.Format( CultureInfo.CurrentCulture, "Exception thrown by analyzer '{0}' while processing '{1}'.", analyzer.Name, document.SourceCode.Path); this.data.Core.SignalOutput(MessageImportance.High, details); throw; } } } } } }
public NQuerySyntacticClassifier(ICodeDocument document) : base(typeof(NQuerySyntacticClassifier).Name, null, document, true) { _classificationTypes = document.Language.GetService <INQueryClassificationTypes>(); document.ParseDataChanged += DocumentOnParseDataChanged; UpdateTags(); }
/// <summary> /// Occurs when a menu item is clicked. /// </summary> /// <param name="sender">The sender of the event.</param> /// <param name="e">The <see cref="RoutedEventArgs"/> that contains data related to this event.</param> private void OnRemoveNote(object sender, RoutedEventArgs e) { MenuItem item = (MenuItem)sender; // Get the tag range TagSnapshotRange <IntraTextNoteTag> tagRange = (TagSnapshotRange <IntraTextNoteTag>)item.Tag; // Get the tagger from the code document ICodeDocument document = tagRange.SnapshotRange.Snapshot.Document as ICodeDocument; if (document != null) { IntraTextNoteTagger tagger = null; if (document.Properties.TryGetValue(typeof(IntraTextNoteTagger), out tagger)) { // Try and find the tag version range that contains the tag TagVersionRange <IIntraTextSpacerTag> tagVersionRange = tagger[tagRange.Tag]; if (tagVersionRange != null) { // Remove the tag version range from the tagger tagger.Remove(tagVersionRange); } } } }
/// <summary> /// Checks the methods within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); /* * // Get the autoupdate setting. * string flag = null; * if (document.File.Project.LocalSettings != null) * { * flag = document.File.Project.LocalSettings.GetProperty("ParamCheckAutomatic"); * if (flag == null && document.File.Project.GlobalSettings != null) * { * flag = document.File.Project.GlobalSettings.GetProperty("ParamCheckAutomatic"); * } * } * * this.autoUpdate = (flag != null && flag == "1"); */ // Analyze the document. CsDocument csdocument = (CsDocument)document; if (csdocument.RootElement != null && !csdocument.RootElement.Generated) { this.ProcessElement(csdocument, csdocument.RootElement); } }
/// <summary> /// Initializes a new instance of the <c>JsonTokenTagger</c> class. /// </summary> /// <param name="document">The specific <see cref="ICodeDocument"/> for which this token tagger will be used.</param> /// <param name="classificationTypeProvider">A <see cref="IJsonClassificationTypeProvider"/> that provides classification types used by this token tagger.</param> public JsonTokenTagger(ICodeDocument document, IJsonClassificationTypeProvider classificationTypeProvider) : base(document) { if ((classificationTypeProvider == null)) throw new ArgumentNullException("classificationTypeProvider"); // Initialize classificationTypeProviderValue = classificationTypeProvider; }
/// <summary> /// Examines the AST data to determine the context type and insert the containing function declaration. /// </summary> /// <param name="context">The <see cref="SimpleContext"/> to update.</param> private static void UpdateFromAst(SimpleContext context) { // Get the snapshot offset TextSnapshotOffset snapshotOffset = context.SnapshotOffset; // Get the document ICodeDocument document = snapshotOffset.Snapshot.Document as ICodeDocument; if (document == null) { return; } ILLParseData parseData = document.ParseData as ILLParseData; if (parseData != null) { CompilationUnit compilationUnit = parseData.Ast as CompilationUnit; if ((compilationUnit != null) && (compilationUnit.HasMembers)) { // Translate the snapshot offset to the AST's snapshot if (parseData.Snapshot != null) { snapshotOffset = snapshotOffset.TranslateTo(parseData.Snapshot, TextOffsetTrackingMode.Negative); } // Loop through AST nodes foreach (FunctionDeclaration functionAstNode in compilationUnit.Members) { // If the child node is a function declaration with valid offsets... if ((functionAstNode.StartOffset.HasValue) && (functionAstNode.EndOffset.HasValue)) { // If the function's text range contains the offset... TextRange functionTextRange = new TextRange(functionAstNode.StartOffset.Value, functionAstNode.EndOffset.Value); if (functionTextRange.Contains(snapshotOffset.Offset)) { // Initially assume we are in a header context.Type = SimpleContextType.FunctionDeclarationHeader; context.ContainingFunctionDeclaration = functionAstNode; // If the function has a body with a range... if ((functionAstNode.Body != null) && (functionAstNode.Body.StartOffset.HasValue) && (functionAstNode.Body.EndOffset.HasValue)) { // If the block's text range contains the offset... TextRange blockTextRange = new TextRange(functionAstNode.Body.StartOffset.Value + 1, functionAstNode.Body.EndOffset.Value - 1); if (blockTextRange.Contains(snapshotOffset.Offset)) { // Mark that we are in a block instead context.Type = SimpleContextType.FunctionDeclarationBlock; } } break; } } } } } }
/// <summary> /// Clears the analyzer tags for the given document and all of its children. /// </summary> /// <param name="document">The document to clear.</param> /// <remarks> /// <para>During each analysis run, analyzers can store data within each analyzed document for /// later use. Analyzers store and retrieve this data using the <see cref="SourceAnalyzer.GetDocumentData"/> /// and <see cref="SourceAnalyzer.SetDocumentData"/> methods.</para> /// <para>After all analysis has been completed, this analyzer data should be cleared so that /// it will not conflict with the next analysis. This method can be called to clear all /// analyzer data which was stored during the previous analysis.</para> /// </remarks> internal static void ClearAnalyzerTags(ICodeDocument document) { Param.AssertNotNull(document, "document"); if (document != null && document.DocumentContents != null) { document.DocumentContents.ClearAnalyzerTags(); } }
public Tagger(ICodeDocument document) : base("Custom", new Ordering[] { new Ordering(TaggerKeys.Token, OrderPlacement.Before) }, document) { // Get a token tag aggregator tokenTagAggregator = document.CreateTagAggregator <ITokenTag>(); tokens.Add("Osc"); tokens.Add("Log"); tokens.Add("Client"); }
/// <summary> /// Initializes a new instance of the <c>JsonTokenTagger</c> class. /// </summary> /// <param name="document">The specific <see cref="ICodeDocument"/> for which this token tagger will be used.</param> /// <param name="classificationTypeProvider">A <see cref="IJsonClassificationTypeProvider"/> that provides classification types used by this token tagger.</param> public JsonTokenTagger(ICodeDocument document, IJsonClassificationTypeProvider classificationTypeProvider) : base(document) { if ((classificationTypeProvider == null)) { throw new ArgumentNullException("classificationTypeProvider"); } // Initialize classificationTypeProviderValue = classificationTypeProvider; }
/// <summary> /// Gets the data saved by this analyzer within the given document. /// </summary> /// <param name="document">The document containing the data.</param> /// <returns>Returns the data if it exists.</returns> protected object GetDocumentData(ICodeDocument document) { Param.RequireNotNull(document, "document"); object data = null; document.AnalyzerData.TryGetValue(this.Id, out data); return(data); }
public static Workspace GetWorkspace(this ICodeDocument codeDocument) { return(codeDocument.Properties.GetOrCreateSingleton(WorkspaceKey, () => { var textContainer = new ActiproSourceTextContainer(codeDocument); var workspace = new Workspace(textContainer); new NQueryParseDataSynchronizer(codeDocument, workspace); return workspace; })); }
/// <summary> /// Checks the spacing of items within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (csdocument != null && !csdocument.Generated) { this.CheckSpacing(csdocument, false); } }
private static JsonObjectNode GetRootAstNode(ICodeDocument document) { var parseData = document.ParseData as ILLParseData; if (parseData == null) { return null; } var node = parseData.Ast.HasChildren ? parseData.Ast.Children[0] as JsonObjectNode : null; return node; }
/// <summary> /// Initializes a new instance of the <c>SimpleTokenTagger</c> class. /// </summary> /// <param name="document">The specific <see cref="ICodeDocument"/> for which this token tagger will be used.</param> /// <param name="classificationTypeProvider">A <see cref="ISimpleClassificationTypeProvider"/> that provides classification types used by this token tagger.</param> public ExecutionTargetSelectorTokenTagger(ICodeDocument document, IExecutionTargetSelectorClassificationTypeProvider classificationTypeProvider) : base(document) { if ((classificationTypeProvider == null)) { throw new ArgumentNullException("classificationTypeProvider"); } // Initialize this.classificationTypeProviderValue = classificationTypeProvider; }
/// <summary> /// Returns a tagger for the specified <see cref="ICodeDocument"/>. /// </summary> /// <typeparam name="T">The type of <see cref="ITag"/> created by the tagger.</typeparam> /// <param name="document">The <see cref="ICodeDocument"/> that requires a tagger.</param> /// <returns>A tagger for the specified <see cref="ICodeDocument"/>.</returns> public ITagger <T> GetTagger <T>(ICodeDocument document) where T : ITag { if (typeof(ITagger <T>).IsAssignableFrom(typeof(JsonTokenTagger))) { var factory = new TaggerFactory(this, document); return((ITagger <T>)(document.Properties.GetOrCreateSingleton(typeof(ITagger <ITokenTag>), new ActiproSoftware.Text.Utility.PropertyDictionary. Creator <JsonTokenTagger>(factory.CreateTagger)))); } return(null); }
private static JsonObjectNode GetRootAstNode(ICodeDocument document) { var parseData = document.ParseData as ILLParseData; if (parseData == null) { return(null); } var node = parseData.Ast.HasChildren ? parseData.Ast.Children[0] as JsonObjectNode : null; return(node); }
/// <summary> /// Gets a value indicating whether the given rule is enabled for the given document. /// </summary> /// <param name="document">The document.</param> /// <param name="ruleName">The rule to check.</param> /// <returns>Returns true if the rule is enabled; otherwise false.</returns> public override bool IsRuleEnabled(ICodeDocument document, string ruleName) { Param.RequireNotNull(document, "document"); Param.RequireValidString(ruleName, "ruleName"); if (document.SourceCode == null || document.SourceCode.Settings == null) { return(true); } return(document.SourceCode.Settings.IsRuleEnabled(this, ruleName)); }
/// <summary> /// Checks the case of element names within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (!csdocument.Generated) { Dictionary<string, string> validPrefixes = this.GetPrefixes(document.Settings); this.ProcessElement(csdocument, validPrefixes, false); } }
public NQuerySemanticIssueSquiggleClassifier(ICodeDocument document) : base(typeof(NQuerySemanticIssueSquiggleClassifier).Name, null, document, true) { _workspace = document.GetWorkspace(); if (_workspace == null) { return; } _workspace.CurrentDocumentChanged += WorkspaceOnCurrentDocumentChanged; UpdateTags(); }
/// <summary> /// Checks the case of element names within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (!csdocument.Generated) { Dictionary <string, string> validPrefixes = this.GetPrefixes(document.Settings); this.ProcessElement(csdocument, validPrefixes, false); } }
public NQuerySemanticErrorSquiggleClassifier(ICodeDocument document) : base(ClassificationTypes.CompilerError, typeof(NQuerySemanticErrorSquiggleClassifier).Name, null, document, true) { _workspace = document.GetWorkspace(); if (_workspace == null) { return; } _workspace.CurrentDocumentChanged += WorkspaceOnCurrentDocumentChanged; UpdateTags(); }
/// <summary> /// Coverts the given document into a <see cref="CsDocument" /> if possible. /// </summary> /// <param name="document">The document to convert.</param> /// <returns>Returns the converted document or null.</returns> public static CsDocument AsCsDocument(this ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocumentWrapper wrapper = document as CsDocumentWrapper; if (wrapper == null) { return(null); } return(wrapper.CsDocument); }
/// <summary> /// Initializes a new instance of the <c>ParentTokenTagger</c> class. /// </summary> /// <param name="document">The specific <see cref="ICodeDocument"/> for which this token tagger will be used.</param> /// <param name="classificationTypeProvider">A <see cref="IParentClassificationTypeProvider"/> that provides classification types used by this token tagger.</param> public ParentTokenTagger(ICodeDocument document, IParentClassificationTypeProvider classificationTypeProvider) : base(document) { if ((classificationTypeProvider == null)) { throw new ArgumentNullException("classificationTypeProvider"); } // Initialize this.classificationTypeProviderValue = classificationTypeProvider; // Create the token tagger for the child language cSharpTokenTagger = new CSharpTokenTagger(document, new DotNetClassificationTypeProvider()); }
/// <summary> /// Stores the given data object within the given document. /// </summary> /// <param name="document">The document to store the data within.</param> /// <param name="data">The data to store.</param> protected void SetDocumentData(ICodeDocument document, object data) { Param.RequireNotNull(document, "document"); Param.Ignore(data); if (document.AnalyzerData.ContainsKey(this.Id)) { document.AnalyzerData[this.Id] = data; } else { document.AnalyzerData.Add(this.Id, data); } }
/// <summary> /// Checks the placement of brackets within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (csdocument != null && !csdocument.Generated) { csdocument.WalkCodeModel(this.VisitCodeUnit); // Check line spacing rules. this.CheckLineSpacing(csdocument); } }
public NQuerySemanticClassifier(ICodeDocument document) : base(typeof(NQuerySemanticClassifier).Name, null, document, true) { _classificationTypes = document.Language.GetService <INQueryClassificationTypes>(); _workspace = document.GetWorkspace(); if (_workspace == null) { return; } _workspace.CurrentDocumentChanged += WorkspaceOnCurrentDocumentChanged; UpdateTags(); }
///////////////////////////////////////////////////////////////////////////////////////////////////// // NON-PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Changes the status of the specified note tag. /// </summary> /// <param name="tagRange">The tag range.</param> /// <param name="status">The new status.</param> private void ChangeNoteStatus(TagSnapshotRange <IntraTextNoteTag> tagRange, ReviewStatus status) { // Get the tagger from the code document ICodeDocument document = tagRange.SnapshotRange.Snapshot.Document as ICodeDocument; if (document != null) { IntraTextNoteTagger tagger = null; if (document.Properties.TryGetValue(typeof(IntraTextNoteTagger), out tagger)) { // Change the tag's status and raise an event so the UI knows to update tagRange.Tag.Status = status; tagger.RaiseTagsChanged(new TagsChangedEventArgs(tagRange.SnapshotRange)); } } }
///////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns an <see cref="IOutliningSource"/> for the specified <see cref="ITextSnapshot"/>. /// </summary> /// <param name="snapshot">The <see cref="ITextSnapshot"/> for which to return an outlining source.</param> /// <returns>An <see cref="IOutliningSource"/> for the specified <see cref="ITextSnapshot"/>.</returns> public IOutliningSource GetOutliningSource(ITextSnapshot snapshot) { ICodeDocument document = snapshot.Document as ICodeDocument; if (document != null) { // Get the outlining source, which should be in the code document's parse data JavascriptOutliningSource source = document.ParseData as JavascriptOutliningSource; if (source != null) { // Translate the data to the desired snapshot, which could be slightly newer than the parsed source source.TranslateTo(snapshot); return(source); } } return(null); }
private static bool _Run() { bool result = true; ICodeDocument document = CodeDocument.Create(); ICodeLine codeline = CodeLine.Create(document); document.AddBefore(codeline); result = result && (document.Cursor == codeline); IToken tokenFirst = Token.Create(Location.Create("filename", 0, 0, 10), "first", TokenKind.LiteralString); codeline.AddBefore(tokenFirst); // codeline = [(first)] result = result && (codeline.Cursor == tokenFirst); IToken tokenAfter = Token.Create(Location.Create("filename", 0, 0, 10), "after", TokenKind.LiteralInteger); codeline.AddAfter(tokenAfter); // codeline = (first)[(after)] result = result && (codeline.Cursor == tokenAfter); // we set cursor to added item IToken tokenBefore = Token.Create(Location.Create("filename", 0, 0, 10), "before", TokenKind.LiteralFloat); codeline.AddBefore(tokenBefore); // codeline = (first)[(before)](after) result = result && (codeline.Cursor == tokenBefore); codeline.MoveCursorPrev(); // codeline = [(first)](before)(aft result = result && (codeline.Cursor == tokenFirst); codeline.MoveCursorNext(); // codeline - (first)[(before)](after) result = result && (codeline.Cursor == tokenBefore); codeline.MoveCursorNext(); // codeline = (first)(before)[(after)] result = result && (codeline.Cursor == tokenAfter); // now test saturation foreach (int i in F.range(0, 6)) { codeline.MoveCursorPrev(); } result = result && (codeline.Cursor == tokenFirst); foreach (int i in F.range(0, 6)) { codeline.MoveCursorNext(); } result = result && (codeline.Cursor == tokenAfter); return(result); }
private void UpdateReferences(ICodeDocument document, DocumentReferencedIdManager idManager) { // Note: if this proves to be too slow with large documents, we can potentially optimize the finding // of references by only considering the parts of the AST which occur after the Offset at which the text change began // (we can find this by getting hold of the TextSnapshotChangedEventArgs) var potentialReferences = FindPotentialReferences(document).ToList(); var newReferences = potentialReferences.Where(idManager.NeedsChecking).ToArray(); if (newReferences.Any()) { DocumentIdCheckHelpers.GetActualIds(newReferences) .ContinueOnSuccessInTheUIThread(ids => { idManager.AddKnownIds(ids); idManager.AddKnownInvalidIds(newReferences.Except(ids, StringComparer.OrdinalIgnoreCase)); idManager.UpdateCurrentIds(potentialReferences); }); } }
/// <summary> /// Returns a value indicating whether to delay analysis of this document until the next pass. /// </summary> /// <param name="document">The document to analyze.</param> /// <param name="passNumber">The current pass number.</param> /// <returns>Returns true if analysis should be delayed.</returns> public override bool DelayAnalysis(ICodeDocument document, int passNumber) { Param.RequireNotNull(document, "document"); Param.Ignore(passNumber); bool delay = false; // We sometimes delay pass zero, but never pass one. if (passNumber == 0) { // Get the root element. CsDocument csdocument = document.AsCsDocument(); if (csdocument != null) { // If the element has any partial classes, structs, or interfaces, delay. This is due // to the fact that the class members rules need knowledge about all parts of the class // in order to find all class members. delay = this.ContainsPartialMembers(csdocument); } } return delay; }
/// <summary> /// Saves the given code document results into a cache document. /// </summary> /// <param name="document">The document to save.</param> /// <param name="parser">The parser that created the document.</param> /// <param name="settingsTimeStamp">The time when the settings were last updated.</param> /// <returns>Returns true if the document was saved.</returns> public bool SaveDocumentResults(ICodeDocument document, SourceParser parser, DateTime settingsTimeStamp) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(parser, "parser"); Param.Ignore(settingsTimeStamp); bool success = false; lock (this) { XmlDocument xml = null; try { if (!this.documentHash.ContainsKey(document.SourceCode.Project.Location)) { XmlNode temp; xml = this.OpenResultsCache(document.SourceCode, parser, out temp); if (xml != null) { this.documentHash.Add(document.SourceCode.Project.Location, xml); } } else { xml = this.documentHash[document.SourceCode.Project.Location]; } if (xml != null) { XmlNode remove = xml.DocumentElement.SelectSingleNode( string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", document.SourceCode.Name, parser.Id)); if (remove != null) { xml.DocumentElement.RemoveChild(remove); } } else { xml = new XmlDocument(); // Create the document node. xml.AppendChild(xml.CreateElement("stylecopresultscache")); // Add the version. XmlNode versionNode = xml.CreateElement("version"); xml.DocumentElement.AppendChild(versionNode); versionNode.InnerText = ResultsCache.Version; if (this.documentHash.ContainsKey(document.SourceCode.Project.Location)) { this.documentHash.Remove(document.SourceCode.Project.Location); } this.documentHash.Add(document.SourceCode.Project.Location, xml); } XmlNode root = xml.CreateElement("sourcecode"); XmlAttribute name = xml.CreateAttribute("name"); name.Value = document.SourceCode.Name; root.Attributes.Append(name); xml.DocumentElement.AppendChild(root); // Save the last write time of the settings. XmlNode settingsNode = xml.CreateElement("settings"); root.AppendChild(settingsNode); XmlNode node = xml.CreateElement("timestamp"); settingsNode.AppendChild(node); node.InnerText = settingsTimeStamp.ToString(CultureInfo.InvariantCulture); node = xml.CreateElement("milliseconds"); settingsNode.AppendChild(node); node.InnerText = settingsTimeStamp.Millisecond.ToString(CultureInfo.InvariantCulture); // Get the last write time of the source code. DateTime writeTime = document.SourceCode.TimeStamp; // Add the timestamp. node = xml.CreateElement("timestamp"); root.AppendChild(node); node.InnerText = writeTime.ToString(CultureInfo.InvariantCulture); node = xml.CreateElement("milliseconds"); root.AppendChild(node); node.InnerText = writeTime.Millisecond.ToString(CultureInfo.InvariantCulture); // Add the parser ID attribute. if (document.SourceCode.Parser != null) { XmlAttribute attribute = xml.CreateAttribute("parser"); root.Attributes.Append(attribute); attribute.Value = document.SourceCode.Parser.Id; } // Create the violations node. node = xml.CreateElement("violations"); root.AppendChild(node); // Add the violations. SourceParser.ExportViolations(document, xml, node); success = true; } catch (XmlException) { } } return success; }
private IEnumerable<string> FindPotentialReferences(ICodeDocument codeDocument) { var stringValueNodes = codeDocument.FindAllStringValueNodes(); return stringValueNodes.Select(n => n.Text).Distinct().Where(IsPotentialReference); }
/// <summary> /// Gets a value indicating whether the given rule is enabled for the given document. /// </summary> /// <param name="document">The document.</param> /// <param name="ruleName">The rule to check.</param> /// <returns>Returns true if the rule is enabled; otherwise false.</returns> public override bool IsRuleEnabled(ICodeDocument document, string ruleName) { Param.RequireNotNull(document, "document"); Param.RequireValidString(ruleName, "ruleName"); if (document.SourceCode == null || document.SourceCode.Settings == null) { return true; } return document.SourceCode.Settings.IsRuleEnabled(this, ruleName); }
/// <summary> /// Analyzes a code document. /// </summary> /// <param name="document">The document to analyze.</param> public virtual void AnalyzeDocument(ICodeDocument document) { Param.Ignore(document); }
/// <summary> /// Checks the methods within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (csdocument != null && !csdocument.Generated) { // Check the access modifier rules. TopLevelElements topLevelElements = new TopLevelElements(); csdocument.WalkCodeModel<TopLevelElements>(this.VisitCodeUnit, topLevelElements); // If there is more than one top-level class in the file, make sure they are all // partial classes and are all of the same type. if (topLevelElements.Classes.Count > 1) { string name = string.Empty; foreach (Class classElement in topLevelElements.Classes) { if (!classElement.ContainsModifier(TokenType.Partial) || (!string.IsNullOrEmpty(name) && string.Compare(name, classElement.FullyQualifiedName, StringComparison.Ordinal) != 0)) { // Set the violation line number to the second class in the file. int count = 0; foreach (Class c in topLevelElements.Classes) { if (count == 1) { this.AddViolation(c, c.LineNumber, Rules.FileMayOnlyContainASingleClass); break; } ++count; } break; } name = classElement.FullyQualifiedName; } } // If there is more than one namespace in the file, this is a violation. if (topLevelElements.Namespaces.Count > 1) { // Set the violation line number to the second namespace in the file. int count = 0; foreach (Namespace n in topLevelElements.Namespaces) { if (count == 1) { this.AddViolation(n, n.LineNumber, Rules.FileMayOnlyContainASingleNamespace); break; } ++count; } } } }
/// <summary> /// Writes the final document back to the source. /// </summary> /// <param name="document">The document to write.</param> /// <param name="exception">Returns an exception if the write operation fails.</param> /// <returns>Returns true if the document was written successfully; false otherwise.</returns> public abstract bool Write(ICodeDocument document, out Exception exception);
/// <summary> /// Analyzes or fixes the given document. /// </summary> /// <param name="document">The document.</param> private void ProcessDocument(ICodeDocument document) { Param.AssertNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); Settings settings = new Settings(); settings.DoNotUseRegions = this.IsRuleEnabled(document, Rules.DoNotUseRegions.ToString()); settings.DoNotPlaceRegionsWithinElements = this.IsRuleEnabled(document, Rules.DoNotPlaceRegionsWithinElements.ToString()); if (csdocument != null && !csdocument.Generated) { // Checks various formatting rules. csdocument.WalkCodeModel<Settings>(this.VisitCodeUnit, settings); // Check statement formatting rules. this.CheckStatementFormattingRulesForElement(csdocument); // Check the class member rules. this.CheckClassMemberRulesForElements(csdocument, null, null); } }
/// <summary> /// Automatically fixes rule violations within a code document. /// </summary> /// <param name="document">The document to fix.</param> public override void AutoFixDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); this.ProcessDocument(document); }
/// <summary> /// Checks the element headers within the given document. /// </summary> /// <param name="document">The document to check.</param> public override void AnalyzeDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (!csdocument.Generated) { this.CheckElementDocumentation(csdocument); this.CheckFileHeader(csdocument); this.CheckSingleLineComments(csdocument); } }
/// <summary> /// Automatically fixes rule violations within a code document. /// </summary> /// <param name="document">The document to fix.</param> public override void AutoFixDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); CsDocument csdocument = document.AsCsDocument(); if (!csdocument.Generated) { this.CheckFileHeader(csdocument); } }
/// <summary> /// Parses the given file. /// </summary> /// <param name="sourceCode">The source code to parse.</param> /// <param name="passNumber">The current pass number.</param> /// <param name="document">The parsed representation of the file.</param> /// <returns>Returns false if no further analysis should be done on this file, or /// true if the file should be parsed again during the next pass.</returns> public override bool ParseFile(SourceCode sourceCode, int passNumber, ref ICodeDocument document) { Param.RequireNotNull(sourceCode, "sourceCode"); Param.RequireGreaterThanOrEqualToZero(passNumber, "passNumber"); Param.Ignore(document); // The document is parsed on the first pass. On any subsequent passes, we do not do anything. if (passNumber == 0) { try { using (TextReader reader = sourceCode.Read()) { // Create the document. if (reader == null) { this.AddViolation(sourceCode, 1, Rules.FileMustBeReadable); } else { CsLanguageService languageService = new CsLanguageService(); document = new CsDocumentWrapper( this, sourceCode, languageService.CreateCodeModel(reader, sourceCode.Name, sourceCode.Path)); } } } catch (SyntaxException syntaxex) { this.AddViolation(sourceCode, syntaxex.LineNumber, Rules.SyntaxException, syntaxex.Message); document = null; } } return false; }
/// <summary> /// Indicates whether to skip analyzis on the given document. /// </summary> /// <param name="document">The document.</param> /// <returns>Returns true to skip analysis on the document.</returns> public override bool SkipAnalysisForDocument(ICodeDocument document) { Param.RequireNotNull(document, "document"); // Get the property indicating whether to analyze designer files. BooleanProperty analyzeDesignerFilesProperty = this.GetSetting( document.Settings, CsParser.AnalyzeDesignerFilesProperty) as BooleanProperty; // Default the setting to true if it does not exist. bool analyzeDesignerFiles = true; if (analyzeDesignerFilesProperty != null) { analyzeDesignerFiles = analyzeDesignerFilesProperty.Value; } if (analyzeDesignerFiles || !document.SourceCode.Name.EndsWith(".Designer.cs", StringComparison.OrdinalIgnoreCase)) { // Get the property indicating whether to analyze generated files. BooleanProperty analyzerGeneratedFilesProperty = this.GetSetting( document.Settings, CsParser.AnalyzeGeneratedFilesProperty) as BooleanProperty; // Default the setting to false if it does not exist. bool analyzeGeneratedFiles = false; if (analyzerGeneratedFilesProperty != null) { analyzeGeneratedFiles = analyzerGeneratedFilesProperty.Value; } if (analyzeGeneratedFiles || (!document.SourceCode.Name.EndsWith(".g.cs", StringComparison.OrdinalIgnoreCase) && !document.SourceCode.Name.EndsWith(".generated.cs", StringComparison.OrdinalIgnoreCase))) { // This document should be analyzed. return false; } } return true; }
/// <summary> /// Exports the violations found within this document into the given xml node. /// </summary> /// <param name="document">The document containing the violations.</param> /// <param name="violationsDocument">The xml document in which to store the violation information.</param> /// <param name="parentNode">The parent node within this xml document under which to store the violation information.</param> internal static void ExportViolations(ICodeDocument document, XmlDocument violationsDocument, XmlNode parentNode) { Param.AssertNotNull(document, "document"); Param.AssertNotNull(violationsDocument, "violationsDocument"); Param.AssertNotNull(parentNode, "parentNode"); if (document.DocumentContents != null) { SourceParser.ExportElementViolations(document.DocumentContents, violationsDocument, parentNode); } if (document.SourceCode != null) { // Add the violations from the source code. foreach (Violation violation in document.SourceCode.Violations) { SourceParser.ExportViolation(violation, violationsDocument, parentNode); } } }
/// <summary> /// Parses a source code document. /// </summary> /// <param name="sourceCode">The source code to parse.</param> /// <param name="passNumber">The current pass number.</param> /// <param name="document">The parsed representation of the file.</param> /// <returns>Returns false if no further analyzation should be done on this file.</returns> public override bool ParseFile(SourceCode sourceCode, int passNumber, ref ICodeDocument document) { Param.Ignore(sourceCode, passNumber, document); throw new NotImplementedException(); }
/// <summary> /// Gets the data saved by this analyzer within the given document. /// </summary> /// <param name="document">The document containing the data.</param> /// <returns>Returns the data if it exists.</returns> protected object GetDocumentData(ICodeDocument document) { Param.RequireNotNull(document, "document"); object data = null; document.AnalyzerData.TryGetValue(this.Id, out data); return data; }
/// <summary> /// Gets a value indicating whether the given rule is enabled for the given document. /// </summary> /// <param name="document">The document.</param> /// <param name="ruleName">The rule to check.</param> /// <returns>Returns true if the rule is enabled; otherwise false.</returns> public virtual bool IsRuleEnabled(ICodeDocument document, string ruleName) { Param.Ignore(document, ruleName); return true; }
/// <summary> /// Automatically fixes rule violations within a code document. /// </summary> /// <param name="document">The document to fix.</param> public virtual void AutoFixDocument(ICodeDocument document) { Param.Ignore(document); }
/// <summary> /// Determines whether the analyzer wishes to delay its analysis until a later pass. /// </summary> /// <param name="document">The document to analyze.</param> /// <param name="passNumber">The current pass number.</param> /// <returns>Returns true if the analysis should be delayed until the next pass, or /// false if the analysis should be performed in the current pass.</returns> public virtual bool DelayAnalysis(ICodeDocument document, int passNumber) { Param.Ignore(document, passNumber); return false; }