Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasherceg committed Apr 14, 2015
2 parents a08ca67 + 1dfec97 commit fda492d
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public string FullTagName

public RwHtmlToken TagNameToken { get; set; }

public RwHtmlElementNode CorrespondingEndTag { get; internal set; }

public RwHtmlElementNode()
{
Expand Down
5 changes: 4 additions & 1 deletion src/Redwood.Framework/Parser/RwHtml/Parser/RwHtmlParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ public RwHtmlRootNode Parse(IList<RwHtmlToken> tokens)
}
else
{
var beginTagName = ((RwHtmlElementNode)ElementHierarchy.Peek()).FullTagName;
var beginTag = (RwHtmlElementNode)ElementHierarchy.Peek();
var beginTagName = beginTag.FullTagName;
if (beginTagName != element.FullTagName)
{
element.NodeErrors.Add(string.Format(RwHtmlParserErrors.ClosingTagHasNoMatchingOpenTag, beginTagName));
Expand All @@ -84,6 +85,8 @@ public RwHtmlRootNode Parse(IList<RwHtmlToken> tokens)
{
ElementHierarchy.Pop();
}

beginTag.CorrespondingEndTag = element;
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions src/Redwood.VS2015Extension/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Redwood.VS2015Extension
{
public static class Extensions
{

/// <summary>
/// Replaces a range in a StringBuilder with specified content.
/// </summary>
public static void SetRange(this StringBuilder sb, int start, int length, string content)
{
length = Math.Min(content.Length, length);
if (length < 0)
{
throw new ArgumentException("length");
}

for (int i = 0; i < length; i++)
{
if (start + i < sb.Length)
{
sb[start + i] = content[i];
}
else
{
sb.Append(content[i]);
}
}
}

}
}
1 change: 1 addition & 0 deletions src/Redwood.VS2015Extension/Redwood.VS2015Extension.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
<Compile Include="RwHtmlEditorExtensions\Classification\ClassificationStyle.cs" />
<Compile Include="RwHtmlEditorExtensions\Classification\RwHtmlBindingBraceDefinition.cs" />
<Compile Include="RwHtmlEditorExtensions\Classification\RwHtmlBindingContentDefinition.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="RwHtmlEditorExtensions\Classification\RwHtmlClassificationTypes.cs" />
<Compile Include="RwHtmlEditorExtensions\Classification\RwHtmlClassifier.cs" />
<Compile Include="RwHtmlEditorExtensions\Classification\RwHtmlClassifierProvider.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@ namespace Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtml
{
public class ControlMetadata
{

public string Name { get; set; }
public string Namespace { get; set; }
public List<ControlPropertyMetadata> Properties { get; set; }
public string TagPrefix { get; set; }
public string TagName { get; set; }

public string FullTagName
{
get { return string.IsNullOrEmpty(TagPrefix) ? TagName : (TagPrefix + ":" + TagName); }
}


public ControlPropertyMetadata GetProperty(string name)
{
return Properties.FirstOrDefault(p => string.Equals(p.Name, name, StringComparison.CurrentCultureIgnoreCase));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ internal List<CompletionData> ReloadAllControls(RwHtmlCompletionContext context)
.ToList();

var result = new List<CompletionData>();
metadata = new ConcurrentDictionary<string, ControlMetadata>();
metadata = new ConcurrentDictionary<string, ControlMetadata>(StringComparer.CurrentCultureIgnoreCase);

foreach (var rule in context.Configuration.Markup.Controls)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Utilities;
using System.Windows.Threading;

namespace Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions
{
Expand All @@ -25,12 +26,18 @@ internal class RwHtmlCompletionHandlerProvider : IVsTextViewCreationListener
[Import]
internal SVsServiceProvider ServiceProvider { get; set; }


public void VsTextViewCreated(IVsTextView textViewAdapter)
{
ITextView textView = AdapterService.GetWpfTextView(textViewAdapter);
if (textView == null)
return;

Dispatcher.CurrentDispatcher.InvokeAsync(() =>
{
var tempSession = CompletionBroker.CreateCompletionSession(textView, textView.TextSnapshot.CreateTrackingPoint(0, Microsoft.VisualStudio.Text.PointTrackingMode.Negative), true);
tempSession.Start();
tempSession.Dismiss();
}, DispatcherPriority.ApplicationIdle);

textView.Properties.GetOrCreateSingletonProperty(() => new RwHtmlCompletionCommandHandler(textViewAdapter, textView, this));
textView.Properties.GetOrCreateSingletonProperty(() => new RwHtmlFormatCommandHandler(textViewAdapter, textView));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public class RwHtmlCompletionSource : ICompletionSource
private readonly RedwoodConfigurationProvider configurationProvider;
private readonly RwHtmlClassifier classifier;
private readonly RwHtmlParser parser;
private readonly MetadataControlResolver metadataControlResolver;

public MetadataControlResolver MetadataControlResolver { get; private set; }

private static List<ICompletionSession> activeSessions = new List<ICompletionSession>();

Expand All @@ -42,7 +43,24 @@ public class RwHtmlCompletionSource : ICompletionSource
this.glyphService = glyphService;
this.dte = dte;
this.configurationProvider = configurationProvider;
this.metadataControlResolver = metadataControlResolver;
this.MetadataControlResolver = metadataControlResolver;
}

public RwHtmlCompletionContext GetCompletionContext()
{
var context = new RwHtmlCompletionContext()
{
Tokens = classifier.Tokens,
Parser = parser,
Tokenizer = classifier.Tokenizer,
RoslynWorkspace = workspace,
GlyphService = glyphService,
DTE = dte,
Configuration = configurationProvider.GetConfiguration(dte.ActiveDocument.ProjectItem.ContainingProject),
MetadataControlResolver = MetadataControlResolver
};
parser.Parse(classifier.Tokens);
return context;
}

public void AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
Expand All @@ -55,22 +73,11 @@ public void AugmentCompletionSession(ICompletionSession session, IList<Completio
var currentToken = tokens.FirstOrDefault(t => t.StartPosition <= cursorPosition && t.StartPosition + t.Length >= cursorPosition);
if (currentToken != null)
{
IEnumerable<SimpleRwHtmlCompletion> items = Enumerable.Empty<SimpleRwHtmlCompletion>();
var context = new RwHtmlCompletionContext()
{
Tokens = classifier.Tokens,
CurrentTokenIndex = classifier.Tokens.IndexOf(currentToken),
Parser = parser,
Tokenizer = classifier.Tokenizer,
RoslynWorkspace = workspace,
GlyphService = glyphService,
DTE = dte,
Configuration = configurationProvider.GetConfiguration(dte.ActiveDocument.ProjectItem.ContainingProject),
MetadataControlResolver = metadataControlResolver
};
parser.Parse(classifier.Tokens);
// prepare the context
var items = Enumerable.Empty<SimpleRwHtmlCompletion>();
var context = GetCompletionContext();
context.CurrentTokenIndex = classifier.Tokens.IndexOf(currentToken);
context.CurrentNode = parser.Root.FindNodeByPosition(session.TextView.Caret.Position.BufferPosition.Position - 1);

var combineWithHtmlCompletions = false;

TriggerPoint triggerPoint = TriggerPoint.None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
namespace Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions
{
[Export(typeof(ICompletionSourceProvider))]
[Export(typeof(RwHtmlCompletionSourceProvider))]
[Name("Redwood IntelliSense")]
[ContentType(RwHtmlContentTypeDefinitions.RwHtmlContentType)]
public class RwHtmlCompletionSourceProvider : ICompletionSourceProvider
Expand Down Expand Up @@ -49,25 +50,28 @@ public class RwHtmlCompletionSourceProvider : ICompletionSourceProvider
public RwHtmlParser Parser { get; private set; }

public RwHtmlClassifier Classifier { get; private set; }


public ICompletionSource TryCreateCompletionSource(ITextBuffer textBuffer)
{
var classifierProvider = new RwHtmlClassifierProvider()
return textBuffer.Properties.GetOrCreateSingletonProperty(() =>
{
Registry = Registry
};
var classifierProvider = new RwHtmlClassifierProvider()
{
Registry = Registry
};
ConfigurationProvider = new RedwoodConfigurationProvider();
MetadataControlResolver = new MetadataControlResolver();
ConfigurationProvider = new RedwoodConfigurationProvider();
MetadataControlResolver = new MetadataControlResolver();
WatchWorkspaceChanges();
WatchWorkspaceChanges();
Parser = new RwHtmlParser();
Classifier = (RwHtmlClassifier)classifierProvider.GetClassifier(textBuffer);
Parser = new RwHtmlParser();
Classifier = (RwHtmlClassifier)classifierProvider.GetClassifier(textBuffer);
return new RwHtmlCompletionSource(this, Parser, Classifier, textBuffer,
Workspace, GlyphService, CompletionHelper.DTE, ConfigurationProvider, MetadataControlResolver);
return new RwHtmlCompletionSource(this, Parser, Classifier, textBuffer,
Workspace, GlyphService, CompletionHelper.DTE, ConfigurationProvider, MetadataControlResolver);
});
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Redwood.Framework.Parser.RwHtml.Tokenizer;
using Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtml;
using Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions.RwHtml.Base;
using System.Text;

namespace Redwood.VS2015Extension.RwHtmlEditorExtensions.Completions
{
Expand Down Expand Up @@ -46,20 +47,29 @@ protected override bool Execute(uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, Int
{
// parse the content
var tokenizer = new RwHtmlTokenizer();
tokenizer.Tokenize(new StringReader(TextView.TextSnapshot.GetText()));
var text = TextView.TextSnapshot.GetText();
tokenizer.Tokenize(new StringReader(text));
var parser = new RwHtmlParser();
var node = parser.Parse(tokenizer.Tokens);

var metadataControlResolver = TextView.Properties.GetProperty<RwHtmlCompletionSourceProvider>(null).MetadataControlResolver;

// prepare the metadata control resolver
var completionSource = TextView.TextBuffer.Properties.GetProperty<RwHtmlCompletionSource>(typeof(RwHtmlCompletionSource));
var metadataControlResolver = completionSource.MetadataControlResolver;
metadataControlResolver.ReloadAllControls(completionSource.GetCompletionContext());

try
{
CompletionHelper.DTE.UndoContext.Open("Format RWHTML document");
var edit = TextView.TextBuffer.CreateEdit(EditOptions.None, null, null);

// fix the casing of all elements
var editText = new StringBuilder(text);
foreach (var element in node.EnumerateNodes().OfType<RwHtmlElementNode>())
{
FixElement(metadataControlResolver, TextView.TextBuffer, element);
FixElement(editText, metadataControlResolver, TextView.TextBuffer, element);
}
edit.Replace(0, editText.Length, editText.ToString());
edit.Apply();
}
finally
{
Expand All @@ -70,46 +80,50 @@ protected override bool Execute(uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, Int
return true;
}

private void FixElement(MetadataControlResolver metadataControlResolver, ITextBuffer textBuffer, RwHtmlElementNode element)
private void FixElement(StringBuilder edit, MetadataControlResolver metadataControlResolver, ITextBuffer textBuffer, RwHtmlElementNode element)
{
// fix element name
var metadata = metadataControlResolver.GetMetadata(element.FullTagName);
if (metadata != null)
{
// we have found the metadata for the control
if (metadata.Name != element.FullTagName)
if (metadata.FullTagName != element.FullTagName)
{
// the used name differs from the correct, fix the tag name
var edit = textBuffer.CreateEdit();
edit.Replace(element.TagPrefixToken.StartPosition, element.TagPrefixToken.Length, metadata.TagPrefix);
edit.Replace(element.TagNameToken.StartPosition, element.TagNameToken.Length, metadata.TagName);
edit.Apply();
edit.SetRange(element.TagPrefixToken.StartPosition, element.TagPrefixToken.Length, metadata.TagPrefix);
edit.SetRange(element.TagNameToken.StartPosition, element.TagNameToken.Length, metadata.TagName);

if (element.CorrespondingEndTag != null)
{
edit.SetRange(element.CorrespondingEndTag.TagPrefixToken.StartPosition, element.CorrespondingEndTag.TagPrefixToken.Length, metadata.TagPrefix);
edit.SetRange(element.CorrespondingEndTag.TagNameToken.StartPosition, element.CorrespondingEndTag.TagNameToken.Length, metadata.TagName);
}
}
}

// fix attribute names
foreach (var attribute in element.Attributes)
{
var property = metadata.GetProperty(attribute.AttributeName);
if (property != null && property.Name != attribute.AttributeName)
// fix attribute names
foreach (var attribute in element.Attributes)
{
// the used name differs from the correct, fix the tag name
var edit = textBuffer.CreateEdit();
edit.Replace(attribute.AttributeNameToken.StartPosition, attribute.AttributeNameToken.Length, property.Name);
edit.Apply();
var property = metadata.GetProperty(attribute.AttributeName);
if (property != null && property.Name != attribute.AttributeName)
{
// the used name differs from the correct, fix the tag name
edit.SetRange(attribute.AttributeNameToken.StartPosition, attribute.AttributeNameToken.Length, property.Name);
}
}
}

// fix property elements
foreach (var child in element.Content.OfType<RwHtmlElementNode>())
{
var property = metadata.GetProperty(child.FullTagName);
if (property != null && property.IsElement && property.Name != child.FullTagName)
// fix property elements
foreach (var child in element.Content.OfType<RwHtmlElementNode>())
{
// the used name differs from the correct, fix the tag name
var edit = textBuffer.CreateEdit();
edit.Replace(element.TagNameToken.StartPosition, element.TagNameToken.Length, property.Name);
edit.Apply();
var property = metadata.GetProperty(child.FullTagName);
if (property != null && property.IsElement && property.Name != child.FullTagName)
{
// the used name differs from the correct, fix the tag name
edit.SetRange(child.TagNameToken.StartPosition, child.TagNameToken.Length, property.Name);
if (child.CorrespondingEndTag != null)
{
edit.SetRange(child.CorrespondingEndTag.TagNameToken.StartPosition, child.CorrespondingEndTag.TagNameToken.Length, property.Name);
}
}
}
}
}
Expand Down

0 comments on commit fda492d

Please sign in to comment.