ZeroBraneStudio icon indicating copy to clipboard operation
ZeroBraneStudio copied to clipboard

REQ: make Analyze aware of api

Open jjvbsag opened this issue 7 years ago • 4 comments

Taking this simple program

local fd=io.open("file")
local line=fd:read()
fd:close()
print(line)

Zerobrane is aware of the type of fd. When I entry ´fd:´ I get a popup with available methods. But if I run Analyze from project menu, I get

Analyzing the source code: 2 warnings.
...\file.lua:2: first use of unknown field 'read'
...\file.lua:3: first use of unknown field 'close'

It would be very nice to pass the knowledge about the api into analyze to eleminate these warnings... Is it possible?

jjvbsag avatar Jul 31 '17 08:07 jjvbsag

I see the point, but I don't think it's going to be sufficiently simple to implement; I'll have to think about this...

pkulchenko avatar Aug 08 '17 23:08 pkulchenko

Yes, I know this is a bigger task. But thinking about the Newbies, taking some sample code - which is absolute fine - from some example page to learn lua, and then get warnings for a correct script might get them skeptical about them or about lua...

What about generating some stub files like this:

local FILE={}
function FILE:read(...)return"data"end
function FILE:close(...)return true end
io={}
function io.open()return FILE end

This could be

  • autogenerated from the api files (and then be cached to a file)
  • preloaded by the analyzer to know more about the world.

Just as a starting point for discussion... :coffee:

jjvbsag avatar Aug 09 '17 06:08 jjvbsag

Referring to this and #821 just an example, how an (autogenerated) api file could look like (real world example):

return {
  i2c={
    type="lib",
    description="This library provides access to i2c devices",
    childs={
      I2CDEV={
        type="function",
        description="Open a generic i2c device\ndev (string,optional) device file, default:\"/dev/i2c-1\"\naddr (number) i2c address of device (0x00..0x7F)\n\t",
        args="(dev:string,addr:number)",
        returns="(i2cdev|nil,string)",
        valuetype="I2CDEV"
      },
      MAG3110={
        type="function",
        description="Open a i2c device of type MAG3110",
        args="()",
        returns="(mag3110|nil,string)",
        valuetype="MAG3110"
      }
    }
  },
  I2CDEV={
    type="class",
    description="One generic i2c device",
    childs={
      rd={
        type="method",
        description="Read data from device",
        args="(number)",
        returns="(string|nil,string)",
        valuetype="string"
      },
      wrrd={
        type="method",
        description="Write and read data from device",
        args="(string,number)",
        returns="(string|nil,string)",
        valuetype="string"
      },
      wr={
        type="method",
        description="Write data to i2c device",
        args="(string)",
        returns="(true|nil,string)",
        valuetype="boolean"
      }
    }
  },
  MAG3110={
    type="class",
    description="One device of type MAG3110",
    childs={
      values={
        [1]="number",
        returns="(number|nil,string)",
        type="method",
        description="Read temperature from MAG3110",
        args="()"
      },
      init={
        type="method",
        description="Initialize MAG3110\nhz : 10,20,40,80,160,320,640,1280\nos : 16,32,64,128\n",
        args="(hz,os)",
        returns="(true|nil,string)",
        valuetype="boolean"
      },
      id={
        type="method",
        description="Return ID of MAG3110",
        args="()",
        returns="(number|nil,string)",
        valuetype="number"
      },
      offsets={
        type="method",
        description="Read/Write offsets from/to MAG3110",
        args="(|number,number,number)",
        returns="(number,number,number|nil,string)",
        valuetype="number"
      },
      ready={
        type="method",
        description="Check status of MAG3110",
        args="()",
        returns="(boolean)",
        valuetype="boolean"
      }
    }
  }
}

a script using the lib looks like this

require"i2c"

local mag=i2c.MAG3110()
print("ID:",mag:id())
mag:init()
for _=1,10 do
	print(mag:values())
end

and works fine. But the analyzer complains

Analyzing the source code: 4 warnings.
.../i2cdev-example.lua:3: first use of unknown field 'MAG3110' in 'i2c'
.../i2cdev-example.lua:4: first use of unknown field 'id'
.../i2cdev-example.lua:5: first use of unknown field 'init'
.../i2cdev-example.lua:7: first use of unknown field 'values'

It would be really, really nice the make the analyser aware of the api's.

jjvbsag avatar Oct 23 '17 06:10 jjvbsag

Same requirements that in #821

LeRatierBretonnien avatar Oct 23 '17 07:10 LeRatierBretonnien