Skip to content

Commit

Permalink
Fixes #1003 MissingMethodException thrown on Django solution load
Browse files Browse the repository at this point in the history
Updates Django's completions and classifier to work with the public API changes made in VS 2015 U1.
  • Loading branch information
zooba committed Jan 13, 2016
1 parent 757af9b commit 52b1769
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 30 deletions.
11 changes: 8 additions & 3 deletions Python/Product/Django/Intellisense/DjangoCompletionSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Microsoft.PythonTools.Intellisense;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Projection;

#if DEV14_OR_LATER
using Microsoft.Html.Editor.Document;
Expand All @@ -37,13 +38,17 @@ public DjangoCompletionSource(IGlyphService glyphService, DjangoAnalyzer analyze
}

public override void AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets) {
var doc = HtmlEditorDocument.FromTextBuffer(_buffer);
var doc = TemplateClassifier.HtmlEditorDocumentFromTextBuffer(_buffer);
if (doc == null) {
return;
}
doc.HtmlEditorTree.EnsureTreeReady();
var tree = doc.HtmlEditorTree;
if (tree == null) {
return;
}
tree.EnsureTreeReady();

var primarySnapshot = doc.PrimaryView.TextSnapshot;
var primarySnapshot = tree.TextSnapshot;
var nullableTriggerPoint = session.GetTriggerPoint(primarySnapshot);
if (!nullableTriggerPoint.HasValue) {
return;
Expand Down
84 changes: 58 additions & 26 deletions Python/Product/Django/TemplateParsing/TemplateClassifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,28 @@ public TemplateClassifier(TemplateClassifierProviderBase provider, ITextBuffer t

public override event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;

internal static HtmlEditorDocument HtmlEditorDocumentFromTextBuffer(ITextBuffer buffer) {
var doc = HtmlEditorDocument.FromTextBuffer(buffer);
#if DEV14_OR_LATER
if (doc == null) {
var projBuffer = buffer as IProjectionBuffer;
if (projBuffer != null) {
foreach (var b in projBuffer.SourceBuffers) {
if (b.ContentType.IsOfType(TemplateHtmlContentType.ContentTypeName) &&
(doc = HtmlEditorDocument.TryFromTextBuffer(b)) != null) {
return doc;
}
}
}
}
#endif
return doc;
}

public override IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span) {
var spans = new List<ClassificationSpan>();

var htmlDoc = HtmlEditorDocument.TryFromTextBuffer(span.Snapshot.TextBuffer);
var htmlDoc = HtmlEditorDocumentFromTextBuffer(span.Snapshot.TextBuffer);
if (htmlDoc == null) {
return spans;
}
Expand All @@ -64,35 +82,49 @@ public TemplateClassifier(TemplateClassifierProviderBase provider, ITextBuffer t
return spans;
}

var projSnapshot = _htmlDoc.PrimaryView.TextSnapshot as IProjectionSnapshot;
if (projSnapshot == null) {
return spans;
}

var primarySpans = projSnapshot.MapFromSourceSnapshot(span);
foreach (var primarySpan in primarySpans) {
var index = _htmlDoc.HtmlEditorTree.ArtifactCollection.GetItemContaining(primarySpan.Start);
if (index < 0) {
continue;
}

var artifact = _htmlDoc.HtmlEditorTree.ArtifactCollection[index] as TemplateArtifact;
if (artifact == null) {
continue;
// The provided span may be in a projection snapshot, so we need to
// map back to the source snapshot to find the correct
// classification. If projSnapshot is null, we are already in the
// correct snapshot.
var projSnapshot = span.Snapshot as IProjectionSnapshot;
var sourceSnapshot = span.Snapshot;

var sourceStartIndex = span.Start.Position;
if (projSnapshot != null) {
var pt = projSnapshot.MapToSourceSnapshot(sourceStartIndex);
sourceStartIndex = pt.Position;
sourceSnapshot = pt.Snapshot;
if (HtmlEditorDocument.TryFromTextBuffer(sourceSnapshot.TextBuffer) != _htmlDoc) {
return spans;
}
}

var artifactStart = projSnapshot.MapToSourceSnapshot(artifact.InnerRange.Start);
if (artifactStart.Snapshot != span.Snapshot) {
continue;
}
var index = _htmlDoc.HtmlEditorTree.ArtifactCollection.GetItemContaining(sourceStartIndex);
if (index < 0) {
return spans;
}

var artifactText = _htmlDoc.HtmlEditorTree.ParseTree.Text.GetText(artifact.InnerRange);
artifact.Parse(artifactText);
var artifact = _htmlDoc.HtmlEditorTree.ArtifactCollection[index] as TemplateArtifact;
if (artifact == null) {
return spans;
}

var classifications = artifact.GetClassifications();
foreach (var classification in classifications) {
var classificationSpan = ToClassificationSpan(classification, span.Snapshot, artifactStart.Position);
spans.Add(classificationSpan);
int artifactStart = artifact.InnerRange.Start;
var artifactText = _htmlDoc.HtmlEditorTree.ParseTree.Text.GetText(artifact.InnerRange);
artifact.Parse(artifactText);

var classifications = artifact.GetClassifications();
foreach (var classification in classifications) {
var cls = GetClassification(classification.Classification);
int clsStart = artifactStart + classification.Span.Start;
int clsLen = Math.Min(sourceSnapshot.Length - clsStart, classification.Span.Length);
var clsSpan = new SnapshotSpan(sourceSnapshot, clsStart, clsLen);
if (projSnapshot != null) {
foreach (var sp in projSnapshot.MapFromSourceSnapshot(clsSpan)) {
spans.Add(new ClassificationSpan(new SnapshotSpan(span.Snapshot, sp), cls));
}
} else {
spans.Add(new ClassificationSpan(clsSpan, cls));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ internal abstract class TemplateClassifierBase : IClassifier {
);
}

private IClassificationType GetClassification(Classification classification) {
protected IClassificationType GetClassification(Classification classification) {
switch (classification) {
case Classification.None: return _classifierProvider._classType;
case Classification.Keyword: return _classifierProvider._keywordType;
Expand Down

0 comments on commit 52b1769

Please sign in to comment.