package org.openquark.cal.compiler; import org.openquark.cal.compiler.SourceModel.CALDoc; import org.openquark.cal.compiler.SourceModel.Name; import org.openquark.cal.compiler.SourceModelCodeFormatter.Options; import org.openquark.util.General; /** * this is the formatter for caldoc comments * Comments are first formatted without decorations (ie \/**, *, *\/) * Decorations are added as the final step. */ public class SourceModelCALDocFormatter extends SourceModelTraverser<Options, Void> { /** * System Line separator. */ private static final String EOL = System.getProperty("line.separator"); /** * this is the string used to separate CAL doc paragraphs */ private static final String paragraphBreak = EOL + EOL; /** * this is a regex designed to match the EOL sequence in DOS, MAC or Unix strings * the formatting will convert all EOL in the input caldoc comment to the system * standard. */ final private static String EOLRegex = "(\r\n)|\n|\r"; /** * Internal state indicated whether or not the element is contained within * a pre-formatted context */ private boolean isPreformatted = false; /** * internal flag is used to record when a CR is removed from * the end of a CALDoc text fragment that is output. * It is used to keep track of paragraph breaks that are split across * adjacent plain segments e.g. The CALDoc source model could contain the * following two segments: "end of paragraph1.\n", "\nStart of next paragraph" */ private boolean newLineRemoved = false; /** * this is used to record where an atomic item * (one that cannot be split for word wrapping) starts. */ private int atomicItemStart = 0; /** this is the standard indent used for items and lists */ private final static int STANDARD_INDENT = 4; /** this is the standard indent used for blocks, e.g. author and arg */ private final static int BLOCK_INDENT = 2; /** the string used to open a caldoc comment*/ private final static String calDocStart = "/**"; /** the string used to end a caldoc comment*/ private final static String calDocEnd = " */"; /** the string used to decorate the left hand edge of caldoc comments*/ private final static String calDocLeft = " * "; /** * this is the current indent in number of spaces. This is incremented and decremented * when the formatter enters/leaves certain blocks. */ private int indent = 0; /** The StringBuilder used to build up the CAL source. */ final private StringBuilder sb; /** * Create CALDocFormatter with StringBuilder to write to. * @param sb the stringbuilder to write the comment to. */ SourceModelCALDocFormatter(StringBuilder sb) { this.sb = sb; } /** * trims trailing spaces from a string buffer * @param sb the string buffer to trim */ private void trimRight(StringBuilder sb) { int i = sb.length() - 1; while (i >= 0 && sb.charAt(i) == ' ') { sb.deleteCharAt(i--); } } /** * decorates a comment. * The comment is returned as a single line comment if it is single line * and fits on a single line, otherwise multi line * @param options the options used - provides the max line width */ public void decorate(Options options) { trimRight(sb); if (sb.indexOf(EOL) == -1 && sb.length() + calDocStart.length() + calDocEnd.length() + 1< options.getMaxColumns()) { sb.insert(0, calDocStart + " "); sb.append(calDocEnd + EOL); } else { int i=0; sb.insert(0, calDocLeft); while( (i = sb.indexOf(EOL, i)) > 0) { i += EOL.length(); sb.insert(i, calDocLeft); } sb.insert(0, calDocStart + EOL); sb.append(EOL + calDocEnd + EOL); } } /** * Creates a string of the specified number of spaces. * @param nSpaces * @return a String containing the specified number of spaces. */ private static String space(int nSpaces) { StringBuilder sb = new StringBuilder(nSpaces); for (int i = 0; i < nSpaces; ++i) { sb.append(' '); } return sb.toString(); } /** * Escapes the specified string for inclusion in the source representation * of a CALDoc comment. * * @param string * the string to be escaped. * @return the escaped version of the specified string. */ private static String caldocEscape(String string) { String augmentedString = EOL + string; // augment the string so that // the @-escaping can be // uniformly applied to even the // first @ after leading spaces String augmentedStringWithEscapedAtSigns = augmentedString.replaceAll( "@", "\\\\@"); String augmentedEscapedString = augmentedStringWithEscapedAtSigns .replaceAll("\\{@", "\\\\{@"); // the first arg is the regular // expression '{@', the second // arg the replacement string // '\{@' return augmentedEscapedString.substring(EOL.length()); } /** * Get the current offset from the start of the line. * * @param sb * @return the offset from the start of the last line. */ private static int getOffset(StringBuilder sb) { int offset = sb.length() - sb.lastIndexOf(EOL) - EOL.length(); if (offset < 0) { offset = 0; } return offset; } /** * Formats the specified string into a suitably indented block of text * for a CALDoc comment in source form. * * @param string * the string to be formatted. * @param info * the current formatting information * @return the formatted string. */ private String formatIntoCALDocLines(String string, Options info) { if (isCalDocContentOnLine() && sb.charAt(sb.length() -1) == ' ' && string.length() >0 && string.charAt(0) == ' ') { string = string.substring(1); } if (isPreformatted) { return string.replaceAll(EOLRegex, EOL +space(indent)); } else { string = wrapCalDocLines(string, getOffset(sb), info .getMaxColumns()); return string.replaceAll("(" + EOLRegex + ")[ \t\f]*", EOL +space(indent)); } } /** * Merge lines by removing each single CR and replacing with a space, * but preserving CRCR as this indicates paragraph break. * * @param text * @return the merged text */ private String mergeLines(String text) { StringBuilder str = new StringBuilder(text); int i = 0; while (i < str.length()) { if (str.charAt(i) == '\n') { if ((i + 1 >= str.length() || str.charAt(i + 1) != '\n')) { str.replace(i, i + 1, " "); } i++; } i++; } return str.toString().replaceAll(" +", " "); } /** * This is used to break CAlDoc text at spaces. We keep track of CR that * are removed as adjacent CRs that indicate a paragraph break can * appear across adjacent text segments. * * @param text * the text to wrap * @param linePos * the position on the current line * @param width * the text width. * @return the text with single new lines replaced by spaces */ private String wrapCalDocLines(String text, int linePos, int width) { String normalizedText = text.replaceAll("[\t ]+", " ") // compress // multiple // spaces .replaceAll(EOLRegex, "\n") // use canonical linefeeds .replaceAll(" ?\n ?", "\n") // trim lines .replaceAll("\n[\t ]*", "\n"); // strip spaces from start of comment if (normalizedText.length() == 0) { return ""; } if (normalizedText.matches("(?s)\n *")) { if (newLineRemoved) { newLineRemoved = false; return paragraphBreak; } else { newLineRemoved = true; return ""; } } String prefix = ""; if (newLineRemoved) { prefix = " "; } if (normalizedText.matches("(?s)\n\n.*")) { prefix = paragraphBreak; linePos = 0; normalizedText = normalizedText.substring(2); newLineRemoved = false; } StringBuilder buffer = new StringBuilder(mergeLines(normalizedText)); int index = 0; if (normalizedText.matches("(?s)\n[^\n].*")) { if (newLineRemoved) { prefix = paragraphBreak; linePos = 0; } normalizedText = normalizedText.substring(1); } if (normalizedText.matches("(?s).*[^\n]\\n *")) { newLineRemoved = true; } else { newLineRemoved = false; } while (buffer.length() - index > width - linePos) { // if the text contains a line feed before the line stop, // there's // no need to wrap. int nl = buffer.indexOf("\n", index); if (nl > 0 && nl <= index + width - linePos) { index = nl + 1; linePos = 0; continue; } // find space to break line at, looking back from line limit int space = buffer.lastIndexOf(" ", index + width - linePos); // if we failed to find a space looking back, we have no choice // but to // look for the first space beyond the line limit if (space < index) { space = buffer.indexOf(" ", index + width - linePos); } if (space < 0 || space == buffer.length() - 1) { break; } // trim trailing spaces from line while (space >= index && buffer.charAt(space) == ' ') { buffer.delete(space, space + 1); space--; } space++; buffer.insert(space, EOL); index = space + EOL.length(); linePos = 0; } return prefix + buffer.toString().replaceAll(" +", " "); } /** * @param moduleName * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_Name_Module(Name.Module moduleName, Options options) { SourceModel.verifyArg(moduleName, "moduleName"); moduleName.getQualifier().accept(this, options); if (moduleName.getQualifier().getNComponents() > 0) { sb.append("."); } sb.append(moduleName.getUnqualifiedModuleName()); return null; } /** * @param qualifier * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_Name_Module_Qualifier( Name.Module.Qualifier qualifier, Options options) { SourceModel.verifyArg(qualifier, "qualifier"); for (int i = 0, n = qualifier.getNComponents(); i < n; ++i) { if (i > 0) { sb.append("."); } sb.append(qualifier.getNthComponents(i)); } return null; } /** * @param cons * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_Name_DataCons(Name.DataCons cons, Options options) { SourceModel.verifyArg(cons, "cons"); if (cons.getModuleName() != null) { cons.getModuleName().accept(this, options); } if (cons.getModuleName() != null) { sb.append('.'); } sb.append(cons.getUnqualifiedName()); return null; } /** * @param function * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_Name_Function(Name.Function function, Options options) { SourceModel.verifyArg(function, "function"); if (function.getModuleName() != null) { function.getModuleName().accept(this, options); sb.append('.'); } sb.append(function.getUnqualifiedName()); return null; } /** * @param typeClass * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_Name_TypeClass(Name.TypeClass typeClass, Options options) { SourceModel.verifyArg(typeClass, "typeClass"); if (typeClass.getModuleName() != null) { typeClass.getModuleName().accept(this, options); sb.append('.'); } sb.append(typeClass.getUnqualifiedName()); return null; } /** * @param cons * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_Name_TypeCons(Name.TypeCons cons, Options options) { SourceModel.verifyArg(cons, "cons"); if (cons.getModuleName() != null) { cons.getModuleName().accept(this, options); sb.append('.'); } sb.append(cons.getUnqualifiedName()); return null; } /** * @param cons * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_Name_WithoutContextCons(Name.WithoutContextCons cons, Options options) { SourceModel.verifyArg(cons, "cons"); if (cons.getModuleName() != null) { cons.getModuleName().accept(this, options); sb.append('.'); } sb.append(cons.getUnqualifiedName()); return null; } //TODO-MB /** * @param comment * the source model element to be traversed * @param options * unused argument * @return null */ protected Void visit_CALDoc_Comment_Helper(CALDoc.Comment comment, Options options) { comment.getDescription().accept(this, options); for (int i = 0, n = comment.getNTaggedBlocks(); i < n; i++) { comment.getNthTaggedBlock(i).accept(this, options); } return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_Plain( CALDoc.TextSegment.Plain segment, Options options) { SourceModel.verifyArg(segment, "segment"); String escapedAndNewlineNormalizedText = caldocEscape(General .toPlatformLineSeparators(segment.getText())); //TODO-MB String s = formatIntoCALDocLines(escapedAndNewlineNormalizedText, options); if (!isCalDocContentOnLine()) { s = s.replaceAll("^ +", ""); } sb.append(s); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_Preformatted( CALDoc.TextSegment.Preformatted segment, Options options) { SourceModel.verifyArg(segment, "segment"); SourceModelCALDocFormatter segmentFormatter = new SourceModelCALDocFormatter(sb); segmentFormatter.isPreformatted = true; final int nSegments = segment.getNSegments(); for (int i = 0; i < nSegments; i++) { segment.getNthSegment(i).accept(segmentFormatter, options); } return null; } /** * this is used to mark the beginning of a CAlDoc item that cannot be * split */ private void beginAtomicCalDocItem() { atomicItemStart = sb.length(); } /** * this is used to mark the end of an atomic caldoc item. If the item extends * past the line's end it is moved to the next line. * * @param options */ private void endAtomicCalDocItem(Options options) { assert(atomicItemStart >= 0); if (getOffset(sb) > options.getMaxColumns() && sb.indexOf(EOL, atomicItemStart) == -1) { //if we are breaking at a space, the space must be removed if (sb.charAt(atomicItemStart) == ' ') { sb.deleteCharAt(atomicItemStart); } sb.insert(atomicItemStart, EOL + space(indent)); } } /** * Starts a new calddoc line with the appropriate left margin indent */ private void emitCalDocLine() { sb.append(EOL).append( space(indent)); } /** * Write out an atomic piece of CAL doc text to the output buffer if the * text is too long to fit on the current line, a new line is started. * * Start the text on a new line if the text is too long and there is a * space at the beginning. * * @param text * @param options */ private void emitCalDocText(String text, Options options) { if (text.length() == 0) { return; } if (getOffset(sb) + text.length() > options.getMaxColumns() && isCalDocContentOnLine() && (sb.charAt(sb.length()-1) == ' ' || text.charAt(text.length()-1) == ' ')) { emitCalDocLine(); sb.append(text); } else { sb.append(text); } } /** * Write out a closing tag * * Enforces the rule that there must be a space before the atomic item. * @param options - formatting options */ private void emitCloseTag(Options options) { sb.append("@}"); } /** * Checks to see if there is content on the current line * * @return true if there is some content on the last caldoc line in the * output buffer */ private boolean isCalDocContentOnLine() { int start = sb.lastIndexOf(General.SYSTEM_EOL, sb.length()); if (start < 0) { start = 0; } else { start += General.SYSTEM_EOL.length(); } while(start < sb.length()) { if (sb.charAt(start++) != ' ') { return true; } } return false; } /** * Start a new CalDoc line if there is content on the current line */ private void ensureOnNewLine() { if (isCalDocContentOnLine()) { emitCalDocLine(); } } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_URL( CALDoc.TextSegment.InlineTag.URL segment, Options options) { SourceModel.verifyArg(segment, "segment"); Options info = options; sb.append("{@url "); beginAtomicCalDocItem(); segment.getContent().accept(this, info); emitCloseTag(options); endAtomicCalDocItem(options); return null; } private void visit_CALDoc_TextSegment_InlineTag_Link_WithContext_Helper( CALDoc.TextSegment.InlineTag.Link.WithContext link, Options info) { emitCalDocText("{@link ", info); emitCalDocText(link.getContextKeyword() + " = ", info); beginAtomicCalDocItem(); link.getAbstractCrossReference().accept(this, info); sb.append("@}"); endAtomicCalDocItem(info); } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Link_Function( CALDoc.TextSegment.InlineTag.Link.Function segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_Link_WithContext_Helper(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Link_Module( CALDoc.TextSegment.InlineTag.Link.Module segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_Link_WithContext_Helper(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Link_TypeCons( CALDoc.TextSegment.InlineTag.Link.TypeCons segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_Link_WithContext_Helper(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Link_DataCons( CALDoc.TextSegment.InlineTag.Link.DataCons segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_Link_WithContext_Helper(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Link_TypeClass( CALDoc.TextSegment.InlineTag.Link.TypeClass segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_Link_WithContext_Helper(segment, options); return null; } private void visit_CALDoc_TextSegment_InlineTag_Link_WithoutContext_Helper( CALDoc.TextSegment.InlineTag.Link.WithoutContext segment, Options info) { emitCalDocText("{@link ", info); beginAtomicCalDocItem(); segment.getAbstractCrossReference().accept(this, info); sb.append("@}"); endAtomicCalDocItem(info); } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Link_ConsNameWithoutContext( CALDoc.TextSegment.InlineTag.Link.ConsNameWithoutContext segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_Link_WithoutContext_Helper( segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Link_FunctionWithoutContext( CALDoc.TextSegment.InlineTag.Link.FunctionWithoutContext segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_Link_WithoutContext_Helper( segment, options); return null; } private void visit_CALDoc_TextSegment_InlineTag_WithTextBlockContent( CALDoc.TextSegment.InlineTag.InlineTagWithTextBlockContent segment, Options info) { emitCalDocText("{@" + segment.getTagName(), info); emitCalDocText(" ", info); segment.getContent().accept(this, info); emitCloseTag(info); } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_TextFormatting_Emphasized( CALDoc.TextSegment.InlineTag.TextFormatting.Emphasized segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_WithTextBlockContent(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_TextFormatting_StronglyEmphasized( CALDoc.TextSegment.InlineTag.TextFormatting.StronglyEmphasized segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_WithTextBlockContent(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_TextFormatting_Superscript( CALDoc.TextSegment.InlineTag.TextFormatting.Superscript segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_WithTextBlockContent(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_TextFormatting_Subscript( CALDoc.TextSegment.InlineTag.TextFormatting.Subscript segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_WithTextBlockContent(segment, options); return null; } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Summary( CALDoc.TextSegment.InlineTag.Summary segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_WithTextBlockContent(segment, options); return null; } private void visit_CALDoc_TextSegment_InlineTag_WithPreformattedContent( CALDoc.TextSegment.InlineTag.InlineTagWithPreformattedContent segment, Options info) { final String open = "{@" + segment.getTagName() + " "; final String close = "@}"; StringBuilder codeBlock = new StringBuilder(); SourceModelCALDocFormatter contentFormatter = new SourceModelCALDocFormatter(codeBlock); contentFormatter.isPreformatted = true; segment.getContent().accept(contentFormatter, info); // does the code item span more than one line? if (codeBlock.indexOf(EOL ) >= 0) { ensureOnNewLine(); emitCalDocText(open, info); sb.append(codeBlock.toString().replaceAll("(?s)(" + EOLRegex + ") ", EOL)); sb.append(close); } else { // no - make sure the open, text and close are one atomic item emitCalDocText(open + codeBlock.toString() + close, info); } } /** * @param segment * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_Code( CALDoc.TextSegment.InlineTag.Code segment, Options options) { SourceModel.verifyArg(segment, "segment"); visit_CALDoc_TextSegment_InlineTag_WithPreformattedContent(segment, options); return null; } private void visit_CALDoc_TextSegment_InlineTag_List( CALDoc.TextSegment.InlineTag.List list, Options info) { // start the ordered list on a new line if we're not already on one ensureOnNewLine(); sb.append("{@").append(list.getTagName()); indent += STANDARD_INDENT; for (int i = 0; i < list.getNItems(); i++) { emitCalDocLine(); list.getNthItem(i).accept(this, info); } indent -= STANDARD_INDENT; emitCalDocLine(); sb.append("@}"); } /** * @param list * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_List_Unordered( CALDoc.TextSegment.InlineTag.List.Unordered list, Options options) { SourceModel.verifyArg(list, "list"); visit_CALDoc_TextSegment_InlineTag_List(list, options); return null; } /** * @param list * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_List_Ordered( CALDoc.TextSegment.InlineTag.List.Ordered list, Options options) { SourceModel.verifyArg(list, "list"); visit_CALDoc_TextSegment_InlineTag_List(list, options); return null; } /** * @param item * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextSegment_InlineTag_List_Item( CALDoc.TextSegment.InlineTag.List.Item item, Options options) { SourceModel.verifyArg(item, "item"); Options info = options; emitCalDocText("{@item ", options); int itemStart = sb.length(); indent += STANDARD_INDENT; item.getContent().accept(this, info); indent -= STANDARD_INDENT; // does the item span more than one line? if (sb.indexOf(EOL, itemStart) > 0 ) { ensureOnNewLine(); } emitCloseTag(options); return null; } /** * @param block * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TextBlock(CALDoc.TextBlock block, Options options) { SourceModel.verifyArg(block, "block"); for (int i = 0, nSegments = block.getNSegments(); i < nSegments; i++) { newLineRemoved = false; block.getNthSegment(i).accept(this, options); } return null; } public void taggedBlockHelper(CALDoc.TaggedBlock taggedBlock, Options options) { ensureOnNewLine(); } /** * @param authorBlock * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_Author( CALDoc.TaggedBlock.Author authorBlock, Options options) { SourceModel.verifyArg(authorBlock, "authorBlock"); ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.Author.AUTHOR_TAG ).append(" "); authorBlock.getTextBlock().accept(this, options); return null; } /** * @param deprecatedBlock * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_Deprecated( CALDoc.TaggedBlock.Deprecated deprecatedBlock, Options options) { SourceModel.verifyArg(deprecatedBlock, "deprecatedBlock"); ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.Deprecated.DEPRECATED_TAG).append(" "); indent += BLOCK_INDENT; deprecatedBlock.getTextBlock().accept(this, options); indent -= BLOCK_INDENT; return null; } /** * @param returnBlock * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_Return( CALDoc.TaggedBlock.Return returnBlock, Options options) { SourceModel.verifyArg(returnBlock, "returnBlock"); ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.Return.RETURN_TAG).append(" "); indent += BLOCK_INDENT; returnBlock.getTextBlock().accept(this, options); indent -= BLOCK_INDENT; return null; } /** * @param versionBlock * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_Version( CALDoc.TaggedBlock.Version versionBlock, Options options) { SourceModel.verifyArg(versionBlock, "versionBlock"); ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.Version.VERSION_TAG).append(" "); indent += BLOCK_INDENT; versionBlock.getTextBlock().accept(this, options); indent -= BLOCK_INDENT; return null; } /** * @param argBlock * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_Arg( CALDoc.TaggedBlock.Arg argBlock, Options options) { SourceModel.verifyArg(argBlock, "argBlock"); ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.Arg.ARG_TAG).append(' ') .append(argBlock.getArgName().getName().getCalSourceForm()); indent += BLOCK_INDENT; argBlock.getTextBlock().accept(this, options); indent -= BLOCK_INDENT; return null; } /** * @param function * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_See_Function( CALDoc.TaggedBlock.See.Function function, Options options) { SourceModel.verifyArg(function, "function"); Options info = options; ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.See.SEE_TAG).append( " function = "); function.getNthFunctionName(0).accept(this, info); for (int i = 1, n = function.getNFunctionNames(); i < n; i++) { sb.append(", "); beginAtomicCalDocItem(); function.getNthFunctionName(i).accept(this, info); endAtomicCalDocItem(options); } return null; } /** * @param module * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_See_Module( CALDoc.TaggedBlock.See.Module module, Options options) { SourceModel.verifyArg(module, "module"); Options info = options; ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.See.SEE_TAG).append( " module = "); module.getNthModuleName(0).accept(this, info); for (int i = 1, n = module.getNModuleNames(); i < n; i++) { sb.append(", "); beginAtomicCalDocItem(); module.getNthModuleName(i).accept(this, info); endAtomicCalDocItem(options); } return null; } /** * @param typeCons * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_See_TypeCons( CALDoc.TaggedBlock.See.TypeCons typeCons, Options options) { SourceModel.verifyArg(typeCons, "typeCons"); Options info = options; ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.See.SEE_TAG).append( " typeConstructor = "); typeCons.getNthTypeConsName(0).accept(this, info); for (int i = 1, n = typeCons.getNTypeConsNames(); i < n; i++) { sb.append(", "); beginAtomicCalDocItem(); typeCons.getNthTypeConsName(i).accept(this, info); endAtomicCalDocItem(options); } return null; } /** * @param dataCons * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_See_DataCons( CALDoc.TaggedBlock.See.DataCons dataCons, Options options) { Options info = options; ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.See.SEE_TAG).append( " dataConstructor = "); dataCons.getNthDataConsName(0).accept(this, info); for (int i = 1, n = dataCons.getNDataConsNames(); i < n; i++) { sb.append(", "); beginAtomicCalDocItem(); dataCons.getNthDataConsName(i).accept(this, info); endAtomicCalDocItem(options); } return null; } /** * @param typeClass * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_TaggedBlock_See_TypeClass( CALDoc.TaggedBlock.See.TypeClass typeClass, Options options) { SourceModel.verifyArg(typeClass, "typeClass"); Options info = options; ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.See.SEE_TAG).append( " typeClass = "); typeClass.getNthTypeClassName(0).accept(this, info); for (int i = 1, n = typeClass.getNTypeClassNames(); i < n; i++) { sb.append(", "); beginAtomicCalDocItem(); typeClass.getNthTypeClassName(i).accept(this, info); endAtomicCalDocItem(options); } return null; } /** * @param reference * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_CrossReference_Function( CALDoc.CrossReference.Function reference, Options options) { SourceModel.verifyArg(reference, "reference"); if (reference.isChecked()) { reference.getName().accept(this, options); } else { sb.append('\"'); reference.getName().accept(this, options); sb.append('\"'); } return null; } /** * @param reference * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_CrossReference_Module( CALDoc.CrossReference.Module reference, Options options) { SourceModel.verifyArg(reference, "reference"); if (reference.isChecked()) { reference.getName().accept(this, options); } else { sb.append('\"'); reference.getName().accept(this, options); sb.append('\"'); } return null; } /** * @param reference * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_CrossReference_TypeCons( CALDoc.CrossReference.TypeCons reference, Options options) { SourceModel.verifyArg(reference, "reference"); if (reference.isChecked()) { reference.getName().accept(this, options); } else { sb.append('\"'); reference.getName().accept(this, options); sb.append('\"'); } return null; } /** * @param reference * the source model element to be traversed * @param options * unused argument * @return null */ public Void visit_CALDoc_CrossReference_DataCons( CALDoc.CrossReference.DataCons reference, Options options) { SourceModel.verifyArg(reference, "reference"); if (reference.isChecked()) { reference.getName().accept(this, options); } else { sb.append('\"'); reference.getName().accept(this, options); sb.append('\"'); } return null; } /** * @param reference * the source model element to be traversed * @param options * the formatting options * @return null */ public Void visit_CALDoc_CrossReference_TypeClass( CALDoc.CrossReference.TypeClass reference, Options options) { SourceModel.verifyArg(reference, "reference"); if (reference.isChecked()) { reference.getName().accept(this, options); } else { sb.append('\"'); reference.getName().accept(this, options); sb.append('\"'); } return null; } /** * @param reference * the source model element to be traversed * @param options * the formatting options * @return null */ public Void visit_CALDoc_CrossReference_WithoutContextCons( CALDoc.CrossReference.WithoutContextCons reference, Options options) { SourceModel.verifyArg(reference, "reference"); if (reference.isChecked()) { reference.getName().accept(this, options); } else { sb.append('\"'); reference.getName().accept(this, options); sb.append('\"'); } return null; } /** * @param seeBlock * the source model element to be traversed * @param options * the formatting options * @return null */ public Void visit_CALDoc_TaggedBlock_See_WithoutContext( CALDoc.TaggedBlock.See.WithoutContext seeBlock, Options options) { SourceModel.verifyArg(seeBlock, "seeBlock"); ensureOnNewLine(); sb.append(CALDoc.TaggedBlock.See.SEE_TAG).append(" "); seeBlock.getNthReferencedName(0).accept(this, options); for (int i = 1, n = seeBlock.getNReferencedNames(); i < n; i++) { sb.append(", "); beginAtomicCalDocItem(); seeBlock.getNthReferencedName(i).accept(this, options); endAtomicCalDocItem(options); } return null; } }