Браузер кода Nemerle: подсветка работает
От: catbert  
Дата: 07.06.10 17:39
Оценка: 27 (3)
Демонстрация по ссылке (хостится прямо на моем компьютере, потому время от времени может быть офлайн):

www.catbert.co.cc/code

Должны правильно подсвечиваться все конструкции языка, кроме идентификаторов типов: сейчас лексер просто угадывает вид идентификатора.

В следующих сериях : навигация, перекрестные ссылки, ссылки на данные из System.Reflection — то есть фичи, для которых код нужно не только парсить, но и типизировать.
Re: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.10 17:44
Оценка:
Здравствуйте, catbert, Вы писали:

C>Демонстрация по ссылке (хостится прямо на моем компьютере, потому время от времени может быть офлайн):


C>www.catbert.co.cc/code


Видимо таки сейчас офлайн.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Браузер кода Nemerle: подсветка работает
От: Воронков Василий Россия  
Дата: 07.06.10 17:46
Оценка:
Здравствуйте, catbert, Вы писали:

C>Демонстрация по ссылке (хостится прямо на моем компьютере, потому время от времени может быть офлайн):

C>www.catbert.co.cc/code

По ходу оффлайн прямо сейчас.
Re[2]: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.10 17:53
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

C>>Демонстрация по ссылке (хостится прямо на моем компьютере, потому время от времени может быть офлайн):

C>>www.catbert.co.cc/code

ВВ>По ходу оффлайн прямо сейчас.


Опубликовал и скрылся

Правда сейчас ответ появился, но он "Bad Request (Invalid Hostname)".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Браузер кода Nemerle: подсветка работает
От: catbert  
Дата: 07.06.10 18:10
Оценка:
Здравствуйте, VladD2, Вы писали:

ВВ>>По ходу оффлайн прямо сейчас.


VD>Правда сейчас ответ появился, но он "Bad Request (Invalid Hostname)".


С конфигурацией IIS борюсь

Сейчас вроде нормально должно быть.
Re[4]: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.10 19:02
Оценка:
Здравствуйте, catbert, Вы писали:

C>С конфигурацией IIS борюсь

C>Сейчас вроде нормально должно быть.

Ага. Заработало. Только глюкает пока.

К тому же без проекта типы правильно не подсветить. Плюс строки не подсвечиваются.

Что до клюков, то попытка залить туда код приведенный ниже привела к "Server Error in '/code' Application.".

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;

using Nemerle.Collections;
using Nemerle.Imperative;
using Nemerle.IO;
using Nemerle.Builtins.Function;
using Nemerle.Utility;

using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
//using Nemerle.Compiler.Typedtree;

using Nemerle.Assertions;

using TT = Nemerle.Compiler.Typedtree;
using TExpr = Nemerle.Compiler.Typedtree.TExpr;
using SCG = System.Collections.Generic;
using Debug = System.Diagnostics.Debug;

namespace Nemerle.Data.Linq
{
  /// <summary>
  /// Description of LinqSyntax.
  /// </summary>
  module LinqSyntax
  {
    internal LinqImpl(typer : Typer, expr : PExpr) : PExpr
    {
      match (expr)
      {
        | PExpr.Literal(Literal.String(_) as lit) => 
          ParseAndTranformLinqQuery(typer, expr.Location, lit.RawString)
          
        | PExpr.Call(PExpr.Member(PExpr.Literal(Literal.String(_) as lit) as litExpr, member) as obj, parms) => 
          // this section add support of "linq <# from ... #>.Sum()" syntax
          PExpr.Call(expr.Location, PExpr.Member(obj.Location, 
            ParseAndTranformLinqQuery(typer, litExpr.Location, lit.RawString), member), parms)
          
        | _ => 
          Message.Error(expr.Location, 
            "The 'linq' macro expect string literal with query code (try enclose query in round brackets)");
          <[ () ]>
      }
    }
    
    internal ParseAndTranformLinqQuery(typer : Typer, loc : Location, queryStrLiteral : string) : PExpr
    {
      unless (queryStrLiteral.StartsWith("<#"))
      {
        Message.Error(loc, "The 'linq' macro hould use recursive strinq (<#...#>)");
        return <[ () ]>;
      }
      
      Macros.DefineCTX(typer);
      
      def query = queryStrLiteral.Substring(2, queryStrLiteral.Length - 4);

      def (complMarkLine, complMarkChar) = 
        if (typer.Manager.IsCompletionInProgress)
          (typer.Manager.CompletionMarkLine, typer.Manager.CompletionMarkChar)
        else (-1, -1);

      def lexer = LexerLinq(typer, query, 
        Location(loc, loc.Line, loc.Column + 2, loc.EndLine, loc.EndColumn),
        complMarkLine, complMarkChar);
      
      def expectKeyword(keywordName : string) : void
      {
        def tok = lexer.GetAnyToken();
        
        match (tok)
        {
          | Token.Operator(x) when x == keywordName => () //It's OK!
          | Token.Keyword(x)  when x == keywordName => () //It's OK!
          | _ => 
            Message.Error(tok.Location, $"expected keyword $keywordName but found '$tok'");
            throw ParseErrorException();
        }
      }
      def tryExpectKeyword(keywordName : string) : bool
      {
        def tok = lexer.GetAnyToken();
        
        match (tok)
        {
          | Token.Operator(x) when x == keywordName
          | Token.Keyword(x)  when x == keywordName => true //It's OK!
          | _ => 
            Message.Error(tok.Location, $"expected keyword $keywordName but found '$tok'");
            false
        }
      }
      def tryParseKeyword[T](keyword : string, sucsessContinuation : void -> T, failValue : T) : T
      {
        match (lexer.Peek())
        {
          | Token.Keyword(kwd) when kwd == keyword => 
            _ = lexer.GetAnyToken();
            sucsessContinuation()
          
          | _ => failValue
        }
      }
      def tryPeekAnyToken(tokenName : string) : bool
      {
        def tok = lexer.GetAnyToken();
        lexer.PushBack(tok);
        
        match (tok)
        {
          | Token.Comma with x = ","
          | Token.Operator(x) 
          | Token.Keyword(x)  
          | Token.Identifier(x) => x == tokenName
          | _ => false
        }
      }
      def parseIdentifier() : Name
      {
        def tok = lexer.GetAnyToken();
        
        match (tok)
        {
          | Token.Identifier(name) as tok => Name(name, tok.Location) //It's OK!
          | _ => 
            Message.Error(tok.Location, $"expected identifier but found '$tok'");
            throw ParseErrorException();
        }
      }
      def parseExpr() : PExpr
      {
        def expr = MainParser.ParseExpr(lexer.Env, lexer, false);
        expr
      }
      def parseFromClause(first) : QueryClause.From
      {
        expectKeyword("from");
        def paramName = parseIdentifier();
        expectKeyword("in");
        def expr = parseExpr();
        QueryClause.From(first + expr.Location, paramName, expr)
      }
      def parseSelectClause(first) : QueryClause.Select
      {
        expectKeyword("select");
        def expr = parseExpr();
        QueryClause.Select(first + expr.Location, expr)
      }
      def parseLetClause(first) : QueryClause.Let
      {
        expectKeyword("let");
        def paramName = parseIdentifier();
        expectKeyword("=");
        def expr = parseExpr();
        QueryClause.Let(first + expr.Location, paramName, expr)
      }
      def parseWhereClause(first) : QueryClause.Where
      {
        expectKeyword("where");
        def expr = parseExpr();
        QueryClause.Where(first + expr.Location, expr)
      }
      def parseJoinClause(first) : QueryClause.Join
      {
        expectKeyword("join");
        def ident = parseIdentifier();
        expectKeyword("in");
        def inExpr = parseExpr();
        def (loc, key1Expr, key2Expr, into) = if (tryExpectKeyword("on"))
        {
          def keyExprs = parseExpr();
          def (key1Expr, key2Expr) = match (keyExprs)
          {
            | <[ $key1Expr == $key2Expr ]> => (key1Expr, key2Expr)
            | _ =>
              Message.Error(keyExprs.Location, "expected key1 == key2 expression");
              (keyExprs, <[ () ]>)
              //throw ParseErrorException();
          }
          def into = tryParseKeyword("into", () => Some(parseIdentifier()), None());
          def last = match (into) { | Some(x) => x.Location | _ => key2Expr.Location };
          (first + last, key1Expr, key2Expr, into)
        }
        else (first + inExpr.Location, <[ () ]>, <[ () ]>, None());

        QueryClause.Join(loc, ident, inExpr, key1Expr, key2Expr, into)
      }
      def parseOrderClause(first) : QueryClause.Orderby
      {
        def parseOrderings() : list[PExpr * bool]
        {
          def expr = parseExpr();
          def ascending1 =                 tryParseKeyword("desc",       () => false, true);
          def ascending2 = if (ascending1) tryParseKeyword("descending", () => false, true) // C# syntax
                           else false;
          def ascending3 = if (ascending2) tryParseKeyword("ascending",  () => true,  true) // C# syntax
                           else false;
          
          if (tryPeekAnyToken(","))
          {
            _ = lexer.GetAnyToken();
            (expr, ascending3) :: parseOrderings()
          }
          else (expr, ascending3) :: []
        }
        unless (tryParseKeyword("order", () => { expectKeyword("by"); true }, false))
          expectKeyword("orderby");
        def orderings = parseOrderings();
        def last = if (orderings.IsEmpty) lexer.Location else orderings.Last[0].Location;
        QueryClause.Orderby(first + last, orderings)
      }
      def parseGroupClause(first) : QueryClause.Group
      {
        expectKeyword("group");
        def expr = parseExpr();
        expectKeyword("by");
        def byExpr = parseExpr();
        QueryClause.Group(first + byExpr.Location, expr, byExpr)
      }
      def parseQueryBody() : list[QueryClause]
      {
        def tok = lexer.Peek();
        def first = tok.Location;
        def clause = match (tok)
          {
            | Token.Keyword("from")   => parseFromClause(first)
            | Token.Keyword("select") => parseSelectClause(first)
            | Token.Keyword("let")    => parseLetClause(first)
            | Token.Keyword("where")  => parseWhereClause(first)
            | Token.Keyword("join")   => parseJoinClause(first)
            | Token.Keyword("orderby")
            | Token.Keyword("order")  => parseOrderClause(first)
            | Token.Keyword("group")  => parseGroupClause(first)
            | Token.Keyword("into")   => parseIntoClause(first)
            | Token.EndOfFile => null
            | _ => null 
              //TODO: Add error report
          };
          
        def res = if (clause == null) []
                  else clause :: parseQueryBody();
        res
      }
      and parseIntoClause(first) : QueryClause.Into
      {
        expectKeyword("into");
        def ident = parseIdentifier();
        QueryClause.Into(first + ident.Location, ident)
      }
      def convertQuery(collection : PExpr, queryClauses : list[QueryClause], parms : SCG.List[PExpr]) : PExpr
      {
        def make_x_param(parms : SCG.List[PExpr]) : PExpr
        {
          assert2(!parms.IsEmpty());
          if (parms.Count == 1) parms[0] else PExpr.Tuple(NList.ToList(parms), 1)
        }
        def appendArgToTuple(paramExpr, exprForAppend) : PExpr.Tuple
        {
          match (paramExpr)
          {
            | PExpr.Tuple(args) => PExpr.Tuple.Create(args + [exprForAppend])
            | _                 => PExpr.Tuple.Create([paramExpr, exprForAppend])
          }
        }
        match (queryClauses)
        {
          | QueryClause.From(ident1, inExpr1) :: QueryClause.From(ident2, inExpr2) :: QueryClause.Select(selExpr) :: tail 
          | QueryClause.From(ident1, inExpr1) :: QueryClause.From(ident2, inExpr2) :: tail with selExpr = null =>
            // from x1 in e1 from x2 in e2 ==> e1.SelectMany( x1 => e2 , ( x1 , x2 ) => new { x1 , x2 } )
            def p1 = <[ $(ident1 : name) ]>;
            def p2 = <[ $(ident2 : name) ]>;
            parms.Add(p1);
            parms.Add(p2);
            
            def selExpr2 = if (selExpr == null) <[ ($p1, $p2) ]> else selExpr;
            
            def newCollection = <[ $inExpr1.SelectMany($p1 => $inExpr2,  (($p1, $p2)) => $selExpr2) ]>;
            convertQuery(newCollection, tail, parms)
          
          | QueryClause.From(ident, inExpr) :: tail => 
            parms.Add(<[ $(ident : name) ]>);
            convertQuery(inExpr, tail, parms)
            
          | QueryClause.Where(expr) as clause :: tail =>
            // from x in e
            // where f
            // from x in ( e ) . Where ( x => f )
            def e = collection;
            def x = make_x_param(parms);
            def newCollection = Util.locate(clause.Location, <[ $e.Where($x => $expr) ]>);
            convertQuery(newCollection, tail, parms)

          | QueryClause.Select(expr) :: tail =>
            //TODO: Тут надо как-то извлекать список имен колонок и копировать его в parms
            def x = make_x_param(parms);
            def newCollection = <[ $collection.Select($x => $expr) ]>;
            convertQuery(newCollection, tail, parms)
            
          | QueryClause.Join(ident, inExpr, k1, k2, into) :: tail =>
            // from x1 in e1    join x2 in e2 on k1 equals k2 
            def e1 = collection;
            def e2 = inExpr;
            def x1 = make_x_param(parms);
            def x2 = <[ $(ident : name) ]>;
            def newCollection = match (into)
            {
              | Some(intoName) => 
                def g = <[ $(intoName : name)]>;
                parms.Add(g);
                // e1.GroupJoin(e2 , x1 => k1, x2 => k2, (x1, g) => new { x1 , g })
                def x1_g = appendArgToTuple(x1, g);
                <[ $e1.GroupJoin($e2, $x1 => $k1, $x2 => $k2, ($x1, $g) => $x1_g) ]>;
                
              | None => 
                parms.Add(x2);
                // from * in (e1).Join(e2, x1 => k1, x2 => k2, (x1, x2) => new { x1 , x2 })
                def x1_x2 = appendArgToTuple(x1, x2);
                <[ $e1.Join($e2, $x1 => $k1, $x2 => $k2, ($x1, $x2) => $x1_x2) ]>;
            };
            convertQuery(newCollection, tail, parms)
            
          | QueryClause.Let(ident, expr) :: tail =>
            // from x in e  
            // let y = f
            // from * in ( e ) . Select ( x => new { x , y = f } )
            def e = collection;
            def x = make_x_param(parms);
            def x_f = appendArgToTuple(x, expr);
            def newCollection = <[ $e.Select($x => $x_f) ]>;
            parms.Add(<[ $(ident : name) ]>);
            convertQuery(newCollection, tail, parms)
            
          | QueryClause.Orderby([]) as o :: tail =>
            Message.Error(o.Location, "a orderby clause should contains one or more orderings");
            convertQuery(collection, tail, parms)

          | QueryClause.Orderby((ordExpr, direction) :: tailOrderings) :: tail =>
            // from x in e   orderby k1 , k2 , … , kn  ==>
            // e.OrderBy(x => k1).ThenBy(x => k2). … .ThenBy(x => kn)
            
            def e = collection;
            def x = make_x_param(parms);
            // e.OrderBy(x => k1)
            def newCollection1 = if (direction) <[ $e.OrderBy          ($x => $ordExpr) ]>
                                 else           <[ $e.OrderByDescending($x => $ordExpr) ]>;
            // .ThenBy(x => k2). … .ThenBy(x => kn)
            def convertTailOrderings(x : PExpr, orderings, e : PExpr) : PExpr
            {
              match (orderings)
              {
                | (ordExpr, direction) :: tail =>
                  def new_e = if (direction) <[ $e.ThenBy          ($x => $ordExpr) ]>
                              else           <[ $e.ThenByDescending($x => $ordExpr) ]>;
                  convertTailOrderings(x, tail, new_e)
                  
                | [] => e
              }
            }            
            def newCollection2 = convertTailOrderings(x, tailOrderings, newCollection1);
                                
            convertQuery(newCollection2, tail, parms)
            
          | QueryClause.Group(expr, byExpr) :: tail =>
            // from x in e group v by k
            // e.GroupBy(x => k, x => v)   ||   e.GroupBy(x => k) WHERE v is x
            def e = collection;
            def x = make_x_param(parms);
            def v = expr;
            def k = byExpr;
            def newCollection = <[ $e.GroupBy($x => $k, $x => $v) ]>;
            //TODO: Implement: e.GroupBy(x => k) WHERE v is x
            convertQuery(newCollection, tail, parms)
            
          | QueryClause.Into(ident) :: tail =>
            // from … into x … 
            // from x in ( from … ) …

            // reset all params and add new one (x)
            def newParms = SCG.List();
            newParms.Add(<[ $(ident : name) ]>);
            // try continue convertions
            convertQuery(collection, tail, newParms);
          
          | [] => collection
          | queryClaus :: _ => 
            def clausName = queryClaus.GetType().Name.ToLower();
            Message.Error(queryClaus.Location, $"clause '$clausName' not supported yet");
            collection
        }
      }
      def parseQuery() : list[QueryClause]
      {
        def from = parseFromClause(lexer.Location);
        def queryBody = parseQueryBody();
        def query = from :: queryBody;
        query
      }
      
      typer.Env.Manager.MacroColors.PushUseSiteColor();
      try { convertQuery(null, parseQuery(), SCG.List()) }
      catch { | _ => <[ () ]> }
      finally { typer.Env.Manager.MacroColors.PopColor(); }
    }
  }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Браузер кода Nemerle: подсветка работает
От: catbert  
Дата: 07.06.10 19:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>К тому же без проекта типы правильно не подсветить. Плюс строки не подсвечиваются.


Проект уже есть, вот только от проекта до подсветки типов неблизко.

Строки подсвечиваются, и обычные, и рекурсивные, но вот заметить коричневый цвет на синем фоне сложно

VD>Что до клюков, то попытка залить туда код приведенный ниже привела к "Server Error in '/code' Application.".


Глюк я уже поправил: ASP очень уж заботился о защите кода от XSS
Re[4]: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.10 19:19
Оценка:
Здравствуйте, catbert, Вы писали:

C>Сейчас вроде нормально должно быть.


Вот этот файл приводит к некислым тормозам.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.10 19:21
Оценка:
Здравствуйте, catbert, Вы писали:

C>Строки подсвечиваются, и обычные, и рекурсивные, но вот заметить коричневый цвет на синем фоне сложно


Понял. Не подсвечиваются $-строки. Например:
 Message.Error(tok.Location, $"expected keyword $keywordName but found '$tok'");
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.06.10 19:28
Оценка:
Здравствуйте, catbert, Вы писали:

C>Проект уже есть, вот только от проекта до подсветки типов неблизко.


Мне кажется самым правильным подходом для такого как у тебя решения было бы сделать плагин к компилятору, который после завершения компиляции прошелся бы по конечному АСТ и собрал бы всю необходимую информацию для подсветки типов и генерации перекрестных ссылок.

Интеграции нужно работать быстро, по этому она делает множество "приседаний". В твоем же случае можно спокойно дождаться окончания компиляции и пройтись по готовым структрам.

Кстати, интеграция пока что не может работать с проектом компилятора. Если бы твой код смог сгенерировать перекрестные ссылки для кода компилятора, то это очень помогло бы развитию самого компилятора, так как навигация по коду компилятора сильно упростилась бы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Браузер кода Nemerle: подсветка работает
От: hardcase Пират http://nemerle.org
Дата: 07.06.10 19:46
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Кстати, интеграция пока что не может работать с проектом компилятора. Если бы твой код смог сгенерировать перекрестные ссылки для кода компилятора, то это очень помогло бы развитию самого компилятора, так как навигация по коду компилятора сильно упростилась бы.


В SharpDevelop точно работает Class View, правда без наследований, никак не соберусь их прикрутить.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[8]: Браузер кода Nemerle: подсветка работает
От: Воронков Василий Россия  
Дата: 07.06.10 19:50
Оценка:
Здравствуйте, hardcase, Вы писали:

VD>>Кстати, интеграция пока что не может работать с проектом компилятора. Если бы твой код смог сгенерировать перекрестные ссылки для кода компилятора, то это очень помогло бы развитию самого компилятора, так как навигация по коду компилятора сильно упростилась бы.

H>В SharpDevelop точно работает Class View, правда без наследований, никак не соберусь их прикрутить.

А как это связано с Class View? AFAIR Class View и навигация начинают работать в #D, когда ты реализуешь их интерфейсик (что-то типа IParser), который конвертит AST в CodeDom. Но там не совсем та навигация, о которой речь. Для Class View, собственно, и типизация-то не нужна. Навигации же хотелось бы такой же, как в том же Рефлекторе — т.е. внутри тел методов по коду.
Re[5]: Браузер кода Nemerle: подсветка работает
От: catbert  
Дата: 07.06.10 21:24
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Вот этот файл приводит к некислым тормозам.


Да не должен бы в теории... там же только Lexer+PreParser.

Да и на практике не могу заметить тормозов. Возможно, в этот же момент мой комп занимался чем-то процессоро-интенсивным.
Re[7]: Браузер кода Nemerle: подсветка работает
От: catbert  
Дата: 07.06.10 21:29
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Понял. Не подсвечиваются $-строки. Например:

VD>
VD> Message.Error(tok.Location, $"expected keyword $keywordName but found '$tok'"); 
VD>


Пофиксил, в связи с чем вопрос. Есть какая-то вменяемая причина, почему LooseGroup не сохраняет список своих токенов в list[Token], а лишь первый из них?
Re[7]: Браузер кода Nemerle: подсветка работает
От: catbert  
Дата: 07.06.10 21:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Мне кажется самым правильным подходом для такого как у тебя решения было бы сделать плагин к компилятору, который после завершения компиляции прошелся бы по конечному АСТ и собрал бы всю необходимую информацию для подсветки типов и генерации перекрестных ссылок.


Приблизительно в этом направлении я работаю. Но мне кажется, можно сделать универсальную "карту" символов для любого языка, чтобы браузер кода работал не только в Nemerle (ну, в стиле PDB).

VD>Кстати, интеграция пока что не может работать с проектом компилятора. Если бы твой код смог сгенерировать перекрестные ссылки для кода компилятора, то это очень помогло бы развитию самого компилятора, так как навигация по коду компилятора сильно упростилась бы.


Ну, учитывая то, что:

VD>Интеграции нужно работать быстро, по этому она делает множество "приседаний". В твоем же случае можно спокойно дождаться окончания компиляции и пройтись по готовым структрам.


не знаю, будет ли мое «спокойное» решение полезно для «быстрой» интеграции.
Re: Браузер кода Nemerle: подсветка работает
От: _nn_ www.nemerleweb.com
Дата: 08.06.10 06:26
Оценка:
Здравствуйте, catbert, Вы писали:

def q = <#
my string
#>;
def p = linq <# from i in a select i #>;
def u = "string";


Все три строки подсвечиваются одинаково.
Мне кажется просто строковой литерал должен подсвечиваться как здесь на rsdn.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.06.10 10:48
Оценка:
Здравствуйте, catbert, Вы писали:

C>Пофиксил, в связи с чем вопрос. Есть какая-то вменяемая причина, почему LooseGroup не сохраняет список своих токенов в list[Token], а лишь первый из них?


Нет. Можешь поправить, если нужно. Только тесты все прогони перед комитом.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Браузер кода Nemerle: подсветка работает
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.06.10 10:51
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>А как это связано с Class View? AFAIR Class View и навигация начинают работать в #D, когда ты реализуешь их интерфейсик (что-то типа IParser), который конвертит AST в CodeDom.


Я тебе уже говорил, что IParser и вся их идеология гнилая. Она только на языки типа шарпа подходит. Как я понял, hardcase разными изворотами прикрутил туда полноценную интеграцию. Так что IParser он попросту обходит (использует не совсем по назначению).

ВВ>Но там не совсем та навигация, о которой речь. Для Class View, собственно, и типизация-то не нужна. Навигации же хотелось бы такой же, как в том же Рефлекторе — т.е. внутри тел методов по коду.


Это да. В студии она работает (с ошибками, пока). Но в студии не грузится проект компилятора. Надо посидеть над этим делом.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Браузер кода Nemerle: подсветка работает
От: hardcase Пират http://nemerle.org
Дата: 08.06.10 11:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это да. В студии она работает (с ошибками, пока). Но в студии не грузится проект компилятора. Надо посидеть над этим делом.


А я-то сперва думал что запрос на тултип в исходниках компилятора сносил бошку SharpDevelop по моей вине.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[10]: Браузер кода Nemerle: подсветка работает
От: Воронков Василий Россия  
Дата: 08.06.10 11:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я тебе уже говорил, что IParser и вся их идеология гнилая. Она только на языки типа шарпа подходит. Как я понял, hardcase разными изворотами прикрутил туда полноценную интеграцию. Так что IParser он попросту обходит (использует не совсем по назначению).


Насколько я помню, там IParser использовался для фолдинга и Класс-вью. Собственно, и все. А для Класс-Вью зачем типизация?

ВВ>>Но там не совсем та навигация, о которой речь. Для Class View, собственно, и типизация-то не нужна. Навигации же хотелось бы такой же, как в том же Рефлекторе — т.е. внутри тел методов по коду.

VD>Это да. В студии она работает (с ошибками, пока). Но в студии не грузится проект компилятора. Надо посидеть над этим делом.

С самим проектом компилятора нельзя работать из студии?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.