Permalink
Browse files

Merge remote-tracking branch 'origin/master'

Conflicts:
	ParserGenerator.sln
  • Loading branch information...
2 parents 055446b + 0ac0190 commit 3666b1b364d3cbf942587a385aba13a07fa22661 @rampelstinskin committed Apr 4, 2012
View
@@ -144,20 +144,29 @@ public partial abstract class N2Parser
def grammarsAttr = typeof(GrammarsAttribute);
def standardAssemblies = HashSet(["Nemerle.dll", "Nemerle.Compiler.dll", "Nemerle.Parser.dll", "Nemerle.Parser.Macro.dll"]);
+ // Обрабатываем фалы не входящие в список сборок самого немерла (стандратные сборки).
+ // В них точно не может быть парсеров.
foreach (file when !standardAssemblies.Contains(file) in files)
{
def asm = Assembly.LoadFrom(file);
def attrs = asm.GetCustomAttributesData();
+ // Для каждого GrammarsAttribute...
foreach (attr when attr.Constructor.DeclaringType.Equals(grammarsAttr) in attrs)
{
+ // ... получаем список GrammarsAttribute-ов...
def attrInstances = asm.GetCustomAttributes(grammarsAttr, false) :> array[GrammarsAttribute];
+ // в GrammarsAttribute описаны грамматики (расширения парсеров). Перебираем их...
foreach (attrInstance in attrInstances)
foreach (type in attrInstance.Grammars)
{
+ // Парсер описвается GrammarDescriptor-ом. Он доступен через статическое поле "StaticDescriptor".
+ // Получаем StaticDescriptor-ы и добавляем их в хэш-таблицу.
def prop = type.GetProperty("StaticDescriptor");
def value = prop.GetValue(null, null) :> GrammarDescriptor;
+ // TODO: FIXME: Могут существовать StaticDescriptor-ы с одинаковым полным именем.
+ // В мапе нужно хранить их список, а не конекретные экзепляры.
_grammarDescriptors.Add(value.FullName, value);
}
}
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{EDCC3B85-0BAD-11DB-BC1A-00112FDE8B61}") = "Rsdn.N2.VisualStudio", "Rsdn.N2.VisualStudio\Rsdn.N2.VisualStudio.nproj", "{24F81277-B44D-4F87-8906-44FE08BB958C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Debug|Any CPU.Build.0 = Debug|x86
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Debug|x86.ActiveCfg = Debug|x86
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Debug|x86.Build.0 = Debug|x86
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Release|x86.ActiveCfg = Release|x86
+ {24F81277-B44D-4F87-8906-44FE08BB958C}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
@@ -0,0 +1,241 @@
+using Nemerle.Imperative;
+
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+
+using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Tagging;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Rsdn.N2.VisualStudio
+{
+ internal class BraceMatchingTagger : ITagger [ TextMarkerTag ]
+ {
+ private m_braceList : Dictionary[char, char];
+
+ internal this ( view : ITextView, sourceBuffer : ITextBuffer )
+ {
+ //here the keys are the open braces, and the values are the close braces
+ m_braceList = Dictionary();
+ m_braceList.Add('{', '}');
+ m_braceList.Add('[', ']');
+ m_braceList.Add('(', ')');
+ this.View = view;
+ this.SourceBuffer = sourceBuffer;
+ this.CurrentChar = null;
+
+ this.View.Caret.PositionChanged += CaretPositionChanged;
+ this.View.LayoutChanged += ViewLayoutChanged;
+ }
+
+ View : ITextView
+ {
+ get; set;
+ }
+
+ SourceBuffer : ITextBuffer
+ {
+ get;
+ set;
+ }
+
+ CurrentChar : SnapshotPoint?
+ {
+ get;
+ set;
+ }
+
+ public event TagsChanged : EventHandler [ SnapshotSpanEventArgs ];
+
+ ViewLayoutChanged ( _ : object, e : TextViewLayoutChangedEventArgs ) : void
+ {
+ unless (e.NewSnapshot == e.OldSnapshot : object) //make sure that there has really been a change
+ UpdateAtCaretPosition(View.Caret.Position);
+ }
+
+ CaretPositionChanged ( _ : object, e : CaretPositionChangedEventArgs ) : void
+ {
+ UpdateAtCaretPosition ( e.NewPosition );
+ }
+
+ UpdateAtCaretPosition ( caretPosition : CaretPosition ) : void
+ {
+ CurrentChar = caretPosition.Point.GetPoint ( SourceBuffer, caretPosition.Affinity );
+
+ when ( CurrentChar.HasValue )
+ {
+ def tempEvent = TagsChanged;
+ when ( tempEvent != null )
+ tempEvent ( this, SnapshotSpanEventArgs ( SnapshotSpan ( SourceBuffer.CurrentSnapshot, 0, SourceBuffer.CurrentSnapshot.Length ) ) );
+ }
+ }
+
+ public GetTags(spans : NormalizedSnapshotSpanCollection) : IEnumerable[ITagSpan[TextMarkerTag]]
+ {
+ when (spans.Count == 0) //there is no content in the buffer
+ Nemerle.Imperative.Return ();
+
+ //don't do anything if the current SnapshotPoint is not initialized or at the end of the buffer
+ when (!CurrentChar.HasValue || CurrentChar.Value.Position >= CurrentChar.Value.Snapshot.Length)
+ Nemerle.Imperative.Return ();
+
+ //hold on to a snapshot of the current character
+ mutable currentChar = CurrentChar.Value;
+
+ //if the requested snapshot isn't the same as the one the brace is on, translate our spans to the expected snapshot
+ when ( spans [ 0 ].Snapshot != currentChar.Snapshot : object )
+ currentChar = currentChar.TranslateTo ( spans [ 0 ].Snapshot, PointTrackingMode.Positive );
+
+ //get the current char and the previous char
+ def currentText = currentChar.GetChar ( );
+ def lastChar = if ( currentChar == 0 ) currentChar else currentChar - 1; //if currentChar is 0 (beginning of buffer), don't move it back
+ def lastText = lastChar.GetChar ( );
+ mutable pairSpan = SnapshotSpan ( );
+
+ if (m_braceList.ContainsKey ( currentText ) ) //the key is the open brace
+ {
+ mutable closeChar;
+ _ = m_braceList.TryGetValue ( currentText, out closeChar );
+ when ( BraceMatchingTagger.FindMatchingCloseChar ( currentChar, currentText, closeChar, View.TextViewLines.Count, out pairSpan ) )
+ {
+ yield TagSpan ( SnapshotSpan ( currentChar, 1 ), TextMarkerTag ( "blue" ) );
+ yield TagSpan ( pairSpan, TextMarkerTag ( "blue" ) );
+ }
+ }
+ else when ( m_braceList.ContainsValue ( lastText ) ) //the value is the close brace, which is the *previous* character
+ {
+ def open = m_braceList.Where ( a => a.Value.Equals ( lastText ) ).Select ( a => a.Key );
+ when ( BraceMatchingTagger.FindMatchingOpenChar ( lastChar, open.ElementAt ( 0 ), lastText, View.TextViewLines.Count, out pairSpan ) )
+ {
+ yield TagSpan ( SnapshotSpan ( lastChar, 1 ), TextMarkerTag ( "blue" ) );
+ yield TagSpan ( pairSpan, TextMarkerTag ( "blue" ) );
+ }
+ }
+ }
+
+ private static FindMatchingCloseChar(startPoint : SnapshotPoint, open : char, close : char, maxLines : int, pairSpan : out SnapshotSpan) : bool
+ {
+ pairSpan = SnapshotSpan(startPoint.Snapshot, 1, 1);
+ mutable line = startPoint.GetContainingLine();
+ mutable lineText = line.GetText();
+ mutable lineNumber = line.LineNumber;
+ mutable offset = startPoint.Position - line.Start.Position + 1;
+
+ mutable stopLineNumber = startPoint.Snapshot.LineCount - 1;
+
+ when (maxLines > 0)
+ stopLineNumber = Math.Min(stopLineNumber, lineNumber + maxLines);
+
+ mutable openCount = 0;
+ mutable founded = false;
+ while (true)
+ {
+ //walk the entire line
+ while (offset < line.Length && !founded)
+ {
+ mutable currentChar = lineText[offset];
+ if (currentChar == close) //found the close character
+ {
+ if (openCount > 0)
+ {
+ openCount--;
+ }
+ else //found the matching close
+ {
+ pairSpan = SnapshotSpan(startPoint.Snapshot, line.Start + offset, 1);
+ founded = true;
+ }
+ }
+ else when (currentChar == open) // this is another open
+ openCount++;
+ offset++;
+ }
+
+ if (!founded)
+ {
+ //move on to the next line
+ lineNumber++;
+ when ( lineNumber > stopLineNumber)
+ break;
+
+ line = line.Snapshot.GetLineFromLineNumber(lineNumber);
+ lineText = line.GetText();
+ offset = 0;
+ }
+ else
+ break;
+ }
+
+ founded;
+ }
+
+ private static FindMatchingOpenChar(startPoint : SnapshotPoint, open : char, close : char, maxLines : int, pairSpan : out SnapshotSpan) : bool
+ {
+ pairSpan = SnapshotSpan(startPoint, startPoint);
+
+ mutable line = startPoint.GetContainingLine();
+
+ mutable lineNumber = line.LineNumber;
+ mutable offset = startPoint - line.Start - 1; //move the offset to the character before this one
+
+ //if the offset is negative, move to the previous line
+ when (offset < 0)
+ {
+ lineNumber--;
+ line = line.Snapshot.GetLineFromLineNumber(lineNumber);
+ offset = line.Length - 1;
+ }
+
+ mutable lineText = line.GetText();
+
+ mutable stopLineNumber = 0;
+ when (maxLines > 0)
+ stopLineNumber = Math.Max(stopLineNumber, lineNumber - maxLines);
+
+ mutable closeCount = 0;
+ mutable founded = false;
+
+ while (true)
+ {
+ // Walk the entire line
+ while (offset >= 0 && !founded)
+ {
+ mutable currentChar = lineText[offset];
+
+ if (currentChar == open)
+ {
+ if (closeCount > 0)
+ closeCount--;
+ else // We've found the open character
+ {
+ pairSpan = SnapshotSpan(line.Start + offset, 1); //we just want the character itself
+ founded = true;
+ }
+ }
+ else when (currentChar == close)
+ closeCount++;
+ offset--;
+ }
+
+ if (!founded)
+ {
+ lineNumber--;
+
+ // Move to the previous line
+ when (lineNumber < stopLineNumber)
+ break;
+
+ line = line.Snapshot.GetLineFromLineNumber(lineNumber);
+ lineText = line.GetText();
+ offset = line.Length - 1;
+ }
+ else
+ break;
+ }
+ founded;
+ }
+ }
+}
@@ -0,0 +1,29 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+
+using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Tagging;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Rsdn.N2.VisualStudio
+{
+ [Export ( typeof ( IViewTaggerProvider ) )]
+ [ContentType ( "Nemerle" ) ]
+ [TagType ( typeof ( TextMarkerTag ) )]
+ internal class BraceMatchingTaggerProvider : IViewTaggerProvider
+ {
+ public CreateTagger [ T ] ( textView : ITextView, buffer : ITextBuffer ) : ITagger [ T ] where T : ITag
+ {
+ if ( textView == null )
+ null;
+ else
+ if ( textView.TextBuffer != buffer : object )
+ null;
+ else
+ BraceMatchingTagger ( textView, buffer ) :> ITagger [ T ];
+ }
+ }
+}
@@ -0,0 +1,30 @@
+#pragma warning disable 10003
+using Nemerle;
+using Nemerle.Collections;
+using Nemerle.Text;
+using Nemerle.Utility;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using System.ComponentModel.Composition;
+
+using Microsoft.VisualStudio.Text.Classification;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Rsdn.N2.VisualStudio
+{
+ internal static class FileAndContentTypeDefinitions
+ {
+ [Export]
+ [Name("hid")]
+ [BaseDefinition("text")]
+ internal static hidingContentTypeDefinition : ContentTypeDefinition;
+
+ [Export]
+ [FileExtension(".n")]
+ [ContentType("Nemerle")]
+ internal static hiddenFileExtensionDefinition : FileExtensionToContentTypeDefinition;
+ }
+}
@@ -0,0 +1,22 @@
+using Nemerle;
+using Nemerle.Collections;
+using Nemerle.Text;
+using Nemerle.Utility;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Microsoft.VisualStudio.Shell;
+
+namespace Rsdn.N2.VisualStudio
+{
+ [PackageRegistration(UseManagedResourcesOnly = true)]
+ public class N2Package : Package
+ {
+ public this ( )
+ {
+
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 3666b1b

Please sign in to comment.