2 above: the information in refDocs.xml is used for several purposes, not just code generators. We don't want to hide this information about inheriting types, and the lookup to find the base type is too trivial to implement for us to consider adding some kind of shortcut.
Announcement
Collapse
No announcement yet.
X
-
I suspect that adding an attribute that specifies the root JavaScript type is also trivial to implement (whether string, number, boolean etc.), would greatly simplify code generation, and would also be useful in the documentation (I've wanted it since way before the TypeScript project). AFAIK, the whole concept of the baseType was introduced in this thread so I assumed that it was meant for code generation. I didn't realize it was being used for anything else, but you're right, I can easily add code to traverse the inheritance chain and find the atomic type, assuming there are no missing links in the chain, misspellings or other issues like we've seen in the inheritsFrom attribute.
Comment
-
The baseType is now also displayed by the SmartClient Reference and allows better type guessing in our Visual Tools. It is not just for code generation.
You started out saying a root type would "greatly simplify code generation" but went on to say you could "easily add code to .. find the atomic type". Well, we agree with the latter assessment. This requires just a trivial helper method with a simple iteration inside of it.
Note, although there are no breaks in the baseType inheritance chain and our tools would catch it if there were, we would recommend falling back to type "string" if something goes wrong in baseType lookup.
Comment
-
Currently, the fail-safe is any as that works in TypeScipt. When I said it would greatly simplify gode-generation, I was referring to not only the current issue, but also to all of the other special stuff (lists of string types, number types, Callback types etc.) that I've already put in place that would have been unnecessary if a rootType attribute existed and for FUTURE code generation if that ever happens for a new language or something. Yes, I've taken care of most of it now and will implement the iterator to handle inherited baseTypes. I'm just suggesting that a rootType would have been, and could be in the future, very useful. Also, for the user-readable documentation, I would like to see something that says it is really just a string, rather than click through a bunch of links just to find out that it's a string. A rootType attribute would be perfect for this.
Comment
-
Any system, doc viewer or code generator etc, can trivially look up the root type. We don't think it makes sense to add extra information to an already large file to obviate a trivial lookup. Let's stop kicking that dead horse..
Not sure what that other complexity is that you're referring to. The information we've added over various enhancements should have allowed you to eliminate hardcoded lists of string or numeric types, classes missing inheritance information, etc. We eliminated all such extra information from our processes for generating SGWT APIs.
Comment
-
The Errors.txt file is generated every day (assuming everything works). The current list of string types without a baseType is listed here:
Code:Attributes suspected as string types but do not have the baseType set: 47. === URL:32 === 1. attr:ActiveXControl.codeBase, valueType=URL 2. attr:Canvas.appImgDir, valueType=URL 3. attr:DataSource.dataURL, valueType=URL 4. attr:DateChooser.nextMonthIcon, valueType=URL 5. attr:DateChooser.nextMonthIconRTL, valueType=URL 6. attr:DateChooser.nextYearIcon, valueType=URL 7. attr:DateChooser.nextYearIconRTL, valueType=URL 8. attr:DateChooser.prevMonthIcon, valueType=URL 9. attr:DateChooser.prevMonthIconRTL, valueType=URL 10. attr:DateChooser.prevYearIcon, valueType=URL 11. attr:DateChooser.prevYearIconRTL, valueType=URL 12. attr:DrawImage.src, valueType=URL 13. attr:DynamicForm.action, valueType=URL 14. attr:DynamicForm.validationURL, valueType=URL 15. attr:Flashlet.codeBase, valueType=URL 16. attr:Flashlet.pluginsPage, valueType=URL 17. attr:Flashlet.src, valueType=URL 18. attr:FusionChart.chartsBaseURL, valueType=URL 19. attr:FusionChart.chartURL, valueType=URL 20. attr:HTMLFlow.contentsURL, valueType=URL 21. attr:ImgProperties.imgDir, valueType=URL 22. attr:ImgProperties.src, valueType=URL 23. attr:ImgTab.labelSkinImgDir, valueType=URL 24. attr:ImgTab.skinImgDir, valueType=URL 25. attr:ListGrid.headerMenuButtonIcon, valueType=URL 26. attr:Mail.templateFile, valueType=URL 27. attr:OperationBinding.dataURL, valueType=URL 28. attr:RPCRequest.actionURL, valueType=URL 29. attr:StretchImgButton.labelSkinImgDir, valueType=URL 30. attr:SVG.pluginsPage, valueType=URL 31. attr:SVG.src, valueType=URL 32. attr:ViewLoader.viewURL, valueType=URL === DOMElement:2 === 1. attr:Canvas.htmlElement, valueType=DOMElement 2. attr:DOMGrid.rootElement, valueType=DOMElement === CSSStyle:1 === 1. attr:Dialog.messageStyle, valueType=CSSStyle === URI:2 === 1. attr:SchemaSet.schemaNamespace, valueType=URI 2. attr:WebService.serviceNamespace, valueType=URI === HTML:7 === 1. attr:GroupNode.groupTitle, valueType=HTML 2. attr:Hilite.htmlAfter, valueType=HTML 3. attr:Hilite.htmlBefore, valueType=HTML 4. attr:Hilite.replacementValue, valueType=HTML 5. attr:ListGridRecord.singleCellValue, valueType=HTML 6. attr:MenuItem.title, valueType=HTML 7. attr:TreeNode.title, valueType=HTML === Field:2 === 1. attr:FormulaBuilder.field, valueType=Field 2. attr:SummaryBuilder.field, valueType=Field === FormItemClassname:1 === 1. attr:Operator.editorType, valueType=FormItemClassname
Here's a section of my C# code that I maintain to deal with inconsistent types. I know that some of them may be fixed by now but this illustrates the issues I've found. With these lists, it mostly all works. The next guy to try code generation will end up making similar lists (minus the ones that are fixed of course).
Code:// To fix missing inheritsFrom attributes Dictionary<string, string> dicInherits = new Dictionary<string, string>() { { "Layout", "Canvas"} , { "VLayout", "Layout"} , { "HLayout", "Layout" } , { "PortalLayout", "Layout" } , { "ToolStripButton", "Button" } // Or is is stretchImgButton? Documentation is conflicted. , { "SectionStack", "VLayout" } , { "BaseWidget", "Class" } , { "ToolStrip", "Layout" } , { "RestDataSource", "DataSource" } , { "HTMLPane", "HTMLFlow" } , { "DataSource", "Class" } , { "Menu", "ListGrid" } , { "ResultSet", "Class" } , { "ImgButton", "Img" } , { "Portlet", "Window" } , { "Time", "Class" } , { "RPCRequest", "Class" } , { "FormItem", "Class" } , { "MathFunction", "Class" } }; // These are all really just a JavaScript number string[] numberTypes = { "Number", "PositiveInteger", "Integer", "Float", "double", "int" }; // Thease are all really just a JavaScript boolean string[] boolTypes = { "Boolean", "bool" }; // Don't know how to deal with these so just make them any for now string[] anyTypes = { "Transaction Object" , "Object<String,SummaryFunction>" , "Object" , "object" , "Any" , "rect" , "measure" , "map" , "discovertreesettings" , "stringmethod" , "map<string,string>" , "RecordList" , "record properties" , "record" , "function" , "PrimaryKeys" , "subClass" , "Widget" , "Widgets" , "arguments" , "objects" , "button object" , "button widget" , "DataSourceRecord" , "DataSourceRecords" , "PKValue" , "varies" , "TimerEvent" // , "Callback" }; // These are all really Callbacks string[] callbackTypes = { "rpccallback", "AnimationCallback", "PrintCanvasCallback", "DataURLCallback", "ClientOnlyDataSourceCallback", "CollapseSectionCallback", "ExpandSectionCallback", "GetFileVersionCallback", "HasFileCallback", "HideSectionCallback" , "PaletteNodeCallback", "ShowSectionCallback", "ValidationStatusCallback", "GetFileCallback", "MessagingCallback", "ProcessCallback", "LoadScreenCallback" , "RPCQueueCallback", "CanPlayCallback", "PlaybackCompleteCallback", "CanPlayCallback", "PlaybackCompleteCallback", "TabIndexUpDatedCallback","ShiftFocusCallback" , "ExportImageCallback" }; // These are extra words that don't really refer to a type. They will be removed. string[] nonTypes = { "Multiautochild", "Autochild", "instance" }; //, "| subClass" }; // Infrequent types that would be difficult to fit in a general rule private Dictionary<string, string> weirdTypes = new Dictionary<string, string>() { {"Array of Array of int", "Array<Array<number>>" } , {"Map<Prefix,URI>", "Map<string, string>" } , {"Response", "RPCResponse | DSResponse" } , {"Request", "RPCRequest | DSRequest" } }; // These are things marked as Classes but do not inherit from Class. string[] notClass = { "isc" , "Date" , "Browser" , "Callbacks" , "WSRequest" , "ServerObject" , "History" , "String" , "TooLStripSeparatorEditProxy" , "SelectionOutline" , "VisualBuilder" , "EBay" , "FileLoader" , "FacetValue" }; // Not working for the reason listed Dictionary<string, string> excludedClasses = new Dictionary<string, string> { { "BooleanItem", "Extends CycleItem but CycleItem is not defined." } , { "ComboBoxItem", "Interface 'ComboBoxItem' incorrectly extends interface 'TextItem'. Types of property 'canEditCriterion' are incompatible." } , {"MultiComboBoxItem" , "Cannot find name 'ComboBoxItem'" } // , {"MathFunction" , "" } , { "MultiFileItem" , "Extends RelationItem but RelationItem is not defined" } , { "PickListMenu" , "Extends ScrollingMenu but ScrollingMenu is not defined" } , { "RelativeDateItem" , "Interface 'RelativeDateItem' incorrectly extends interface 'CanvasItem'. Types of property 'valueField' are incompatible." } , { "RichTextItem" , "Interface 'RichTextItem' incorrectly extends interface 'CanvasItem'. Types of property 'colSpan' are incompatible." } , { "ToolbarItem" , "Interface 'ToolbarItem' incorrectly extends interface 'CanvasItem'. Types of property 'colSpan' are incompatible." } }; // Really just strings, hopefully they'll be putting in baseType='string' so we won't need this list anymore. string[] stringTypes = { "ListGridGroupState" , "RelativeDateString" , "CSSClass" , "CSSText" , "CSSColor" , "CSSClassName" , "CSSStyleName" , "Color" , "SCClassName" , "SCImgURL" , "DataPath" , "DateInputFormat" , "ListGridFieldState" , "ListGridSelectionState" , "ListGridSelectedState" , "ListGridSortState" , "ListGridViewState" , "TreeGridOpenState" , "TreeGridViewState" , "FormItemBaseStyle" , "VelocityExpression" , "XPathExpression" , "HTMLString" , "DetailViewerViewState" , "FormatString" , "character" , "AutoTestLocator" , "ListGridViewState" // , "identifier" , "align" , "stringMethod" , "String" , "global ID" , "HTML Element" // Check this BEFORE HTML , "HTML" , "ElementName" , "XPath" , "URI" , "Prefix" , "Type" , "string Expression" , "String Expression" , "keyChar" , "animateShowEffectId" , "DOMElement", "DOM Element" , "datasource id", "URL", "id", "fieldNames", "fieldName", "Field", "Fields", "facetId", "facetIds", "facetValueGroupId" , "class object" /*, "KeyIdentifier", "keyidentifier",*/, "keyidentifer", "DSField" , "identifier", "string", "operationid", "formlayouttype", "domelement", "itemName" , "color", "urn", "valign", "classname", "cssclass" ,"CSSStyle", "name", "DataURLFormat", "FormItemClassname"}; // Skip these because they cause weird problems (redefined in subclasses?) string[] excludedAttributes = { "valuesManager", "ValuesManager", "dataProperties", "State", "dataGradients", "activeAreaHTML"};
Comment
-
We're double-checking on URL, URI and HTML. All of those were intended to receive baseType markers. The other two are typos and we'll get those too.
It looks like almost all of the "hardcoding" predates the many, many fixes we've announced in this thread. Do you need us to go back over those, or did you just not get around to updating after each fix?
Comment
-
I'm sure many of them are unnecessary now but it's a pain to go test each thing every time there's an update so if the generator still works, I don't mess with it. At some point I will clean it up. Just showing, in general, the complexities that I've dealt with so far, some of which I am still dealing with. In general, the stuff I'd like you to go over is the stuff that I manage to get into the Errors.txt file. And by looking at the Progress page, I can see that many have gone down to 0, which is great.
As long as we're making progress though, it's all good. There are actually more things that could improve the docs but they're more nit-picky and I'm saving them until after the big stuff is fixed (inconsistent casing for example).
Comment
-
We definitely appreciate that before the fixes noted in this thread, some of those lists would have been necessary. As far as the "next guy", we believe it's the case that he won't need any such lists, and whenever you have time to check, that would be nice to confirm.
A couple of points on your lists (possibly covered before):
1. DOMElement is not a string type, this refers to native DOM elements as returned by standard DOM APIs like getElementById(). TypeScript surely has something appropriate to map this to.
2. Integer, Float etc are not just variants of Number, they convey that only integral or decimal values are expected and supported. If there is no corresponding TypeScript notion, we would suggest mapping to Number but then adding a note in the doc ("Decimal value expected and allowed" or similar)
3. similarly, "Boolean" vs "boolean" conveys whether null is allowed and expected (and the one typo of "bool" has been fixed for a long time)
4. any method defined on the "Callbacks" object can be assumed to be a callback. This is a SmartClient idiomatic way of defining things, but should not require a list of hardcoded callback names (which would be fragile)
5. "AutoChild" and "MultiAutoChild" are not really "extra" words - although you probably need to strip them out to figure out the TypeScript type, it makes sense to provide a link in the generated doc to the AutoChild / MultiAutoChild usage information, as we do in the SmartClient Reference
Comment
-
1. DOMElement is not a string type, this refers to native DOM elements as returned by standard DOM APIs like getElementById(). TypeScript surely has something appropriate to map this to.
Code:string[] elementTypes = { "DOMElement", "DOM Element", "domelement", "HTML Element" };
2. Integer, Float etc are not just variants of Number, they convey that only integral or decimal values are expected and supported. If there is no corresponding TypeScript notion, we would suggest mapping to Number but then adding a note in the doc ("Decimal value expected and allowed" or similar)
Code:readonly maxHeight?: number /* integer */;
3. similarly, "Boolean" vs "boolean" conveys whether null is allowed and expected (and the one typo of "bool" has been fixed for a long time)
4. any method defined on the "Callbacks" object can be assumed to be a callback. This is a SmartClient idiomatic way of defining things, but should not require a list of hardcoded callback names (which would be fragile)
Agree that all of these lists are fragile and I wish I didn't have to make them in the first place. But, unfortunately, there is no field in the refDocs that just tells me what the actual JavaScript type is so I need to maintain (hopefully decreasing) lists in order to map the types to something the compiles.
Comment
-
5. "AutoChild" and "MultiAutoChild" are not really "extra" words - although you probably need to strip them out to figure out the TypeScript type, it makes sense to provide a link in the generated doc to the AutoChild / MultiAutoChild usage information, as we do in the SmartClient Reference
Comment
-
We use only "DOMElement" (not those other variations) and an API that takes DOMElement or String will have the type "DOMElement | String" (consistent with all other alternative types).
We don't have any plans to change from using informative type names like "Integer" and "Float", nor do we plan to inject thousands of copies of an identical description of what these types mean into the refDocs file. However, we could add offical @type declarations (with @baseType Number) so that you have a source for a description to generate into the TypeScript headers. This would also allow you to get rid of these last (very small) lists. The rest have been obsolete for some time.
We don't *think* we have any more instances of subclasses overriding with the wrong type (or different casing). This doesn't seem to be something you're flagging in Errors.txt.
"Callbacks" is neither a Class nor an Object, it's just a way of organizing the docs. This one item needs to be flagged as something to be ignored in terms of API generation.
Take a look at the AutoChild docs again: if something is documented as an AutoChild, it implies multiple related APIs exist, which are not necessarily explicitly, separately documented. So it's not just a usage hint. It's true that we could have a separate attribute "autoChild=true" but this doesn't materially change the work of a generator so we don't plan to change that now.
Comment
-
We use only "DOMElement" (not those other variations) and an API that takes DOMElement or String will have the type "DOMElement | String" (consistent with all other alternative types).Code:<docItems scVersionNumber="12.0" scVersion="12.0d" versionNumber="SNAPSHOT_v12.0d_2017-08-09" version="SNAPSHOT_v12.0d_2017-08-09/AllModules Deployment"> ... <docItem type="method" definingClass="class:GridRenderer" ref="method:GridRenderer.getCellFromDomElement" description=" Given a pointer to an element in the DOM, this method will check whether this&#010 element is contained within a cell of the gridRenderer, and if so return a&#010 2 element array denoting the <code>[rowNum,colNum]</code> of the element&#010 in question.&#010" flags="A" name="getCellFromDomElement"> <returns type="Array" description="2 element array containing rowNum and colNum, or null if the element is not contained in any cell in this gridRenderer"/> <groups>autoTest</groups> <params optional="false" [B]type="DOM Element[/B]" description="DOM element to test" name="element"></params> </docItem> ... <docItem ref="method:ActiveXControl.getPluginHandle" type="method" definingClass="class:ActiveXControl" description=" Returns a handle to the element for this ISC ActiveX control object.&amp;#010" flags="" name="getPluginHandle"> <returns [B]type="HTML Element"[/B] description="pointer to the plugin element in the DOM"></returns> </docItem> <docItem ref="method:Flashlet.getPluginHandle" type="method" definingClass="class:Flashlet" description=" &amp;#010 Returns a handle to the flashlet DOM element (valid only after the component has been drawn). &amp;#010&amp;#010" flags="A" name="getPluginHandle"> <returns [B]type="HTML Element"[/B] description="pointer to the plugin element in the DOM"></returns> </docItem> <docItem ref="classMethod:EventHandler.getNativeMouseTarget" type="classMethod" definingClass="class:EventHandler" description=" Returns the natively reported target (or source) DOM element for the current mouse event.&amp;#010 &lt;b&gt;NOTE:&lt;/b&gt; SmartClient cannot guarantee that the same element will&amp;#010 be reported in all browser/platform configurations for all event types.&amp;#010 If you wish to make use of this value, we recommend testing your use case &amp;#010 in all target browser configurations.&amp;#010&amp;#010" flags="A" name="getNativeMouseTarget"> <returns [B]type="HTML Element"[/B] description="native DOM element over which the mouse event occurred"></returns> </docItem>
we could add offical @type declarations (with @baseType Number) so that you have a source for a description to generate into the TypeScript headers.
We don't *think* we have any more instances of subclasses overriding with the wrong type (or different casing). This doesn't seem to be something you're flagging in Errors.txt.
Code:Build:Interface 'MenuItem' incorrectly extends interface 'ListGridRecord'. Build:Interface 'CubeGrid' incorrectly extends interface 'ListGrid'. Build:Interface 'DynamicFormProps' incorrectly extends interface 'CanvasProps'. Build:Interface 'DynamicForm' incorrectly extends interface 'Canvas'. Build:Interface 'EventCanvasProps' incorrectly extends interface 'VLayoutProps'. Build:Interface 'EventCanvas' incorrectly extends interface 'VLayout'. Build:Interface 'MenuProps' incorrectly extends interface 'ListGridProps'. Build:Interface 'Menu' incorrectly extends interface 'ListGrid'. Build:Interface 'MenuButtonProps' incorrectly extends interface 'ButtonProps'. Build:Interface 'MenuButton' incorrectly extends interface 'Button'. Build:Interface 'MiniDateRangeItemProps' incorrectly extends interface 'StaticTextItemProps'. Build:Interface 'SelectItemProps' incorrectly extends interface 'FormItemProps'. Build:Interface 'SelectItem' incorrectly extends interface 'FormItem'. Build:Interface 'SliderProps' incorrectly extends interface 'CanvasProps'. Build:Interface 'Slider' incorrectly extends interface 'Canvas'. Build:Interface 'SplitbarProps' incorrectly extends interface 'StretchImgProps'. Build:Interface 'Splitbar' incorrectly extends interface 'StretchImg'. Build:Interface 'ToolbarProps' incorrectly extends interface 'LayoutProps'. Build:Interface 'Toolbar' incorrectly extends interface 'Layout'. Build:Interface 'ToolStripProps' incorrectly extends interface 'LayoutProps'. Build:Interface 'ToolStrip' incorrectly extends interface 'Layout'.
Comment
-
I see that several Classes that did not inherit from Class are now tagged as "objects". This makes sense. I also see that for these objects, what used to be classMethods are now called staticMethods. All good. I've modified the generator to handle these. Thanks.
However, I also see that isA has been moved to its own object, which is fine, but the the methods are marked as classMethod. I think they should be staticMethod. This probably accounts for most of the decrease in the Methods Generated count which went from 3298 to 3278.
Comment
Comment