Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

  • Isomorphic
    replied
    As before, generalities don't really help but specific instances will.

    1. As the docs say, Object means a plain JavaScript Object. As with JavaScript in general, an Object can have methods added it to it as properties. What specific API(s) are you looking at where it's unclear what to generate for TypeScript?

    2. methods can't have IRWA flags at all (there is not even a way to declare such a thing in our JS doc format), so what specific methods do you think have an "I" flag? Yes, method overrides and custom methods can be passed to create(), there is no need for a special flag to allow this

    Leave a comment:


  • kylemwhite
    replied
    I'm making good progress. I am almost to the point where everything works for my project (subset of classes/objects and subset of methods). There are, of course, lots of issues with the referenceDocs.xml file, too many to list in the forum here so part of my program will now try to identify the issues and generate a report so that we may easily keep track of them. I have a few fundamental questions though:

    1. How is an object (called plain old javascript object in the docs) different than a class? At first I thought it might be that an object doesn't inherit from anything or have methods but I've found examples that violate those rules. So what is the rule that makes an object an object vs. a class? If I know the rule, then I can easily validate the file. It doesn't really matter to the TypeScript definition library, everything is an interface anyway, but I'm curious and if you've decided to call them different things, then there must be a reason.

    2. I'm using the I flag to create 'Properties' interfaces. These represent classes (or objects?) that can be created and type-checked inside a call to .create(). For example, if you type
    Code:
    isc.TabSet.create({
    intellisense will give you all of the possible properties that can be passed into the TabSet.create() method but not the ones that can't (i.e. only the properties marked with 'I'). This has already helped my identify stuff I was passing in that wouldn't be used anyway or was misspelled etc. In my old JavsScript code, I am also passing method definitions this way and it works. But out of 3,063 defined methods, only 6 are marked with the I flag, which makes me think that the I flag isn't really accurate for methods. So, is the I flag valid on methods or can I define any method in the call to create()?

    Leave a comment:


  • Isomorphic
    replied
    Right, it's common in OOP systems to re-doc a property on a subclass to explain different behavior, different default value, etc.

    All of the types declared for SCImgDir are just strings, but we'll clean this up so they all say SCImgURL.

    Similarly, the valuesManager property does allow either a ValuesManager or (String) ID of a valuesManager, we'll make that consistent as well.

    BaseWidget was recently introduced to explain some drag-and-drop properties that are in common between Canvas and DrawItem, and so missed out on the @inheritsFrom docs we added everywhere - we'll get that one corrected too.

    Leave a comment:


  • kylemwhite
    replied
    BaseWidget missing inheritsFrom Class?

    Leave a comment:


  • kylemwhite
    replied
    More weirdness: Some classes which inherit from other clasess implement the (seemingly) same property but with a different type. For example: TabSet has a skinImgDir property of type string but it inherits from Canvas which has a skinImgDir property of type URL. Of course they're both really strings by why would a sublass redefine a property? I see that the TabSet version has a default value. Is that why?

    Similarly, DynamicForm redefines valuesManager (as ValuesManger | global id) from Canvas (which is just ValuesManager) but neither has a default value. Are these on purpose?

    Leave a comment:


  • Isomorphic
    replied
    We haven't proposed keeping anything in your script that would need to be revisited when new versions of SmartClient are released.

    Adding version information to referenceDocs.xml makes sense, we'll try to get that done soon. For now, you could pull this information from either the .zip download filename or from docs/readme.html.

    Leave a comment:


  • kylemwhite
    replied
    Yes, I am already working around the inconsistencies and that will work for now. If, however, we want to maintain an up-to-date typedef file(s) as new versions are released, then we'd want that to be auto-generated and not have to implement new workarounds. Which brings up another idea. Can we get some kind of version number in the referenceDocs file? Maybe in a top-level root tag or something. Currently I am modifying the file to add a root tag anyway (because the .NET parser wants one) but it would be nice to have some global info like the version number, build date etc which would then end up in the typedef files as well.

    Leave a comment:


  • Isomorphic
    replied
    Look like you've hit a few of the instances where the SmartGWT Java API is hand-coded rather than generated, so the reference docs for those properties weren't corrected to be a machine-readable description of the type (that explains ListGridField.includeInRecordSummaryFields, DataSourceField.filterEditorType, and LayoutProperties.placeHolderProperties). We'll get these three fixed - please keep letting us know about any of these as they can be quickly fixed.

    As far as "or" vs "|", and the 3 array notations - yes, our own tools are tolerant of these minor variations. We'll get this cleaned up, standardizing on "|" and the "Array of " wording, but to be able to proceed we'd recommend just having your script deal with these variations (which should be easy).

    Note we won't be going with your suggestion of separate valueType tags as that becomes quite verbose for things like parameters, and it usually doesn't make sense to have completely different descriptions for each possible argument type.

    Leave a comment:


  • kylemwhite
    replied
    It's general inconsistencies in the way that properties are defined that makes it tough. Here are some Examples:

    ListGridField.includeInRecordSummaryFields: array of fieldNames <-- fieldNames is pluralized. Also the way of specifying arrays is inconsistent. Would prefer just FieldName[] or string[].

    DataSourceField.filterEditorType: FormItem className <-- Again, this is really a string, Hopefully the baseType will fix that.

    Menu.data: Array of MenuItem | Array[] of Record | Tree | RecordList <-- Array is specified in two different ways for the same property. Or is specified with |

    Validator.dependentFields: String[]<-- Another way an array is specified

    UserTask.targetVM: ValuesManager or String <-- Or is specified with or.

    LayoutProperties.placeHolderProperties: canvas properties <-- Canvas is not capitalized

    If I had my way, all arrays would be specified as T[] or Array<T> if it really uses an Array object and Or would always be specified with a pipe |. This maps nicely to (future)JavaScript and TypeScript without any transformation. Also, it would be nice if things were all Capitalized correctly and not pluralized. These things, of course, are all nit-picky details for a human to figure out but require extra rules when read by a program.

    If you're considering modifying the schema, one change that might make it easier for all kinds of code/document generation is converting the type attribute to a tag and allow multiple type tags per property. This would allow any code-generator to easily parse union types and format them in the appropriate (using |, or OR or a comma-seperated list like This,That, or TheOther) way either for documentation or for code. For example

    Code:
    <docItem defaultValue="null" type="attr" definingClass="class:Menu" ref="attr:Menu.data" valueType="Array of MenuItem | Array[] of Record | Tree | RecordList" description="An array of menuItem objects, specifying the menu items this menu should show.&amp;#010&amp;#010 Data may also be set to a ${isc.DocUtils.linkForRef('class:Tree')} in which case a hierarchy of menus and&amp;#010 submenus will automatically be generated to match the tree structure.  See also&amp;#010 ${isc.DocUtils.linkForRef('attr:Menu.dataSource')} for dynamically fetching menuItems and submenus from a&amp;#010 hierarchical DataSource." flags="IRW" name="data">
        <groups>data</groups>
        <setter>setData</setter>
        <examples>${isc.DocUtils.linkForExampleId('fullMenu')}</examples>
    </docItem>
    could be something like

    Code:
    <docItem defaultValue="null" type="attr" definingClass="class:Menu" ref="attr:Menu.data" flags="IRW" name="data">
        <valueType type="MenuItem[]" description="An array of MenuItem objects, specifying the menu items this menu should show">
        <valueType type="Record[]" description="An array of Records, specifying the menu items this menu should show">
        <valueType type="Tree" description="a Tree in which case a hierarchy of menus and submenus will automatically be generated to match the tree structure">
        <valueType type="RecordList" description="A RecordList object because...">
    <valueType type="Record[]" description="An array of Records, specifying the menu items this menu should show">
        <groups>data</groups>
        <setter>setData</setter>
        <examples>${isc.DocUtils.linkForExampleId('fullMenu')}</examples>
    </docItem>

    Leave a comment:


  • Isomorphic
    replied
    We don't plan to add "baseType" declarations for int, float, etc as that's a small, static, self-explanatory list. However it would be great to hear about any further issues you discover that make it difficult to translate to a TypeScript API definition (or, like the string-based types, require information to be maintained inside the translation script).

    Leave a comment:


  • kylemwhite
    replied
    recall, we actually generate full Java interfaces from this information
    I kinda figured that but I'm finding so many inconsistencies that you must have a bunch of rules built in code like I do to make everything work. I think that by making the referenceDocs (or a derivative format) more consistent will improve SmartGWT, TypeScript, the documentation and possibly SmartClient itself.

    Currently, for the handful of types like CSSStyleName which are basically strings, for translation to Java APIs we just have a list of them in the translation tool, and the list is:
    Ok, it looks like I am re-inventing the your translation tool because I've got a similar list going. Your's is more complete of course so I'll just put that in there. Thanks.

    We'll look at adding something like adding a ' baseType:"String" ' property to referenceDocs.xml
    That is fantastic!(although I would use lowercase string). The same field could be used for number. And I understand about focusing on 11.1. I'm looking forward to the Tahoe skin.

    We can fix this one, let us know if you find others.
    There's a bunch in the 11.0, Next week, I'll be using 11.1 and let you know when I find more.

    I made a lot of progress today but nothing to upload yet.

    Leave a comment:


  • Isomorphic
    replied
    No language can enforce (at compile time) every constraint that a programmer might wish for.
    Definitely. But this doesn't mean that constraints should never be expressed via type. For example, no one would think Java could be improved by having all parameters be Object and just having developers document what's expected. The trend is actually the reverse, as some modern languages incorporate parameter constraints, code contracts, or compilable annotations that express constraints on basic types.

    Not to mention that, of course, systems like XML Schema allow such constraints for data values, and in many ways, the distinction between data values and parameter values is blurring (isn't an XML element passed to a WSDL web service basically a method parameter?). In fact, SC's type system allows you to attach not just constraints but also behaviors to atomic types - SimpleTypes in SmartClient can extend each other, and add value constraints, parsing and formatting rules, default editors to use, etc.

    So, we definitely will not be changing our reference to show just Number where we currently show int, float, etc as it clearly provides useful information in a compact, easily understood format. Similarly for things like CSSStyleName - we find this a lot better than having docs throughout the system link to an explanation of what to pass, and the fact that the information is structurally part of the doc makes it much easier to build tools for editing component properties.

    However we would like to make referenceDocs.xml, or a derivative format, easier to process for TypeScript *and other possible targets* (recall, we actually generate full Java interfaces from this information).

    Currently, for the handful of types like CSSStyleName which are basically strings, for translation to Java APIs we just have a list of them in the translation tool, and the list is:

    <class name="Callback"/>
    <class name="ListGridGroupState"/>
    <class name="RelativeDateString"/>
    <class name="CSSClass" />
    <class name="CSSText" />
    <class name="CSSColor" />
    <class name="CSSClassName" />
    <class name="CSSStyleName" />
    <class name="Color" />
    <class name="SCClassName" />
    <class name="SCImgURL" />
    <class name="DataPath" />
    <class name="DateInputFormat" />
    <class name="ListGridFieldState" />
    <class name="ListGridSelectionState" />
    <class name="ListGridSelectedState" />
    <class name="ListGridSortState" />
    <class name="ListGridViewState" />
    <class name="TreeGridOpenState" />
    <class name="TreeGridViewState" />
    <class name="FormItemBaseStyle" />
    <class name="VelocityExpression" />
    <class name="XPathExpression" />
    <class name="HTMLString" />
    <class name="DetailViewerViewState" />
    <class name="FormatString" />

    For now, we'd suggest just using this same list in the TypeScript translation script. We'll look at adding something like adding a ' baseType:"String" ' property to referenceDocs.xml so this list doesn't need to be hardcoded into the translation script, but we're very focused on the 11.1 / 6.1 release right now, so there will be some delay.

    For the NavigationMode enum, those values are the names of constants, so you can actually evaluate "TableView.NAVICON_ONLY" to get the string "naviconOnly". However, we went through and eliminated these as part of making our docs more easily translate to Java. We can fix this one, let us know if you find others.

    Leave a comment:


  • kylemwhite
    replied
    It's true that TypeScript / JavaScript lacks the richness of SC's type system
    Did I miss something? What is the SC type system? It's JavaScript, there is no type system, that's why we have things like GWT and TypeScript. There are, of course, the custom types documented in the referenceDocs and those can easily be defined in TypeScript and referenced where appropriate. In fact, the type definitions part is already working and uploaded to the git repository. But, as far as enforcing fundamental types like float, integer etc. SC can't do that anymore than any other JavaScript library (at compile time). TypeScript can, however, at least enforce a number vs. a string vs. a custom type at COMPILE time, and even provide intellisense (depending upon the IDE of course).

    but this is definitely not a reason to dumb down our own reference documentation, as that just removes extremely valuable information that developers need
    Agree to disagree on this one. I see this an opportunity to make the documentation better, not dumbed down. The description field (IMHO) is the proper place to further express the constraints that a property or parameter should adhere to. It could be as simple as "a positive integer representing the number of minutes before timing out" or as complicated as "a prime number ending in 5 on Tuesdays or 3 on weekends". No language can enforce (at compile time) every constraint that a programmer might wish for. But if there's a schema that specifies a 'type' for a particular language, then it seems to me the type field should contain the actual language type, not a description of what that parameter represents, that goes in the description field.

    This issue has actually bugged me in the docs even before I started using TypeScript. Many times I would encounter something like CSSStyleName and wonder what that is, then looking further at the docs I see that it is really just a 'string' and since in JS, there is no type enforcement, it's not like I could create a new CSSStyleName object and pass it in. It's just a string that should, hopefully, match up to a style name in a CSS file. I wished it would have just said the type is 'string' and the description would explain what the string represents. Of course I come from an OOP background, not JavaScipt so that may affect my thinking.

    Now, however, with TypeScript, we can actually define a type called CSSStyleName (which is really still just a string, after I fix it) but the intellisense will have documentation explaining what kind of string it is so the developer will get that information immediately without having to look it up in the docs.

    Click image for larger version

Name:	isc.typescript.sample2.png
Views:	290
Size:	30.0 KB
ID:	244250
    Intellisense in Visual Studio (yes, I know I still need to remove the encoding in the description)

    Those are my opinions, take 'em or leave 'em. As for fundamental types, yes it is very easy to map Integer, int, float, Float, positiveInteger (and whatever else I find) to number. I am already putting the original type field in the comments (see the isc.classes.d.ts file in the repository) and could also include them in the JSdoc field (although it might appear to be redundant in some cases if that information is already in the description field).

    for example, no way to subclass or constrain the expected values of Strings
    The Good news: TypeScript DOES allow you to constrain the expected values of strings. See the PreserveOpenState type in isc.types.d.ts. The only valid values are "never", "whenUnique" or "always" and TypeScript will enforce this. This works because the <values> tags in the referenceDocs actually contain the real string values.

    Click image for larger version

Name:	isc.typescript.sample1.png
Views:	292
Size:	20.4 KB
ID:	244247

    The Bad news: Many of these string 'enums' do not contain the actual strings in the <values> tag. They appear to contain a reference to a constant or something although in most cases, I cannot find the definition of the constant. For example NavigationMode has the values TableView.WHOLE_RECORD and TableView.NAVICON_ONLY which really become "wholeRecord" and "naviconOnly" (according to the Docs but I don't know how it figured that out). I don't know how to get the real values from the values in the <values> tag. If they all follow the same pattern like, "remove the period and everything before it, strip the underscore and convert to camelCase", then I can write a transform function to do that. Or maybe the docs could be modified to just contain the actual values? Please advise.

    That's it for now. Please have a look at the git repository as I think it will make some of the issues clearer, especially if viewed by someone familiar with TypeScript.
    Attached Files

    Leave a comment:


  • Isomorphic
    replied
    [quote]For example integer, Integer, int, float, and Float are all things that we understand ... [/url]

    It's true that TypeScript / JavaScript lacks the richness of SC's type system, but this is definitely not a reason to dumb down our own reference documentation, as that just removes extremely valuable information that developers need. The right place to "dumb down" the types is in the script that translates from SC's type information to TypeScript's less rich type system. This also allows improvements to be made as TypeScript gets richer.

    That script should, for example, translate "float" to the JavaScript Number type, but also add a note to the docs for the target attribute or method parameter saying that floating point numbers are expected or allowed. We take this same kind of approach when generating SmartGWT's Java API from SC's reference for cases where Java's type system is also too weak (for example, no way to subclass or constrain the expected values of Strings).

    Given this, is there anything you see that needs fixing in the referenceDocs.xml file?

    Note: we're not reproducing an issue with the SmartClient Reference with the latest available 11.1 build (4-18-2017). You may need to clear cache.

    Leave a comment:


  • kylemwhite
    replied
    Ok, I've got a github repository going and I've uploaded two files: isc.types.d.ts and isc.classes.d.ts. These are both 100% code-generated from the referenceDocs.xml file (with a bunch of rules to fix the previously mentioned type issues). The types file compiles but the classes file does not. So far, I'm generating only a small subset of classes including Class, BaseWidget, Canvas, Layout, VLayout, ListGrid, Tabset and Tab. I'm only doing the properties, no methods yet and only on the instance (not the static class). If I tried to include everything, the files will be huge so I'll need to figure out how to break them up. I'm NOT a TypeScript expert. This effort is to help me with my first TypeScript project which is also a SmartClient project. If there are TypeScript gurus out there that would like to advise on file structure etc. please let me know.

    By looking at the generated code, it becomes obvious (to me anyway) the issues faced with the referenceDocs data. I'm sure we can get it cleaned up but it will take a few iterations. In many cases, I bailed and just used any. This is a good way to get it going but eventually I'd like to get everything properly typed.

    https://github.com/kylemwhite/isc

    Leave a comment:

Working...
X