public void BindTo(Label entity, CommentBinding binding) { Context.TrapWriter.Writer.commentblock_binding(this, entity, binding); }
internal static void commentblock_binding(this TextWriter trapFile, CommentBlock commentBlock, Label entity, CommentBinding binding) { trapFile.WriteTuple("commentblock_binding", commentBlock, entity, (int)binding); }
/// <summary> /// Generate the bindings between a comment and program elements. /// Called once for each commentBlock. /// </summary> /// /// <param name="commentBlock">The comment block.</param> /// <param name="previousElement">The element before the comment block.</param> /// <param name="nextElement">The element after the comment block.</param> /// <param name="parentElement">The parent element of the comment block.</param> /// <param name="cb">Output binding information.</param> void GenerateBindings( ICommentBlock commentBlock, KeyValuePair <Location, Label>?previousElement, KeyValuePair <Location, Label>?nextElement, KeyValuePair <Location, Label>?parentElement, CommentBinding cb ) { EnsureSameFile(commentBlock, ref previousElement); EnsureSameFile(commentBlock, ref nextElement); EnsureSameFile(commentBlock, ref parentElement); if (previousElement != null) { var key = previousElement.Value.Value; cb(key, GetDuplicationGuardKey(key), commentBlock, Binding.Before); } if (nextElement != null) { var key = nextElement.Value.Value; cb(key, GetDuplicationGuardKey(key), commentBlock, Binding.After); } if (parentElement != null) { var key = parentElement.Value.Value; cb(key, GetDuplicationGuardKey(key), commentBlock, Binding.Parent); } // Heuristic to decide which is the "best" element associated with the comment. KeyValuePair <Location, Label>?bestElement; if (previousElement != null && previousElement.Value.Key.EndLine() == commentBlock.Location.StartLine()) { // 1. If the comment is on the same line as the previous element, use that bestElement = previousElement; } else if (nextElement != null && nextElement.Value.Key.StartLine() == commentBlock.Location.EndLine()) { // 2. If the comment is on the same line as the next element, use that bestElement = nextElement; } else if (nextElement != null && previousElement != null && previousElement.Value.Key.EndLine() + 1 == commentBlock.Location.StartLine() && commentBlock.Location.EndLine() + 1 == nextElement.Value.Key.StartLine()) { // 3. If comment is equally between two elements, use the parentElement // because it's ambiguous whether the comment refers to the next or previous element bestElement = parentElement; } else if (nextElement != null && nextElement.Value.Key.StartLine() == commentBlock.Location.EndLine() + 1) { // 4. If there is no gap after the comment, use "nextElement" bestElement = nextElement; } else if (previousElement != null && previousElement.Value.Key.EndLine() + 1 == commentBlock.Location.StartLine()) { // 5. If there is no gap before the comment, use previousElement bestElement = previousElement; } else { // 6. Otherwise, bind the comment to the parent block. bestElement = parentElement; /* if parentElement==null, then there is no best element. The comment is effectively orphaned. * * This can be caused by comments that are not in a type declaration. * Due to restrictions in the dbscheme, the comment cannot be associated with the "file" * which is not an element, and the "using" declarations are not emitted by the extractor. */ } if (bestElement != null) { var label = bestElement.Value.Value; cb(label, GetDuplicationGuardKey(label), commentBlock, Binding.Best); } }