I've updated the VS Language service to VS 2010.. refactored it.

Nov 19, 2010 at 9:17 PM

Hi Roman,

I've refactored the Visual Studio Language Service project on CodePlex to use VS 2010, and factored most of the code into a separate assembly Irony.VisualStudio.LanguageService.dll which handles everything except for the configuration, grammar, and the vs package itself.    This dll allows you to create a language service with a project of just 3 very short files, one of them being the grammar.

I think this would make a nice addition to the base project, along with a VSIX installable template for creating your own language service.  Do you think this could be added to the default irony source base.

Two problems I'm currently having though:

One is that the Location in irony doesn't take into account the current tab size setting.  Where is the current tab size set in Irony.  I'm sure I could find it if I do a deep search, but maybe you could help me out.  Irony is currently assuming 8 char tabs, and mine are 4.  VS tells you what the current file setting is, but Irony needs to be informed.

The other is that in many cases, the raw parser error information coming from irony is not very informative (I often get an error unexpected character 'i', for example).  I'd like to have a chance to handle errors myself for various parse tree non-terminals.  Is this possible.. easy?

Finally, is an Irony grammar Xaml serializable?  (i.e. do grammar elements have public setters, and a default constructor, etc.)   Might be nice to be able to define grammars in Xaml and load them on the fly.

Thanks.

Nov 20, 2010 at 3:18 AM

For the tab size issue, the TabSize from the Context needs to update the SourceStream tab size when Parse is called.  There is no way to actually set the SourceStream in the current system, so no way to change the tab size as far as I can tell.  I think the intention was that the TabWidth can be changed in the Context, which would affect the next call to Parse, and that's what I changed.

Line 49, Parser.cs:

    public ParseTree Parse(string sourceText, string fileName) {
      AutoReset();
      Context.SourceStream.TabWidth = Context.TabWidth;
      Context.SourceStream.SetText(sourceText, 0, Context.Status == ParserStatus.AcceptedPartial);

The SourceStream TabWidth property needs to be made either internal or public.  I chose internal.

Thanks.

 

Nov 20, 2010 at 4:56 AM

Also, to make the line scanner work in the language serivce.  I formatted the code in the current style of the file.

ParsingContext.cs line 55:

    public int TabWidth {
      get { return _tabWidth; }
      set {
        _tabWidth = value;
        if (SourceStream != null) {
          SourceStream.TabWidth = value;
        }
      }
    } int _tabWidth = 8;

Coordinator
Nov 21, 2010 at 4:42 PM

Hi

About VS integration - would be happy to look at it and include in code base. Contact me directly (through this site, Contact user feature), I'll reply and you'll send zip

About problems you describe.

Tab size - I know about the problem; the main problem is that (as user yallie pointed in one of previous discussions - cannot find the discussion), so the real problem is that tab handling in incorrect. Instead of "skipping" n symbols on Tab, the code should move to the next position which is multiple of "n". That's how tabbing behaves in general in apps. So I need to fix that

Error handling - I'm working on the fix; there's already a grammar method "ConstructParserErrorMessage" that you can override to customize the message; the problem is that it is called not for all messages. I will be submitting the fix shortly

About Xaml-serialiation - have no idea what you're talking about

Roman

Nov 29, 2010 at 9:16 AM

> About VS integration - would be happy to look at it and include in code base. Contact me directly (through this site, Contact user feature), I'll reply and you'll send zip.

I'm going to fix the original template for the 2008 project, then send it.

>Tab size - I know about the problem; the main problem is that (as user yallie pointed in one of previous discussions - cannot find the discussion), so the real problem is that tab >handling in incorrect. Instead of "skipping" n symbols on Tab, the code should move to the next position which is multiple of "n". That's how tabbing behaves in general in apps. So I >need to fix that

Not sure about that.  My fix was to just allow the TabWidth properties in SourceText and ParseContext to be set by the application.  No problem.   With this fix irony seems to work correctly (as far as I can tell). Unfortunately the visual studio language service doesn't seem to correctly draw the red error underscores based on the editor tab size, so it looks like I may need to go directly to the text editor to draw the underscores manually using the new WPF editor system.

>Error handling - I'm working on the fix; there's already a grammar method "ConstructParserErrorMessage" that you can override to customize the message; the problem is that it is called not for all messages. I will be submitting the fix shortly

It looks like the scanner is throwing an error recognizing what should be valid tokens before the parser has a chance to actually throw a useful parsing error.  I'm getting "Invalid character "x" when I type a valid keyword or identifier in the wrong place.  Shouldn't the scanner be tokenizing the identifier and/or keywords, then letting the parser notice that they're unexpected?

> About Xaml-serialiation - have no idea what you're talking about.

Xaml just allows you to read in a tree of .NET objects directly to and from XML files without any other setup (if the classes follow a few basic rules).  The names of the xml tags are the class names, and the attributes are public properties.  It's generally useful for instantiating or writing out DAG's of objects without having to write any serialization code.   Just wondering if it would be possible to use XamlReader.Load() or XamlWriter.Save() to read or write a grammar to/from a xaml file.

 

 

 

 

 

Coordinator
Nov 30, 2010 at 7:19 PM

TabSize - added your code snippet in the latest code drop;

Error handling - fixed and improved; now you have full control over the message in all cases.

Xaml - serialization... seems fancy, but what it can be used for?

thanks

Roman

Dec 1, 2010 at 4:19 AM

> Xaml - serialization... seems fancy, but what it can be used for?

Editing grammars on the fly and loading and saving them.

One more thing.. I changed ParserMessage to return a SourceSpan instead of a SourceLocation (the language service wants a span).  The error highligher on the language service uses the span to highlight exactly the text that is incorrect.  The old language service just highlighted the whole line.

------ ParserMessage.cs -------

  public class ParserMessage {
    public ParserMessage(ParserErrorLevel level, SourceSpan span, string message, ParserState parserState) {
      Level = level;
      Span = span;
      Message = message;
      ParserState = parserState;
    }

    public readonly ParserErrorLevel Level;
    public readonly ParserState ParserState;
    public readonly SourceSpan Span;
    public readonly string Message;

    public SourceLocation Location {
      get { return Span.Location; }
    }

    public override string ToString() {
      return Message;
    }
  }//class

-----------

--------- ParsingContext.cs ---------------

    public void AddParserError(string message, params object[] args) {
      var span = CurrentParserInput == null? new SourceSpan(Source.Location, 1) : CurrentParserInput.Span;
      HasErrors = true;
      AddParserMessage(ParserErrorLevel.Error, span, message, args);
    }
    public void AddParserMessage(ParserErrorLevel level, SourceSpan span, string message, params object[] args) {
      if (CurrentParseTree == null) return;
      if (CurrentParseTree.ParserMessages.Count >= MaxErrors) return;
      if (args != null && args.Length > 0)
        message = string.Format(message, args);
      CurrentParseTree.ParserMessages.Add(new ParserMessage(level, span, message, CurrentParserState));
      if (OptionIsSet(ParseOptions.TraceParser))
        ParserTrace.Add( new ParserTraceEntry(CurrentParserState, ParserStack.Top, CurrentParserInput, message, true));
    }

    public void AddTrace(string message, params object[] args) {
      if (!OptionIsSet(ParseOptions.TraceParser)) return;
      if (args != null && args.Length > 0)
        message = string.Format(message, args);
      ParserTrace.Add(new ParserTraceEntry(CurrentParserState, ParserStack.Top, CurrentParserInput, message, false));
    }

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

A few other files modified to either pass a span, or to create a span with a length of 1 if they don't have one.

 

 

 

 

Dec 1, 2010 at 4:37 AM

Updating my project, I noticed exceptions being thrown in ParseTreeNode for FirstChild and LastChild.  This seems to fix it.

-------- ParseTree.cs Line 103 -------

    public ParseTreeNode FirstChild {
      get { return ChildNodes.Count > 0 ? ChildNodes[0] : null; }
    }
    public ParseTreeNode LastChild {
      get { return ChildNodes.Count > 0 ? ChildNodes[ChildNodes.Count -1] : null; }
    }

Coordinator
Dec 1, 2010 at 10:24 PM

Ok, will add it. thanks!

Roman

Dec 10, 2010 at 6:14 PM

I'm at this point in my project (meaning that I'm working on the language service because the grammar part is done).  Any idea when we will see this in the repository?

Jere

Dec 10, 2010 at 6:17 PM

And an example on how to create a language service?  I would like to add Clojure to to VS.

Oct 6, 2012 at 12:25 PM

Sorry to revive this thread, but I'd like to know if there have been any updates

Coordinator
Oct 9, 2012 at 5:40 PM

no new development on this, sorry

Roman