private int startOfCurrentLine; //^ invariant 0 <= startOfCurrentLine && startOfCurrentLine <= fragmentIndex; /// <summary> /// Allocates a preprocessor instance that can be queried for a list of source locations that represent the output from the preprocessor. This output /// omits preprocessor directives as well as any excluded sections. It also applies line directives by mapping some of the produced source locations /// onto the documents mentioned in the line directives. In other words, the produced source locations will not necessarily come from the document /// being preprocessed. Preprocessing happens lazily as the result of calling GetIncludedSections is enumerated. /// </summary> /// <param name="documentToProcess">The source document to preprocess.</param> /// <param name="options">An object that specifies any preprocessor symbols that are defined as compiler options by the environment.</param> internal Preprocessor(IPrimarySourceDocument documentToProcess, SpecSharpOptions options) { //TODO: use Dictionary<string,string> instead of StringDictionary. this.documentToProcess = documentToProcess; List<IErrorMessage> errors = this.errors = new List<IErrorMessage>(); this.preprocessorInformation = new PreprocessorInformation(documentToProcess, errors); Dictionary<string, string> preprocessorDefinedSymbols = new Dictionary<string, string>(); foreach (string definedSymbol in options.DefinedSymbols) preprocessorDefinedSymbols[definedSymbol] = definedSymbol; preprocessorDefinedSymbols["true"] = "true"; preprocessorDefinedSymbols.Remove("false"); this.preprocessorDefinedSymbols = preprocessorDefinedSymbols; this.buffer = new char[16]; //TODO: make this a more realistic size once simple testing is done. }
private ISymUnmanagedDocumentWriter GetDocumentWriterFor(IPrimarySourceDocument document) { ISymUnmanagedDocumentWriter writer; if (!this.documentMap.TryGetValue(document, out writer)) { Guid language = document.Language; Guid vendor = document.LanguageVendor; Guid type = document.DocumentType; writer = this.SymWriter.DefineDocument(document.Location, ref language, ref vendor, ref type); this.documentMap.Add(document, writer); } return(writer); }
private void DefineSequencePointsForCurrentDocument() { if (this.currentDocument != SourceDummy.PrimarySourceDocument) { ISymUnmanagedDocumentWriter document = this.GetDocumentWriterFor(this.currentDocument); uint seqPointCount = (uint)this.offsets.Count; uint[] offsets = this.offsets.ToArray(); uint[] startLines = this.startLines.ToArray(); uint[] startColumns = this.startColumns.ToArray(); uint[] endLines = this.endLines.ToArray(); uint[] endColumns = this.endColumns.ToArray(); this.SymWriter.DefineSequencePoints(document, seqPointCount, offsets, startLines, startColumns, endLines, endColumns); } this.currentDocument = SourceDummy.PrimarySourceDocument; this.offsets.Clear(); this.startLines.Clear(); this.startColumns.Clear(); this.endLines.Clear(); this.endColumns.Clear(); }
private ISymUnmanagedDocumentWriter GetDocumentWriterFor(IPrimarySourceDocument document) { Contract.Requires(document != null); Contract.Requires(document != SourceDummy.PrimarySourceDocument); string filename = document.Location; ISymUnmanagedDocumentWriter writer; if (!this.documentMap.TryGetValue(filename, out writer)) { Guid language = document.Language; Guid vendor = document.LanguageVendor; Guid type = document.DocumentType; writer = this.SymWriter.DefineDocument(filename, ref language, ref vendor, ref type); if (document.Checksum != null) { writer.SetCheckSum(document.ChecksumAlgorithm, (uint)document.Checksum.Length, document.Checksum); } this.documentMap.Add(filename, writer); } return(writer); }
/// <summary> /// Allocates a range of source text that corresponds to an identifiable entity. /// </summary> /// <param name="primarySourceDocument">The document containing the source text of which this location is a subrange.</param> /// <param name="startIndex">The character index of the first character of this location, when treating the source document as a single string.</param> /// <param name="length">The number of characters in this source location.</param> public PrimarySourceLocation(IPrimarySourceDocument primarySourceDocument, int startIndex, int length) : base(startIndex, length) //^ requires startIndex >= 0 && startIndex <= primarySourceDocument.Length; //^ requires length >= 0 && length <= primarySourceDocument.Length; //^ requires 0 <= startIndex + length; //^ requires startIndex + length <= primarySourceDocument.Length; { this.primarySourceDocument = primarySourceDocument; }
/// <summary> /// Allocates source location that spans entire primary source document, but that delays computing this.Length until needed so that the document can be streamed. /// </summary> /// <param name="primarySourceDocument">The document that the resulting source location spans.</param> public SourceLocationSpanningEntirePrimaryDocument(IPrimarySourceDocument primarySourceDocument) : base(primarySourceDocument, 0, 0) { }
/// <summary> /// Allocates source location that spans entire primary source document, but that delays computing this.Length until needed so that the document can be streamed. /// </summary> /// <param name="primarySourceDocument">The document that the resulting source location spans.</param> public SourceLocationSpanningEntirePrimaryDocument(IPrimarySourceDocument primarySourceDocument) : base(primarySourceDocument, 0, 0) { Contract.Requires(primarySourceDocument != null); }
/// <summary> /// Allocates an object that represents a primary source document that has a region of text that originally came from another source document. /// </summary> /// <param name="wrappedDocument">A primary source document that has an inclusion (but does not know about it).</param> /// <param name="originalLineNumber">The starting line number that the included region of text has in the the document it originated from.</param> /// <param name="originalDocumentName">The name of the document from which the included region of text has originated.</param> /// <param name="startingPositionOfIncludedRegion">The position in the wrapped document where the included region starts.</param> public SourceDocumentWithInclusion(IPrimarySourceDocument wrappedDocument, int originalLineNumber, string originalDocumentName, int startingPositionOfIncludedRegion) //^ requires 0 <= startingPositionOfIncludedRegion && startingPositionOfIncludedRegion < wrappedDocument.Length; { this.wrappedDocument = wrappedDocument; this.originalLineNumber = originalLineNumber; this.originalDocumentName = originalDocumentName; this.startingPositionOfIncludedRegion = startingPositionOfIncludedRegion; }
/// <summary> /// Allocates an object that represents a primary source document that has a region of text that originally came from another source document. /// </summary> /// <param name="wrappedDocument">A primary source document that has an inclusion (but does not know about it).</param> /// <param name="originalLineNumber">The starting line number that the included region of text has in the the document it originated from.</param> /// <param name="originalDocumentName">The name of the document from which the included region of text has originated.</param> /// <param name="startingPositionOfIncludedRegion">The position in the wrapped document where the included region starts.</param> public SourceDocumentWithInclusion(IPrimarySourceDocument wrappedDocument, int originalLineNumber, string originalDocumentName, int startingPositionOfIncludedRegion) { Contract.Requires(wrappedDocument != null); Contract.Requires(0 <= startingPositionOfIncludedRegion && startingPositionOfIncludedRegion < wrappedDocument.Length); this.wrappedDocument = wrappedDocument; this.originalLineNumber = originalLineNumber; this.originalDocumentName = originalDocumentName; this.startingPositionOfIncludedRegion = startingPositionOfIncludedRegion; }
public PrimarySourceLocation(IPrimarySourceDocument primarySourceDocument, int startIndex, int length) : base(startIndex, length) { Contract.Requires(primarySourceDocument != null); Contract.Requires(startIndex >= 0 && startIndex <= primarySourceDocument.Length); Contract.Requires(length >= 0 && length <= primarySourceDocument.Length); //Contract.Requires(0 <= startIndex + length); Contract.Requires(startIndex + length <= primarySourceDocument.Length); this.primarySourceDocument = primarySourceDocument; }
/// <summary> /// Flushes accumulated sequence points and re-initializes sequence point state. /// </summary> private void DefineSequencePointsForCurrentDocument() { //^ requires this.currentDocument != null && this.currentDocument != SourceDummy.PrimarySourceDocument ISymUnmanagedDocumentWriter document = this.GetDocumentWriterFor(this.currentDocument); uint seqPointCount = (uint)this.offsets.Count; if (seqPointCount > 0) { uint[] offsets = this.offsets.ToArray(); uint[] startLines = this.startLines.ToArray(); uint[] startColumns = this.startColumns.ToArray(); uint[] endLines = this.endLines.ToArray(); uint[] endColumns = this.endColumns.ToArray(); this.SymWriter.DefineSequencePoints(document, seqPointCount, offsets, startLines, startColumns, endLines, endColumns); } this.currentDocument = null; this.offsets.Clear(); this.startLines.Clear(); this.startColumns.Clear(); this.endLines.Clear(); this.endColumns.Clear(); }
private ISymUnmanagedDocumentWriter GetDocumentWriterFor(IPrimarySourceDocument document) { Contract.Requires(document != null); Contract.Requires(document != SourceDummy.PrimarySourceDocument); ISymUnmanagedDocumentWriter writer; if (!this.documentMap.TryGetValue(document, out writer)) { Guid language = document.Language; Guid vendor = document.LanguageVendor; Guid type = document.DocumentType; writer = this.SymWriter.DefineDocument(document.Location, ref language, ref vendor, ref type); this.documentMap.Add(document, writer); } return writer; }
internal PreprocessorInformation(IPrimarySourceDocument documentToPreprocess, List<IErrorMessage> errors) { this.errors = errors; this.sourceDocument = documentToPreprocess; }
private ISymUnmanagedDocumentWriter GetDocumentWriterFor(IPrimarySourceDocument document) { Contract.Requires(document != null); Contract.Requires(document != SourceDummy.PrimarySourceDocument); string filename = document.Location; ISymUnmanagedDocumentWriter writer; if (!this.documentMap.TryGetValue(filename, out writer)) { Guid language = document.Language; Guid vendor = document.LanguageVendor; Guid type = document.DocumentType; writer = this.SymWriter.DefineDocument(filename, ref language, ref vendor, ref type); if (document.Checksum != null) writer.SetCheckSum(document.ChecksumAlgorithm, (uint)document.Checksum.Length, document.Checksum); this.documentMap.Add(filename, writer); } return writer; }
internal PreprocessorInformation(IPrimarySourceDocument newDocumentToPreprocess, PreprocessorInformation template) { this.sourceDocument = newDocumentToPreprocess; SourceDocumentWithInclusion/*?*/ sourceOfInclusion = null; List<Directive> directives = new List<Directive>(template.Directives); List<IErrorMessage> errors = new List<IErrorMessage>(template.errors); List<ISourceLocation> excludedLocations = new List<ISourceLocation>(template.ExcludedLocations); List<ISourceLocation> includedLocations = new List<ISourceLocation>(template.IncludedLocations); for (int i = 0, n = directives.Count; i < n; i++) { //^ assume newDocumentToPreprocess.IsUpdatedVersionOf(directives[i].SourceLocation.SourceDocument); directives[i] = directives[i].MakeShallowCopy(newDocumentToPreprocess); } for (int i = 0, n = errors.Count; i < n; i++) { ISourceErrorMessage/*?*/ sourceError = errors[i] as ISourceErrorMessage; //^ assume sourceError != null; //^ assume newDocumentToPreprocess.IsUpdatedVersionOf(sourceError.SourceLocation.SourceDocument); errors[i] = sourceError.MakeShallowCopy(newDocumentToPreprocess); } for (int i = 0, n = excludedLocations.Count; i < n; i++) { ISourceLocation excludedLocation = excludedLocations[i]; SourceDocumentWithInclusion/*?*/ idoc = excludedLocation.SourceDocument as SourceDocumentWithInclusion; if (idoc != null) { if (sourceOfInclusion == null || !idoc.IsUpdatedVersionOf(sourceOfInclusion)) sourceOfInclusion = new SourceDocumentWithInclusion(newDocumentToPreprocess, idoc.OriginalLineNumber, idoc.OriginalDocumentName, idoc.StartingPositionOfIncludedRegion); excludedLocations[i] = sourceOfInclusion.GetCorrespondingSourceLocation(excludedLocation); } else { //^ assume newDocumentToPreprocess.IsUpdatedVersionOf(excludedLocation.SourceDocument); excludedLocations[i] = newDocumentToPreprocess.GetCorrespondingSourceLocation(excludedLocation); } } for (int i = 0, n = includedLocations.Count; i < n; i++) { ISourceLocation includedLocation = includedLocations[i]; SourceDocumentWithInclusion/*?*/ idoc = includedLocation.SourceDocument as SourceDocumentWithInclusion; if (idoc != null) { if (sourceOfInclusion == null || !idoc.IsUpdatedVersionOf(sourceOfInclusion)) sourceOfInclusion = new SourceDocumentWithInclusion(newDocumentToPreprocess, idoc.OriginalLineNumber, idoc.OriginalDocumentName, idoc.StartingPositionOfIncludedRegion); includedLocations[i] = sourceOfInclusion.GetCorrespondingSourceLocation(includedLocation); } else { //^ assume newDocumentToPreprocess.IsUpdatedVersionOf(includedLocation.SourceDocument); includedLocations[i] = newDocumentToPreprocess.GetCorrespondingSourceLocation(includedLocation); } } this.directives = directives; this.errors = errors; this.excludedLocations = excludedLocations; this.includedLocations = includedLocations; }
//^ requires startIndex >= 0 && startIndex <= primarySourceDocument.Length; //^ requires length >= 0 && length <= primarySourceDocument.Length; //^ requires 0 <= startIndex + length; //^ requires startIndex + length <= primarySourceDocument.Length; /// <summary> /// Allocates a range of source text that corresponds to an identifiable entity. /// </summary> /// <param name="primarySourceDocument">The document containing the source text of which this location is a subrange.</param> /// <param name="startIndex">The character index of the first character of this location, when treating the source document as a single string.</param> /// <param name="length">The number of characters in this source location.</param> public PrimarySourceLocation(IPrimarySourceDocument primarySourceDocument, int startIndex, int length) : base(startIndex, length) { this.primarySourceDocument = primarySourceDocument; }
public void DefineSequencePoint(ILocation location, uint offset) { IPrimarySourceLocation ploc = null; foreach (IPrimarySourceLocation psloc in this.sourceLocationProvider.GetPrimarySourceLocationsFor(location)) { ploc = psloc; break; } if (ploc == null) return; if (ploc.Document != this.currentDocument && this.currentDocument != null && ploc.Document != SourceDummy.PrimarySourceDocument) this.DefineSequencePointsForCurrentDocument(); if (ploc.Document != SourceDummy.PrimarySourceDocument) this.currentDocument = ploc.PrimarySourceDocument; this.offsets.Add(offset); this.startLines.Add((uint)ploc.StartLine); this.startColumns.Add((uint)ploc.StartColumn); this.endLines.Add((uint)ploc.EndLine); this.endColumns.Add((uint)ploc.EndColumn); }