Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » Lua Development Tools » How to document inherit relation
How to document inherit relation [message #1229396] Thu, 09 January 2014 11:01 Go to next message
Hoping White is currently offline Hoping WhiteFriend
Messages: 71
Registered: July 2009
Member
Hi, all

I have tried to make an Execution Environment for cocos2d-x,and it's all ok now except for inherit. For example, CCAtion is parent of CCActionEase, but I can't get any support from CCAtion when I type CCActionEase. So how to express inherit reletionship in ldt? Thanks
Re: How to document inherit relation [message #1229401 is a reply to message #1229396] Thu, 09 January 2014 11:16 Go to previous messageGo to next message
Simon Bernard is currently offline Simon BernardFriend
Messages: 345
Registered: July 2009
Senior Member
Hi,
Currently there are no way to express inheritance in LDT.
A workarround could be to duplicate all the parent methods in children classes.
We're thinking seriously to add this feature in the next version of LDT.
You could follow the bug and even the LDT project plan for the next release (it's only a plan, we will surely not be able to implement all thoses features).
Do not hesitate to give us some feedback about that Smile
Re: How to document inherit relation [message #1229691 is a reply to message #1229401] Fri, 10 January 2014 01:55 Go to previous messageGo to next message
Hoping White is currently offline Hoping WhiteFriend
Messages: 71
Registered: July 2009
Member
Thanks for the reply. I will modify my program to duplicate all the methods in children classes.
Re: How to document inherit relation [message #1229705 is a reply to message #1229691] Fri, 10 January 2014 02:56 Go to previous messageGo to next message
Hoping White is currently offline Hoping WhiteFriend
Messages: 71
Registered: July 2009
Member
I have found another problem.
CCDirector.sharedDirector():getRunningScene()
sharedDirector and getRunningScene has code assistant, but CCDirector.sharedDirector():getRunningScene(): does not.
I guess that code assistant can only occurs in one module, for this example that is CCDirector.
I have a workaround as this
local scene =CCDirector.sharedDirector():getRunningScene() -- CCScene#CCScene
and now scene has code assistant now
Re: How to document inherit relation [message #1229923 is a reply to message #1229705] Fri, 10 January 2014 14:58 Go to previous messageGo to next message
Simon Bernard is currently offline Simon BernardFriend
Messages: 345
Registered: July 2009
Senior Member
This should works if getRunningScene return the good type : CCScene#CCScene.
Should I see your documentation somewhere (on github or something like that) to check if there are not a mistake ?
Re: How to document inherit relation [message #1230514 is a reply to message #1229923] Sun, 12 January 2014 07:39 Go to previous messageGo to next message
Abe Cee is currently offline Abe CeeFriend
Messages: 2
Registered: January 2014
Junior Member
I also don't know how to make types like that work. How would you make doumentation for this?

Position = {meta = {}}
setmetatable(Position, Position.meta)

function Position.meta:__call(x, y, z)
  local t = {x = x, y = y, z = z}
  return setmetatable(t, {__index = Position})
end

function Position:toString()
  return "{" .. "x = " .. self.x .. ", y = " .. self.y .. ", z = " .. self.z .."}"
end

local s = Position(32, 32, 32)
print(s:toString())
Re: How to document inherit relation [message #1230764 is a reply to message #1229923] Mon, 13 January 2014 02:15 Go to previous messageGo to next message
Hoping White is currently offline Hoping WhiteFriend
Messages: 71
Registered: July 2009
Member
My mistake, I just return #CCScene, not CCScene#CCScene
I push my code to github:https://github.com/lazytiger/cocos2dx-ldt-ee

[Updated on: Mon, 13 January 2014 03:41]

Report message to a moderator

Re: How to document inherit relation [message #1231015 is a reply to message #1230764] Mon, 13 January 2014 16:05 Go to previous messageGo to next message
Marc Aubry is currently offline Marc AubryFriend
Messages: 86
Registered: August 2012
Member
@Hoping: Glad you fix your problem. When you think your EE is ready feel free to contribute it to the following page: http://wiki.eclipse.org/Koneki/LDT/User_Area/Available_Execution_Environments

@Abe: The metatable field "__call" is not supported by the documentation. You need to create a function to see it in the auto-completion.
Also, too have autocompletion on a new variable you need to affect it a type.
See this sample in the documentation.

So for example auto-completion on your sample you need to modify a bit the code to look like that:
--- @type position
local position = {x = 0, y = 0, z = 0} -- initialize the type

--- @function
-- @return #position
function position.new(x, y, z)
  local t = {x = x, y = y, z = z}
  return setmetatable(t, {__index = position})
end

function position:toString()
  return "{" .. "x = " .. self.x .. ", y = " .. self.y .. ", z = " .. self.z .."}"
end

local s = position.new()
s:toString()

As you see, you need to create a type and then to specify the return value of the new fonction as the created type.
Re: How to document inherit relation [message #1231288 is a reply to message #1231015] Tue, 14 January 2014 09:21 Go to previous messageGo to next message
Hoping White is currently offline Hoping WhiteFriend
Messages: 71
Registered: July 2009
Member
EE already added to the page
Re: How to document inherit relation [message #1256441 is a reply to message #1231015] Tue, 25 February 2014 12:36 Go to previous messageGo to next message
mark lowne is currently offline mark lowneFriend
Messages: 8
Registered: February 2014
Junior Member
Marc Aubry wrote on Mon, 13 January 2014 11:05

@Abe: The metatable field "__call" is not supported by the documentation. You need to create a function to see it in the auto-completion.


I would very much like to see this addressed. While this construct is admittedly dubious from a statically typed language point of view, it is convenient and used in lua.
After expending quite some effort on setting up a (wonderful!) live coding environment for Codea based on LDT, I was trying to generate an execution environment for Codea but got stuck because of this issue - and I can't just change their runtime Sad

I propose something like this:
---@type mytype

---@function [parent=#mytype] __call

with, as a bonus, syntactic sugar to internally transform
---@function mytype
into the above (i.e. when a function name clashes with a type name).

In my scenario, the workaround of defining type.new functions would require adding a source file with all the stubs to every project Sad
Re: How to document inherit relation [message #1257605 is a reply to message #1256441] Wed, 26 February 2014 16:14 Go to previous messageGo to next message
Simon Bernard is currently offline Simon BernardFriend
Messages: 345
Registered: July 2009
Senior Member
You're right, we should definitely support that. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=429170)

I not sure we have time to integrate that for the v1.2, but we will think about that.

If it's not for the 1.2, this will be for the 1.3 !

About the syntax, your proposition seems nice, but not sure we are able to implement the syntactic sugar easily.
Re: How to document inherit relation [message #1262369 is a reply to message #1257605] Mon, 03 March 2014 15:09 Go to previous messageGo to next message
mark lowne is currently offline mark lowneFriend
Messages: 8
Registered: February 2014
Junior Member
Thanks Simon!

After further investigation, I found a workaround (and have now a fully functioning execution environment): the trick is to take advantage of ---@type's "implicit scoping" (implicit as we can't have [parent=#something] in a type declaration) within its file or module. Then that type can be referred to from a *different* file where the .metatable:__call function is documented (with the same name of the type).

Using the example from @Abe:
-- file Position.lua

Position = {meta = {}} -- #Position
setmetatable(Position, Position.meta)

function Position.meta:__call(x, y, z)
  local t = {x = x, y = y, z = z}
  return setmetatable(t, {__index = Position})
end

function Position:toString()
  return "{" .. "x = " .. self.x .. ", y = " .. self.y .. ", z = " .. self.z .."}"
end

-- file main.lua

---@function [parent=#global] Position
--@param x
--@param y
--@param z
--@return Position#Position a position instance

require('Position') -- this isn't necessary (or even allowed) in Codea
local s = Position(32, 32, 32)
print(s:toString()) -- autocompletion works


This workaround, while satisfactory for building an execution environment, is still less than ideal in daily use, given that changing a __call constructor requires edits in two separate files!

It seems a tall order, but would it be possible to allow arbitrary scoping of everything using the classic dot notation? Although I'm sure there must be hundreds of reasons that make this a really bad idea.

EDIT: what I'm trying to get at is this: if we allow the idea that everything - in this case, functions - is a type (everything is a table!), then everything should be scoped in a straightforward way. As another example, take the tween.lua library used in Codea:
tween = {}
tween.start = function()...  -- it doesn't even return a normal instance but just an id, as it's more like a collection singleton keeping its "instances" internally
tween.delay = function()...
tween.meta:__call = function(...) tween.start(...) end
tween.easing = {}
tween.easing.cubicInOut = function()...
-- etc

If everything is a type, then "tween()" is a function - and also a type. "easing" is a type with parent=#tween. etc.

[Updated on: Mon, 03 March 2014 15:32]

Report message to a moderator

Re: How to document inherit relation [message #1268530 is a reply to message #1262369] Mon, 10 March 2014 16:29 Go to previous messageGo to next message
Marc Aubry is currently offline Marc AubryFriend
Messages: 86
Registered: August 2012
Member
Here some tips about your exemple, but you still have two files to edit.

In the Position.lua you should explicit the type declaration by adding a @type annotation instead to type your variable using "-- #Position" (which create a implicit type).

You should put the Position constructor function declaration in the global.lua file your Codea Execution Environment as this function is global and seems to be pre-loaded by the Codea framework. See the note about globals in the following documentation: https://wiki.eclipse.org/Koneki/LDT/User_Area/Execution_Environment_file_format.

So in the main.lua file autocompletion works on both contructor and methods.

Here the files:
-- file Position.lua

--- @type
Position = {meta = {}}
setmetatable(Position, Position.meta)

function Position.meta:__call(x, y, z)
  local t = {x = x, y = y, z = z}
  return setmetatable(t, {__index = Position})
end

function Position:toString()
  return "{" .. "x = " .. self.x .. ", y = " .. self.y .. ", z = " .. self.z .."}"
end


-- file global.lua

---@function [parent=#global] Position
--@param x
--@param y
--@param z
--@return Position#Position a position instance


-- file main.lua

local s = Position(32, 32, 32) -- autocompletion works
print(s:toString()) -- autocompletion works


About the "scoping" stuff, the concept of "parent" is only used by functions and field to attach them to a type. As you say a type is always implementing by a lua table and tables have no consider about their parents so i don't get the point to add this concept to a table. Declaring tween as a type let you have auto completion on his subtable such as "easing".
Be aware that in the notation "Postion#Position" the first "Position" is the module (i.e. file) name (not his parent) and the second one is the type name.

Maybe you can explain what problem this scoping should fix ?

Marc
Re: How to document inherit relation [message #1278771 is a reply to message #1268530] Thu, 27 March 2014 20:35 Go to previous messageGo to next message
mark lowne is currently offline mark lowneFriend
Messages: 8
Registered: February 2014
Junior Member
Marc, thanks for the response.

Let me try again to explain what I mean: I'm not saying to allow types to have a parent; I'm saying to make everything a type (while probably still leaving the option of explicitly declaring "abstract" types).

Before I continue:
Quote:
Maybe you can explain what problem this scoping should fix ?


And the answer would be
Quote:
The metatable field "__call" is not supported by the documentation.

But, instead of treating it as a special case...
Quote:
You're right, we should definitely support that. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=429170)

...I'm suggesting to have a discussion on whether it's possible (and sensible) to find a more generalized solution.

In the tween example, even once (if) it becomes possible to declare the __call, I'd still have to jump through needless hoops:
---@function tween
--@param ...

---@type type_tween

---@field [parent=#global] #type_tween tween

---@function delay [parent=#type_tween]
--@param ...

whereas I'd want the example in my previous post to be self-documenting.

Moreover, the way to *document* (as opposed to have them inferred from code) subtables (such as tween.easing), from what I understand, seems to be:
---@type sometype
---@type sometype.subtable
---@field [parent=#sometype] #sometype.subtable subtable
---@field [parent=#sometype.subtable] subfield

which shows in the outline sometype and sometype.subtable as siblings (because, no subtypes!) But isn't this a rather clear case of subtable being a type whose parent is sometype? The fact that such constructs are even allowed to begin with seems to prove it, but this "syntactic sugar" seems unnecessarily verbose (and even imprecise with respect to the way the code is actually structured). I don't understand why you say that tables (/types) have no concept of a parent.
But! - you say - if subtypes were allowed, we would then have
---@type sometype
---@type [parent=#sometype] subtable
---@field [parent=#sometype] #sometype.subtable subfield
---@field [parent=#sometype.subtable] subfield

which is just as verbose and even *more* confusing. Which is why my suggestion is (again) to make everything a type, as opposed to allow [parent] in types, so that we'd simply have
---@type sometype (This one we'll leave as *explicit* abstract type - there's no global singleton for it)
--@field subtable (this is also a type)

---@field [parent=#sometype.subtable] subfield

which I'd further simplify using the classic dot notation (from where to infer parenthood relationships):
---@type sometype

---@field sometype.subtable

---@field sometype.subtable.subfield


--------------

Another, completely different way of seeing the issue (it's *very* hard to describe it effectively, please bear with me) is this: the current luadocumentor specification "forces" an OOP-like approach onto one's documentation (and therefore code).
OOP-like because of the distinction between @type ("class") and @field or whatever ("instance"). But Lua doesn't want to be constricted into any specific paradigm! The module system (which luadocumentor models) is a *suggestion*, but it's seen (by luadocumentor) as the One True Way (which it isn't, as proven for example by the mere existence of Codea).

For example, Lua allows me to do something like this:
dsl = setmetatable({},{
  __call = function() return crazystuff() end
  __index = function(t,k) 
    if k=='key1' then dosomething() 
    elseif key=='key2' then dosomethingelse() end
  end
  __newindex = function(t,k,v)
    if k=='case1' then dostuff() v(somearg)
    elseif k=='case2' then domorestuff() v(otherarg) end
  end
})

which I'd want to document like this (again, I substituted the [parent=] syntax with the "classic dot notation" I mentioned in my previous post):
---@function dsl
--@return #sometype some crazy stuff
dsl = setmetatable({},{
  __call = function() return crazystuff() end
  __index = function(t,k) 
---@function dsl.key1
    if k=='key1' then dosomething() 
---@function dsl.key2
    elseif key=='key2' then dosomethingelse() end
  end
  __newindex = function(t,k,v)
---Does stuff, then calls somecallback
--@function dsl.case1
--@usage dsl.case1 = somecallback
    if k=='case1' then dostuff() v(somearg)
---Does more stuff, then calls somecallback
--@function dsl.case2
--@usage dsl.case2 = somecallback
    elseif k=='case2' then domorestuff() v(otherarg) end
  end
})

... and the reason for this weirdness is that I *want* to think of dsl.case1 and everything else as functions rather than fields - and the reason for *that* shouldn't matter; I want the tooling to enable my way of thinking however "crazy", otherwise I'd still be doing Java Razz . But I use Lua *precisely* because it allows me to concisely express these constructs, which might look crazy on the surface but can be extremely useful.


Having said all this, I'd be happy to just have the __call thing sorted out, because, contrary to what I previously stated, there is no way to have a *fully* functioning Codea execution environment, as
---@function [parent=#global] tween
and
---@field [parent=#global] Tween#tween tween
still clash, making autocompletion fail.



Re: How to document inherit relation [message #1279397 is a reply to message #1278771] Fri, 28 March 2014 17:34 Go to previous messageGo to next message
Simon Bernard is currently offline Simon BernardFriend
Messages: 345
Registered: July 2009
Senior Member
hi,
Ouch complex discussion, I will try to answer but sorry if I miss the point.

To be clear, I will explain some concept.
For us:
when we talk about parent of type, we talk about type inheritance.
when we talk about parent of field, we talk about field container. (#global is a special case to define a global variable maybe not a really good idea...)
Documentation language should explain the API not the way it is implemented.

For us a type is a contract between API users and API developers. It describes the constraints on a table (or even on a function, but we will not talk about that to simplify the problem).
A Type has fields. Fields are typed but are not type. A type could have 2 fields, typed with the same type and even could reference itself. (ouch not sure this is really clear, we need a sample Razz)

 --- @type node
 -- @field #node next
 -- @field #node previous

In this case field and type is clearly 2 different notion. But I understand some time, this 2 notions seems so closed that you would have to manipulate it as 1 concept. We should probably find a better notation (maybe, the [parent=#blabla] is not the best one) We will think about that.

Waiting for the next release we will provide a way to declare type "callable".
The syntax will looks like something like that :

--- @type dsl
dsl = setmetatable({},{
  ---@callof #dsl
  --@return #sometype some crazy stuff
  __call = function() return crazystuff() end
  __index = function(t,k) 
    ---@function[parent=#dsl] key1
    if k=='key1' then dosomething() 
    ---@function[parent=#dsl] key2
    elseif key=='key2' then dosomethingelse() end
  end
  __newindex = function(t,k,v)
   ---Does stuff, then calls somecallback
   --@field[parent=#dsl] case1
   --@usage dsl.case1 = somecallback
    if k=='case1' then dostuff() v(somearg)
   ---Does more stuff, then calls somecallback
   --@field[parent=#dsl]case2
   --@usage dsl.case2 = somecallback
    elseif k=='case2' then domorestuff() v(otherarg) end
  end
})

We should release a milestone release in 1 or 2 weeks, you will be able to test it. (we have added inheritance and map/list concept)
If you have any feedback Smile


Re: How to document inherit relation [message #1280570 is a reply to message #1279397] Sun, 30 March 2014 15:14 Go to previous messageGo to next message
mark lowne is currently offline mark lowneFriend
Messages: 8
Registered: February 2014
Junior Member
Hi,
looking good! I like the @callof syntax, looking forward to the next milestone!

Thanks for your clarification and the dsl example, it helped me better understand the problem domain (and what luadocumentor expects). It is true that once LDT gets @callof, one should be able to document basically everything in one way or another. Which is great - awesome job there!

What I was trying to get across is that the "right" way to luadocument things is not what I'd "instinctively" think of. So perhaps it's better to take my rants as an RFC of sorts for an LDT 2.0 roadmap.

Let's try this. For the sake of argument, let's assume you guys do decide that [parent=#blabla] is not the best way after all. You are looking at the following snippet:
---@field [parent=#global] #tab tab

---@field [parent=#tab] #tab.subtab subtab

---@field [parent=#tab.subtab] subfield

that is meant to refer to something that exports 'tab' (along with its .subtab.subfield) to the global namespace (which isn't usually a wise thing - but this example works also if 'tab' were just a type as opposed to a field). Along with the field struct, it exposes both the implicitly created *types* "tab" and "tab.subtab" in the Outline view in Eclipse.

Again for the sake of argument, let's say that after some brainstorming, you guys decide that the above should instead look like this:
---@field tab

---@field tab.subtab

---@field tab.subtab.subfield

Moreover, you decide that this should *not* result in having 'tab.subtab' as a "root" type in the Outline. Actually, since you want to be really fancy, you don't want the type 'tab' there (in the Outline) either, because in this case it's not really a (user-facing) "type" - it's just a necessary "crutch" to allow the definition of the global *field* 'tab', which is what the API developer wants the API users to see and use. (BUT - if one were to explicitly add ---@type tab, then it *should* be in the Outline).
Very well! At this point in this hypothetical scenario you have your user story as described above. Now comes the hard part: how to actually implement it in LDT, with all the nasty complexity of internal models, metalua etc.

Ok, at this point take a couple minutes to try to answer that question: assuming that you *wanted* to have LDT behave like described above, *how* would you implement it?


So. Using this point of view, my post above would be better expressed this way:
Assuming that you guys *want* to implement that kind of behaviour (described above) in LDT, perhaps one way of getting there without too much work could be to have two kinds of "types". One is the current ---@type - explicitly declared, shows up in the outline, etc. The other would be an "implicit" type that is created behind the scenes alongside any other declaration (field, function, etc). This second "type" would just be a *container* according to the current way of modeling [parent=#blabla] relations.
In other words, this would simply mean that everything automatically becomes a potential *container* for other things. Getting back to the specific __call issue, using the tween example, you'd get this working as intended, for "free" (i.e. without coding any specific handling of __call):
---@function tween

---@field tween.foo

---@field tween.foo.bar

because in the model, tween() - the function - would automatically have a "hidden twin" container, ready to accept tween.foo in it.

(EDIT: or seen yet another way: instead of my suggestion *everything is a type* (which is confusing terminology for the reasons outlined by Simon) think of *everything is (or can be) a table*; namely, ---@fields and ---@functions are also tables, initially childless when declared, but ready to become "parents", like tween() above as soon as tween.foo comes about)


And my questions then would be: if you'd *actually* like to have this in LDT, does my idea have any merit? And if you do *not* want to have this in LDT, why not? (as I said initially, I'm sure there must be many many reasons I didn't think of).

[Updated on: Sun, 30 March 2014 16:26]

Report message to a moderator

Re: How to document inherit relation [message #1289701 is a reply to message #1280570] Wed, 09 April 2014 15:07 Go to previous message
Simon Bernard is currently offline Simon BernardFriend
Messages: 345
Registered: July 2009
Senior Member
Interesting proposition. We will really think about that even if this should be technically complex to implement.

I continue to think that mixing "type" and "field" could be a problem. In your sample what does it mean if I do that ?
---@field tab

---@field #number tab.subtab

---@field tab.subtab.subfield

I open a bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=432449
You should follow it if you want to participate to this feature.


By the way, the 1.2M2 of ldt is out you could try it and give us some feedback.
http://eclipse.org/koneki/ldt/
http://wiki.eclipse.org/Koneki/LDT/User_Area/New_Noteworthies/New_Noteworthy_1.2 (screenshot and documentation is not yet ready, but this should be available very soon)
Previous Topic:Parsing files not commented in luadocs
Next Topic:Koneki LDT moving in his own project.
Goto Forum:
  


Current Time: Fri Apr 19 05:31:00 GMT 2024

Powered by FUDForum. Page generated in 0.02630 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top