/// <summary>Initializes a new instance of the <see cref="TokenTextIndex"/> class.</summary> /// <exception cref="ArgumentNullException">Thrown when <paramref name="text"/> is null.</exception> /// <param name="text">The string to tokenize.</param> public TokenTextIndex(string text) { if (text == null) { throw new ArgumentNullException("text"); } this.Text = text; _newlines = new NewLineIndex(text); }
private void PopulateControl(ObservableCollection <AnnotatedCodeLocationModel> items, IList <IList <AnnotatedCodeLocation> > annotatedCodeLocationSets, AnnotatedCodeLocationKind kind) { int index = 0; NewLineIndex newLineIndex = null; Dictionary <string, NewLineIndex> fileToNewLineIndexMap = new Dictionary <string, NewLineIndex>(); foreach (IList <AnnotatedCodeLocation> annotatedCodeLocations in annotatedCodeLocationSets) { index++; // Labels are 1-indexed in UI foreach (AnnotatedCodeLocation codeLocation in annotatedCodeLocations) { PhysicalLocationComponent plc = codeLocation.PhysicalLocation[0]; string fileName = plc.Uri.LocalPath; Region region = plc.Region; if (!File.Exists(fileName)) { fileName = RebaselineFileName(fileName, _remappedPathPrefixes); if (fileName == null) { // User cancelled items.Clear(); return; } } if (!fileToNewLineIndexMap.TryGetValue(fileName, out newLineIndex)) { fileToNewLineIndexMap[fileName] = newLineIndex = new NewLineIndex(File.ReadAllText(fileName)); } region.Populate(newLineIndex); items.Add(new AnnotatedCodeLocationModel() { Index = index, Kind = kind, Message = codeLocation.Message, Region = region, FilePath = fileName, }); } } }
internal bool TryNavigateTo(SarifError sarifError, string fileName, string mimeType, Region region, ResultTextMarker marker, out IVsWindowFrame result) { result = null; if (string.IsNullOrEmpty(fileName)) { return(false); } string remappedName = fileName; if (!File.Exists(fileName)) { remappedName = RebaselineFileName(fileName); if (!File.Exists(remappedName)) { return(false); } } CodeAnalysisResultManager.Instance.RemapFileNames(fileName, remappedName); fileName = remappedName; NewLineIndex newLineIndex = null; if (!sarifError.RegionPopulated && mimeType != MimeType.Binary) { if (!_fileToNewLineIndexMap.TryGetValue(fileName, out newLineIndex)) { _fileToNewLineIndexMap[fileName] = newLineIndex = new NewLineIndex(File.ReadAllText(fileName)); } region.Populate(newLineIndex); sarifError.RegionPopulated = true; } marker.FullFilePath = remappedName; result = marker.NavigateTo(false, null, false); return(result != null); }
/// <summary> /// Completely populate all Region property members. Missing data /// is computed based on the values that are already present. /// </summary> /// <param name="region"></param> /// <param name="newLineIndex"></param> public static void Populate(this Region region, NewLineIndex newLineIndex) { // TODO: we need charOffset and byteOffset to be expressed as // nullable types in order to differentiate between text // and binary file regions. For text files, we need to populate // startLine, etc. based on document offset. For now, we'll // assume we're always looking at text files if (region.StartLine == 0) { OffsetInfo offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.Offset); region.StartLine = offsetInfo.LineNumber; region.StartColumn = offsetInfo.ColumnNumber; offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.Offset + region.Length); region.StartLine = offsetInfo.LineNumber; region.EndColumn = offsetInfo.ColumnNumber; } else { // Make endColumn and endLine explicit, if not expressed if (region.EndLine == 0) { region.EndLine = region.StartLine; } if (region.EndColumn == 0) { region.EndColumn = region.StartColumn; } LineInfo lineInfo = newLineIndex.GetLineInfoForLine(region.StartLine); region.Offset = lineInfo.StartOffset + (region.StartColumn - 1); lineInfo = newLineIndex.GetLineInfoForLine(region.EndLine); region.Length = lineInfo.StartOffset + (region.EndColumn - 1) - region.Offset; } }
private Grammar Parse(IEnumerable <Token> tokens, string text) { List <Token> list = tokens.ToList(); NewLineIndex newLines = new NewLineIndex(text); Grammar grammar = null; ParserState state = ParserState.None; Production production = null; List <Token> rhsTokens = null; string grammarNamespace = "Undefined"; for (int i = 0; i < list.Count; i++) { Token token = list[i]; Token next = (i < list.Count - 1) ? list[i + 1] : null; switch (state) { case ParserState.None: if (token.Kind == Token.TokenKind.Identifier) { if (token.Value == "grammar") { if (next != null) { grammar = new Grammar { Name = next.Value, GrammarNamespace = grammarNamespace }; i++; } next = (i < list.Count - 1) ? list[i + 1] : null; Contract.Assert(next != null && next.Kind == Token.TokenKind.Semicolon); i++; state = ParserState.ReadyForLhs; production = new Production(); } } else if (token.Kind == Token.TokenKind.Annotation) { string[] split = token.Value.Split(new[] { ':' }); if (split.Count() == 2) { if (split[0].Equals("namespace")) { grammarNamespace = split[1]; } } } break; case ParserState.ReadyForLhs: Contract.Assert( token.Kind == Token.TokenKind.Identifier, String.Format( "Expected an identifier at location {0}, found {1}", newLines.GetOffsetInfoForOffset(token.Offset), token.Kind)); if (token.Value == "fragment") { while (list[i].Kind != Token.TokenKind.Semicolon) { i++; } } else { if (production != null) { production.LHS = new NonTerminal { Name = token.Value, Type = token.Value, }; production.Location = newLines.GetOffsetInfoForOffset(token.Offset); } Contract.Assert( next != null && next.Kind == Token.TokenKind.Colon, String.Format( "Expected a colon at {0}, found {1}", newLines.GetOffsetInfoForOffset(token.Offset), token)); i++; rhsTokens = new List <Token>(); state = ParserState.ReadyForRhs; } break; case ParserState.ReadyForRhs: if (token.Kind != Token.TokenKind.Semicolon) { Contract.Assert(rhsTokens != null); rhsTokens.Add(token); } else { if (production != null) { production.RHS = this.CreateRHS(rhsTokens).ToList(); if (grammar != null) { grammar.AddProductionRaw(production); } state = ParserState.ReadyForLhs; } production = new Production(); } break; } } return(grammar); }
private Result MakeResultFromError(JsonError error) { var result = new Result(); string analysisTargetFilePath; NewLineIndex index = null; switch (error.Location) { case JsonErrorLocation.InstanceDocument: analysisTargetFilePath = _instanceFilePath; index = InstanceFileIndex; break; case JsonErrorLocation.Schema: analysisTargetFilePath = _schemaFilePath; index = SchemaFileIndex; break; default: analysisTargetFilePath = "unknown_file"; break; } Uri analysisTargetUri = new Uri(analysisTargetFilePath); switch (error.Kind) { case JsonErrorKind.Syntax: result.RuleId = JsonSyntaxErrorRule.Id; result.Kind = ResultKind.Error; result.FormattedRuleMessage = new FormattedRuleMessage { FormatId = JsonSyntaxErrorFormatSpecifier, Arguments = new[] { error.Message } }; break; case JsonErrorKind.Validation: result.RuleId = JsonSchemaValidationErrorRule.Id; result.Kind = ResultKind.Error; result.FormattedRuleMessage = new FormattedRuleMessage { FormatId = JsonSchemaValidationErrorFormatSpecifier, Arguments = new[] { error.Message } }; break; default: result.RuleId = UnknownErrorRule.Id; result.Kind = ResultKind.InternalError; result.FormattedRuleMessage = new FormattedRuleMessage { FormatId = UnknownErrorFormatSpecifier, Arguments = new string[] { error.Kind.ToString() } }; break; } Region region; if (index != null) { region = new Region { Offset = error.Start, Length = error.Length }; region.Populate(index); } else { region = new Region(); } var location = new Location { AnalysisTarget = new PhysicalLocation { Uri = analysisTargetUri, Region = region } }; result.Locations = new HashSet <Location> { location }; return(result); }
private void WriteRunToErrorList(Run runLog) { List <SarifError> sarifErrors = new List <SarifError>(); // Prefer optional fullName, fall back to required Name property string toolName = runLog.Tool.FullName ?? runLog.Tool.Name; foreach (Result result in runLog.Results) { string category, document, shortMessage, fullMessage; Region region; NewLineIndex newLineIndex; IRule rule = null; category = null; if (result.Properties != null) { result.Properties.TryGetValue("category", out category); } foreach (Location location in result.Locations) { region = null; PhysicalLocation physicalLocation = null; if (location.ResultFile != null) { physicalLocation = location.ResultFile; document = physicalLocation.Uri.LocalPath; region = physicalLocation.Region; } else if (location.AnalysisTarget != null) { physicalLocation = location.AnalysisTarget; document = physicalLocation.Uri.LocalPath; region = physicalLocation.Region; } else { document = location.FullyQualifiedLogicalName; } rule = GetRule(runLog, result.RuleId); shortMessage = result.GetMessageText(rule, concise: true); fullMessage = result.GetMessageText(rule, concise: false); if (shortMessage == fullMessage) { fullMessage = null; } SarifError sarifError = new SarifError(document) { Region = region, RuleId = result.RuleId, RuleName = rule?.Name, Kind = result.Kind, Category = category, ShortMessage = shortMessage, FullMessage = fullMessage, Tool = toolName, HelpLink = rule?.HelpUri?.ToString() }; CaptureAnnotatedCodeLocationCollections(result.Stacks, AnnotatedCodeLocationKind.Stack, sarifError); CaptureAnnotatedCodeLocationCollections(result.CodeFlows, AnnotatedCodeLocationKind.CodeFlow, sarifError); CaptureAnnotatedCodeLocations(result.RelatedLocations, AnnotatedCodeLocationKind.Stack, sarifError); if (region != null) { sarifError.ColumnNumber = region.StartColumn - 1; sarifError.LineNumber = region.StartLine - 1; } sarifErrors.Add(sarifError); } // TODO zap this on implementing todo above if (result.RelatedLocations != null) { foreach (AnnotatedCodeLocation annotation in result.RelatedLocations) { PhysicalLocation physicalLocation = annotation.PhysicalLocation; region = physicalLocation.Region; shortMessage = annotation.Message; document = annotation.PhysicalLocation.Uri.LocalPath; if (!this.documentToLineIndexMap.TryGetValue(document, out newLineIndex)) { this.documentToLineIndexMap[document] = newLineIndex = new NewLineIndex(File.ReadAllText(document)); } if (region != null) { region.Populate(newLineIndex); } SarifError sarifError = new SarifError(document) { Region = region, RuleId = result.RuleId, RuleName = rule?.Name, Kind = ResultKind.Note, Category = "Related Location", // or should we prefer original result category? ShortMessage = shortMessage, FullMessage = null, Tool = toolName }; if (region != null) { sarifError.ColumnNumber = region.StartColumn - 1; sarifError.LineNumber = region.StartLine - 1; } sarifErrors.Add(sarifError); } } CodeAnalysisResultManager.Instance.SarifErrors = sarifErrors; SarifTableDataSource.Instance.AddErrors(sarifErrors); } }