Непонятность с extension methods
От: Nuald Россия http://nuald.blogspot.com
Дата: 13.09.06 05:49
Оценка:
Всем привет!
Я тут недавно
Автор: Nuald
Дата: 11.09.06
задавал вопрос о вылете ConsoleTest, но так как на него никто не ответил, постарался сам понять причину. Небольшое исследование показало, что парсер Немерле почему-то криво отрабатывает методы расширения.
Если просто посмотреть на Output-окно при запуске ConsoleTest, то можно увидеть следующее (по-крайней мере у меня):
...загрузка...
Nemerle.Completion2\Tests\Content\Class1.n(146,14,146,18): error: parse error near keyword 'this': expecting identifier
Nemerle.Completion2\Tests\Content\Class1.n(146,19,146,20): error: parse error near identifier 's': unexpected token after group of tokens
A first chance exception of type 'System.ArgumentException' occurred in Nemerle.Compiler.dll
System.ArgumentException: GetName () called for option 
   at Nemerle.Compiler.Parsetree.Splicable.GetName() in D:\Work\Nemerle\ncc\parsing\ParseTree.n:line 320
   at Nemerle.Compiler.Parsetree.DeclarationBase.get_ParsedName() in D:\Work\Nemerle\ncc\parsing\ParseTree.n:line 138
   at Nemerle.Compiler.MethodBuilder._N_mkparm_33234.apply(Fun_parm _N_33233) in D:\Work\Nemerle\ncc\hierarchy\ClassMembers.n:line 772
   at Nemerle.Collections.List.Map['a,'b](list`1 l, Function`2 f) in D:\Work\Nemerle\lib\list.n:line 848
   at Nemerle.Compiler.MethodBuilder..ctor(TypeBuilder par, Function f, Boolean is_property) in D:\Work\Nemerle\ncc\hierarchy\ClassMembers.n:line 834
   at Nemerle.Compiler.MethodBuilder..ctor(TypeBuilder par, Function f) in D:\Work\Nemerle\ncc\hierarchy\ClassMembers.n:line 719
   at Nemerle.Compiler.TypeBuilder.bind_and_add_member(ClassMember class_member) in D:\Work\Nemerle\ncc\hierarchy\TypeBuilder.n:line 1611
   at Nemerle.Compiler.TypeBuilder.BindAndAddMember(ClassMember class_member) in D:\Work\Nemerle\ncc\hierarchy\TypeBuilder.n:line 1386
   at Nemerle.Compiler.TypeBuilder._N__N_method_lambda_29410.apply_void(ClassMember _N_29409) in D:\Work\Nemerle\ncc\hierarchy\TypeBuilder.n:line 1771
   at Nemerle.Collections.List.Iter['a](list`1 l, FunctionVoid`1 f) in D:\Work\Nemerle\lib\list.n:line 842
   at Nemerle.Compiler.TypeBuilder.add_members() in D:\Work\Nemerle\ncc\hierarchy\TypeBuilder.n:line 1771
   at Nemerle.Compiler.TypesManager._N__N_l27228_27308.apply_void(TypeBuilder _N_27307) in D:\Work\Nemerle\ncc\hierarchy\TypesManager.n:line 313
   at Nemerle.Compiler.TypesManager._N_maybe_f_27480.apply_void(TypeBuilder _N_27479) in D:\Work\Nemerle\ncc\hierarchy\TypesManager.n:line 221
   at Nemerle.Collections.List.Iter['a](list`1 l, FunctionVoid`1 f) in D:\Work\Nemerle\lib\list.n:line 842
   at Nemerle.Core.list`1.Iter(FunctionVoid`1 f) in D:\Work\Nemerle\lib\list.n:line 284
   at Nemerle.Compiler.TypesManager.Iter(list`1 builders, FunctionVoid`1 f) in D:\Work\Nemerle\ncc\hierarchy\TypesManager.n:line 227
   at Nemerle.Compiler.TypesManager.Iter(FunctionVoid`1 f) in D:\Work\Nemerle\ncc\hierarchy\TypesManager.n:line 238
   at Nemerle.Compiler.TypesManager.Run() in D:\Work\Nemerle\ncc\hierarchy\TypesManager.n:line 313
   at Nemerle.Completion2.Engine.GetProject() in D:\Work\Nemerle\vs-plugin\Nemerle.Compiler.Utils\Nemerle.Completion2\Engine\Engine-main.n:line 79
A first chance exception of type 'Nemerle.Compiler.CompletionResult' occurred in Nemerle.Compiler.dll
# RunCompletionEngine() return 
Nemerle.Completion2\Tests\Content\Class1.n(143,18,143,21): error: expecting simple identifier instead of 'Foo ()'
A first chance exception of type 'Nemerle.Compiler.RestartInErrorMode' occurred in Nemerle.Compiler.dll
Nemerle.Completion2\Tests\Content\Class1.n(143,15,143,21): error: $ operator outside quotation <[ ... ]> context
A first chance exception of type 'Nemerle.Compiler.Recovery' occurred in Nemerle.Compiler.dll
A first chance exception of type 'NUnit.Framework.AssertionException' occurred in nunit.framework.dll
...вылетело исключение...

Более того, прописав опцию препроцессора PRINT_AST в ExprFinder.n можно увидеть следующее:
...покусано...
Start at: 143:20.
Nemerle.Compiler.Parsetree.PExpr+Sequence 142:3:144:4 cur:142:3:243:1 143:20.
def str = "".(NULL-MEM)

  Nemerle.Compiler.Parsetree.PExpr+Define 143:5:143:21 cur:142:3:243:1 143:20.
  def str = "".(NULL-MEM)

    Nemerle.Compiler.Parsetree.PExpr+Ref 143:5:143:8 cur:142:3:243:1 143:20.
    str

    Nemerle.Compiler.Parsetree.PExpr+Member 143:15:143:21 cur:143:9:243:1 143:20.
    "".(NULL-MEM)
...покусано...

Таким образом, парсер (вопрос чей, но скорей всего Немерле) не смог корректно отпарсить метод расширения Foo в модуле ClassExtension:
module ClassExtension
{
  Boo() : void
  {
    def str = "".Foo/*ClassExtension:-1*/();
  }
  
  public Foo(this s : string) : int
  {
    0
  }
}

Вопрос. Собственно, эта фича реализована или нет? Где здесь надо копать — в компиляторе Немерле или проекте интеграции? Или вообще, я что-то неправильно делаю?

P.S. Как ни странно, независимое юнит-тестирование проходит успешно, однако у меня какие-то подозрения в его корректности.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.