luke-gru / riml

Riml is a subset of VimL with some nice added features. It compiles to plain VimL.
MIT License
224 stars 6 forks source link

class method name generation error #30

Open tek opened 10 years ago

tek commented 10 years ago

I upgraded from 0.2.9 today and it broke class generation. when trying to instantiate a class, I get the error

E117: Unknown function: s:SID
E116: Invalid arguments for function function('<SNR>' . s:SID() . '_s:MyClass_method_name')
E15: Invalid expression: function('<SNR>' . s:SID() . '_s:MyClass_method_name')

I put a debug output statement into ast_rewriter.rb and a SID node is excluded in the rewritten syntax tree, though it's not present in the generated viml file.

If I just paste it on top of the riml file (in VimL), everything's fine.

Also, the generated methods look like

function! <SID>s:MyClass_method_name()

Isn't the s: superfluous?

luke-gru commented 10 years ago

Hi @tek,

Thanks for the detailed report. The s: is superfluous, but to my knowledge it does no harm. I'm not sure if that's what the problem is here or not.

Can you paste a small standalone example that will reproduce this error so I can have a better idea of what's going on?

Thanks,

tek commented 10 years ago

@luke-gru

class MyClass
  defm foo
  end
end

foo = new MyClass()

Then doing runtime autoload/foo.vim would be enough. The output file:

function! s:MyClassConstructor()
  let myClassObj = {}
  let myClassObj.foo = function('<SNR>' . s:SID() . '_s:MyClass_foo')
  return myClassObj
endfunction

function! <SID>s:MyClass_foo() dict
endfunction

let s:foo = s:MyClassConstructor()

s:SID() obviously can't be there, do I miss an import or something?

btw, I wrote 'excluded' in the first post when I meant 'included'.

luke-gru commented 10 years ago

Ah I see, thanks. Are you compiling from the commandline, or running riml interactively (riml -i)?

I get the following output when saving your example in a file foo.riml and running riml -c foo.riml

function! s:SID()
  if exists('s:SID_VALUE')
    return s:SID_VALUE
  endif
  let s:SID_VALUE = matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
  return s:SID_VALUE
endfunction

function! s:MyClassConstructor()
  let myClassObj = {}
  let myClassObj.foo = function('<SNR>' . s:SID() . '_s:MyClass_foo')
  return myClassObj
endfunction

function! <SID>s:MyClass_foo() dict
endfunction

let s:foo = s:MyClassConstructor()

When running riml interactively, the generated s:SID function is left off, but maybe that is confusing behaviour.

tek commented 10 years ago

ah, alright. I am using guard-shell with a Guardfile I created some months ago, that was using riml -s < #{infile} > ${outfile}…I guess SID() is being omitted in stdin mode, too. using -c, I get the correct results.

tek commented 10 years ago

After updating vim today, the <sid>s: seems to be illegal now.

tek commented 10 years ago

FWIW, this is working at first glance: https://github.com/tek/riml/commit/9d2131f1ceb1ca5e4a6cfc14d4d56bbdeea4c3dd