private void AddClassification(TextSpan textSpan, string type) { var tuple = new ClassifiedSpan(type, textSpan); if (!_set.Contains(tuple)) { _list.Add(tuple); _set.Add(tuple); } }
private void AddClassification(TextSpan textSpan, string type) { if (textSpan.Length > 0 && textSpan.OverlapsWith(_textSpan)) { var tuple = new ClassifiedSpan(type, textSpan); if (!_set.Contains(tuple)) { _list.Add(tuple); _set.Add(tuple); } } }
public abstract ClassifiedSpan FixClassification(SourceText text, ClassifiedSpan classifiedSpan);
private void AddClassifiedSpansForPreviousTree <TClassificationService>( IClassificationDelegationService <TClassificationService> delegationService, TClassificationService classificationService, SnapshotSpan span, ITextSnapshot lastSnapshot, Document lastDocument, List <ClassifiedSpan> classifiedSpans) { // Slightly more complicated case. They're asking for the classifications for a // different snapshot than what we have a parse tree for. So we first translate the span // that they're asking for so that is maps onto the tree that we have spans for. We then // get the classifications from that tree. We then take the results and translate them // back to the snapshot they want. Finally, as some of the classifications may have // changed, we check for some common cases and touch them up manually so that things // look right for the user. // Note the handling of SpanTrackingModes here: We do EdgeExclusive while mapping back , // and EdgeInclusive mapping forward. What I've convinced myself is that EdgeExclusive // is best when mapping back over a deletion, so that we don't end up classifying all of // the deleted code. In most addition/modification cases, there will be overlap with // existing spans, and so we'll end up classifying well. In the worst case, there is a // large addition that doesn't exist when we map back, and so we don't have any // classifications for it. That's probably okay, because: // 1. If it's that large, it's likely that in reality there are multiple classification // spans within it. // 2.We'll eventually call ClassificationsChanged and re-classify that region anyway. // When mapping back forward, we use EdgeInclusive so that in the common typing cases we // don't end up with half a token colored differently than the other half. // See bugs like http://vstfdevdiv:8080/web/wi.aspx?id=6176 for an example of what can // happen when this goes wrong. // 1) translate the requested span onto the right span for the snapshot that corresponds // to the syntax tree. var translatedSpan = span.TranslateTo(lastSnapshot, SpanTrackingMode.EdgeExclusive); if (translatedSpan.IsEmpty) { // well, there is no information we can get from previous tree, use lexer to // classify given span. soon we will re-classify the region. AddClassifiedSpansForTokens(delegationService, classificationService, span, classifiedSpans); return; } var tempList = ClassificationUtilities.GetOrCreateClassifiedSpanList(); AddClassifiedSpansForCurrentTree( delegationService, classificationService, translatedSpan, lastDocument, tempList); var currentSnapshot = span.Snapshot; var currentText = currentSnapshot.AsText(); foreach (var lastClassifiedSpan in tempList) { // 2) Translate those classifications forward so that they correspond to the true // requested snapshot. var lastSnapshotSpan = lastClassifiedSpan.TextSpan.ToSnapshotSpan(lastSnapshot); var currentSnapshotSpan = lastSnapshotSpan.TranslateTo(currentSnapshot, SpanTrackingMode.EdgeInclusive); var currentClassifiedSpan = new ClassifiedSpan(lastClassifiedSpan.ClassificationType, currentSnapshotSpan.Span.ToTextSpan()); // 3) The classifications may be incorrect due to changes in the text. For example, // if "clss" becomes "class", then we want to changes the classification from // 'identifier' to 'keyword'. currentClassifiedSpan = delegationService.AdjustStaleClassification( classificationService, currentText, currentClassifiedSpan); classifiedSpans.Add(currentClassifiedSpan); } ClassificationUtilities.ReturnClassifiedSpanList(tempList); }
public override ClassifiedSpan AdjustStaleClassification(SourceText text, ClassifiedSpan classifiedSpan) => ClassificationHelpers.AdjustStaleClassification(text, classifiedSpan);
public ClassifiedSpan AdjustStaleClassification(SourceText text, ClassifiedSpan classifiedSpan) { return(_delegatee.AdjustStaleClassification(text, classifiedSpan)); }
public static TagSpan <IClassificationTag> Convert(IClassificationTypeMap typeMap, ITextSnapshot snapshot, ClassifiedSpan classifiedSpan) { return(new TagSpan <IClassificationTag>( classifiedSpan.TextSpan.ToSnapshotSpan(snapshot), new ClassificationTag(typeMap.GetClassificationType(classifiedSpan.ClassificationType)))); }
private static string GetText(ClassifiedSpan tuple) { return("(" + tuple.TextSpan + ", " + tuple.ClassificationType + ")"); }
private bool TryClassifySymbol( NameSyntax name, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken, out ClassifiedSpan classifiedSpan) { if (symbol != null) { // see through using aliases if (symbol.Kind == SymbolKind.Alias) { symbol = (symbol as IAliasSymbol).Target; } else if (symbol.IsConstructor() && name.IsParentKind(SyntaxKind.Attribute)) { symbol = symbol.ContainingType; } } if (name.IsVar && IsInVarContext(name)) { var alias = semanticModel.GetAliasInfo(name, cancellationToken); if (alias == null || alias.Name != "var") { if (!IsSymbolCalledVar(symbol)) { // We bound to a symbol. If we bound to a symbol called "var" then we want to // classify this appropriately as a type. Otherwise, we want to classify this as // a keyword. classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword); return true; } } } if (symbol != null) { // Use .Equals since we can't rely on object identity for constructed types. if (symbol is ITypeSymbol) { var classification = GetClassificationForType((ITypeSymbol)symbol); if (classification != null) { var token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, classification); return true; } } } classifiedSpan = default(ClassifiedSpan); return false; }
public ITagSpan <IClassificationTag> GetTagSpan(SyntaxNode node, ClassifiedSpan span, ITextSnapshot snapshot, ISymbol symbol, Dictionary <string, IClassificationType> classificationTypeDictionary) { if (symbol?.Kind == SymbolKind.Namespace) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Namespace, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } if (symbol?.Kind == SymbolKind.Parameter) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Parameter, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } if (symbol?.Kind == SymbolKind.Property) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Property, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } if (symbol?.Kind == SymbolKind.Local) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.LocalVariable, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } if (node.IsCSharpConstructorSyntaxKind()) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Constructor, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } if (symbol?.Kind == SymbolKind.Method) { if (symbol.IsExtensionMethod()) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.ExtensionMethod, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } if (symbol.IsStatic) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.StaticMethod, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } else { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Method, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } } if (symbol?.Kind == SymbolKind.Field) { if (symbol.ContainingType.TypeKind == TypeKind.Enum) { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.EnumMember, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } else { classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Field, out IClassificationType classificationValue); return(new TagSpan <IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue))); } } //if (symbol?.Kind == SymbolKind.NamedType) //{ // if (node.IsCSharpAttributeSyntaxKind()) // { // classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Attribute, out IClassificationType classificationValue); // return new TagSpan<IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue)); // } //} return(null); }
IClassificationType GetClassificationType2(ClassifiedSpan cspan) { var symRes = GetSymbolResult(cspan.TextSpan); if (symRes.Type != null) return symRes.Type; var symbol = symRes.Symbol; if (symbol == null) return null; the_switch: switch (symbol.Kind) { case SymbolKind.Alias: return roslynClassificationTypes.Namespace; case SymbolKind.ArrayType: case SymbolKind.Assembly: case SymbolKind.DynamicType: case SymbolKind.ErrorType: break; case SymbolKind.Event: var evtSym = (IEventSymbol)symbol; return evtSym.IsStatic ? roslynClassificationTypes.StaticEvent : roslynClassificationTypes.InstanceEvent; case SymbolKind.Field: var fldSym = (IFieldSymbol)symbol; if (fldSym.ContainingType?.IsScriptClass == true) return roslynClassificationTypes.Local; if (fldSym.ContainingType?.TypeKind == TypeKind.Enum) return roslynClassificationTypes.EnumField; if (fldSym.IsConst) return roslynClassificationTypes.LiteralField; if (fldSym.IsStatic) return roslynClassificationTypes.StaticField; return roslynClassificationTypes.InstanceField; case SymbolKind.Label: return roslynClassificationTypes.Label; case SymbolKind.Local: return roslynClassificationTypes.Local; case SymbolKind.Method: var methSym = (IMethodSymbol)symbol; switch (methSym.MethodKind) { case MethodKind.Constructor: case MethodKind.Destructor: case MethodKind.StaticConstructor: symbol = methSym.ContainingType; goto the_switch; case MethodKind.Ordinary: case MethodKind.DelegateInvoke: case MethodKind.ExplicitInterfaceImplementation: case MethodKind.AnonymousFunction: case MethodKind.Conversion: case MethodKind.EventAdd: case MethodKind.EventRaise: case MethodKind.EventRemove: case MethodKind.UserDefinedOperator: case MethodKind.PropertyGet: case MethodKind.PropertySet: case MethodKind.BuiltinOperator: case MethodKind.DeclareMethod: case MethodKind.LocalFunction: default: if (methSym.IsExtensionMethod) return roslynClassificationTypes.ExtensionMethod; if (methSym.IsStatic) return roslynClassificationTypes.StaticMethod; return roslynClassificationTypes.InstanceMethod; case MethodKind.ReducedExtension: return roslynClassificationTypes.ExtensionMethod; } case SymbolKind.NetModule: break; case SymbolKind.NamedType: var nts = (INamedTypeSymbol)symbol; switch (nts.TypeKind) { case TypeKind.Class: if (nts.IsStatic) return roslynClassificationTypes.StaticType; if (nts.IsSealed) return roslynClassificationTypes.SealedType; return roslynClassificationTypes.Type; case TypeKind.Delegate: return roslynClassificationTypes.Delegate; case TypeKind.Enum: return roslynClassificationTypes.Enum; case TypeKind.Interface: return roslynClassificationTypes.Interface; case TypeKind.Struct: return roslynClassificationTypes.ValueType; case TypeKind.TypeParameter: if ((symbol as ITypeParameterSymbol)?.DeclaringMethod != null) return roslynClassificationTypes.MethodGenericParameter; return roslynClassificationTypes.TypeGenericParameter; case TypeKind.Unknown: case TypeKind.Array: case TypeKind.Dynamic: case TypeKind.Error: case TypeKind.Module: case TypeKind.Pointer: case TypeKind.Submission: default: break; } break; case SymbolKind.Namespace: return roslynClassificationTypes.Namespace; case SymbolKind.Parameter: return roslynClassificationTypes.Parameter; case SymbolKind.PointerType: break; case SymbolKind.Property: var propSym = (IPropertySymbol)symbol; return propSym.IsStatic ? roslynClassificationTypes.StaticProperty : roslynClassificationTypes.InstanceProperty; case SymbolKind.RangeVariable: return roslynClassificationTypes.Local; case SymbolKind.TypeParameter: return (symbol as ITypeParameterSymbol)?.DeclaringMethod != null ? roslynClassificationTypes.MethodGenericParameter : roslynClassificationTypes.TypeGenericParameter; case SymbolKind.Preprocessing: break; default: Debug.WriteLine($"Unknown SymbolKind: {symbol.Kind}"); break; } return null; }
public Range(ClassifiedSpan classifiedSpan, string text) { ClassifiedSpan = classifiedSpan; Text = text; }
public Range(string classification, TextSpan textSpan, string text) { ClassifiedSpan = new ClassifiedSpan(classification, textSpan); Text = text; }
public Range(ClassifiedSpan classifiedSpan, string text) { this.ClassifiedSpan = classifiedSpan; this.Text = text; }
public override ClassifiedSpan FixClassification(SourceText rawText, ClassifiedSpan classifiedSpan) { return(ClassificationHelpers.AdjustStaleClassification(rawText, classifiedSpan)); }
public IEnumerable <ITagSpan <ClassificationTag> > GetTags(NormalizedSnapshotSpanCollection snapshots) { try { if (snapshots.Count >= 1) { SnapshotSpan snapspan = snapshots[0]; ClassifierContext ctx = ClassifierContext.GetContext(ref this.CachedContext, snapspan); if (ctx != null) { List <ClassifiedSpan> ls = ctx.GetClassifiedSpans(snapspan); for (int idx = 0; idx < ls.Count; idx++) { ClassifiedSpan clsspan = ls[idx]; TextSpan txt = clsspan.TextSpan; switch (clsspan.ClassificationType) { case "string": ClassifyString(ctx, txt); break; case "method name": ClassifyIdentifier(ctx, txt); break; case "property name": ClassifyIdentifier(ctx, txt); break; case "identifier": ClassifyIdentifier(ctx, txt); break; case "event name": ctx.AssociateTagWithText(Tags.IdentifierEvent, txt); break; case "field name": ctx.AssociateTagWithText(Tags.IdentifierField, txt); break; case "constant name": ctx.AssociateTagWithText(Tags.IdentifierConst, txt); break; case "local name": ctx.AssociateTagWithText(Tags.Variable, txt); break; case "parameter name": ctx.AssociateTagWithText(Tags.Param, txt); break; case "enum member name": ctx.AssociateTagWithText(Tags.EnumMember, txt); break; case "extension method name": ctx.AssociateTagWithText(Tags.MethodExtension, txt); break; case "keyword": ctx.AssociateTagWithText(Tags.SyntaxKeyword, txt); break; case "operator": ClassifyOperator(ctx, txt); break; case "number": ctx.AssociateTagWithText(Tags.SyntaxNumber, txt); break; case "punctuation": ctx.AssociateTagWithText(Tags.SyntaxPunctuation, txt); break; case "comment": ctx.AssociateTagWithText(Tags.SyntaxComment, txt); break; case "class name": ctx.AssociateTagWithText(Tags.TypeClass, txt); break; case "module name": ctx.AssociateTagWithText(Tags.TypeModule, txt); break; case "struct name": ctx.AssociateTagWithText(Tags.TypeStructure, txt); break; case "interface name": ctx.AssociateTagWithText(Tags.TypeInterface, txt); break; case "type parameter name": ctx.AssociateTagWithText(Tags.TypeGeneric, txt); break; case "delegate name": ctx.AssociateTagWithText(Tags.TypeDelegate, txt); break; case "enum name": ctx.AssociateTagWithText(Tags.Enum, txt); break; case "preprocessor keyword": ctx.AssociateTagWithText(Tags.Preprocessor, txt); break; case "preprocessor text": ctx.AssociateTagWithText(Tags.PreprocessorText, txt); break; case "xml doc comment": break; case "xml doc comment - text": break; case "xml doc comment - name": break; case "xml doc comment - delimiter": break; case "xml doc comment - attribute name": break; case "xml doc comment - attribute value": break; case "xml doc comment - attribute quotes": break; case "xml doc comment - entity reference": break; case "excluded code": break; default: //System.Diagnostics.Debugger.Break(); break; } } return(ctx.Classified); } } } catch (Exception ex) { throw new SyntaxColorizorException(inner: ex); } return(EmptyTagSpansList); }
public override ClassifiedSpan AdjustStaleClassification(SourceText text, ClassifiedSpan classifiedSpan) { return ClassificationHelpers.AdjustStaleClassification(text, classifiedSpan); }
IClassificationType GetClassificationType(ClassifiedSpan cspan) { IClassificationType classificationType; SymbolResult symRes; switch (cspan.ClassificationType) { case ClassificationTypeNames.ClassName: symRes = GetSymbolResult(cspan.TextSpan); if (symRes.Type != null) return symRes.Type; if (symRes.Symbol?.IsStatic == true) return roslynClassificationTypes.StaticType; if (symRes.Symbol?.IsSealed == true) return roslynClassificationTypes.SealedType; Debug.WriteLineIf(symRes.Symbol == null, "Couldn't get ClassName classification type"); return roslynClassificationTypes.Type; case ClassificationTypeNames.Comment: return roslynClassificationTypes.Comment; case ClassificationTypeNames.DelegateName: return roslynClassificationTypes.Delegate; case ClassificationTypeNames.EnumName: return roslynClassificationTypes.Enum; case ClassificationTypeNames.ExcludedCode: return roslynClassificationTypes.ExcludedCode; case ClassificationTypeNames.Identifier: return GetClassificationType2(cspan); case ClassificationTypeNames.InterfaceName: return roslynClassificationTypes.Interface; case ClassificationTypeNames.Keyword: return roslynClassificationTypes.Keyword; case ClassificationTypeNames.ModuleName: return roslynClassificationTypes.Module; case ClassificationTypeNames.NumericLiteral: return roslynClassificationTypes.Number; case ClassificationTypeNames.Operator: return roslynClassificationTypes.Operator; case ClassificationTypeNames.PreprocessorKeyword: return roslynClassificationTypes.PreprocessorKeyword; case ClassificationTypeNames.PreprocessorText: return roslynClassificationTypes.PreprocessorText; case ClassificationTypeNames.Punctuation: return roslynClassificationTypes.Punctuation; case ClassificationTypeNames.StringLiteral: return roslynClassificationTypes.String; case ClassificationTypeNames.StructName: return roslynClassificationTypes.ValueType; case ClassificationTypeNames.Text: return roslynClassificationTypes.Text; case ClassificationTypeNames.TypeParameterName: classificationType = GetClassificationType2(cspan); Debug.WriteLineIf(classificationType == null, "Couldn't get TypeParameterName color type"); return classificationType ?? roslynClassificationTypes.TypeGenericParameter; case ClassificationTypeNames.VerbatimStringLiteral: return roslynClassificationTypes.VerbatimString; case ClassificationTypeNames.WhiteSpace: return roslynClassificationTypes.Text; case ClassificationTypeNames.XmlDocCommentAttributeName: return roslynClassificationTypes.XmlDocCommentAttributeName; case ClassificationTypeNames.XmlDocCommentAttributeQuotes: return roslynClassificationTypes.XmlDocCommentAttributeQuotes; case ClassificationTypeNames.XmlDocCommentAttributeValue: return roslynClassificationTypes.XmlDocCommentAttributeValue; case ClassificationTypeNames.XmlDocCommentCDataSection: return roslynClassificationTypes.XmlDocCommentCDataSection; case ClassificationTypeNames.XmlDocCommentComment: return roslynClassificationTypes.XmlDocCommentComment; case ClassificationTypeNames.XmlDocCommentDelimiter: return roslynClassificationTypes.XmlDocCommentDelimiter; case ClassificationTypeNames.XmlDocCommentEntityReference: return roslynClassificationTypes.XmlDocCommentEntityReference; case ClassificationTypeNames.XmlDocCommentName: return roslynClassificationTypes.XmlDocCommentName; case ClassificationTypeNames.XmlDocCommentProcessingInstruction: return roslynClassificationTypes.XmlDocCommentProcessingInstruction; case ClassificationTypeNames.XmlDocCommentText: return roslynClassificationTypes.XmlDocCommentText; case ClassificationTypeNames.XmlLiteralAttributeName: return roslynClassificationTypes.XmlLiteralAttributeName; case ClassificationTypeNames.XmlLiteralAttributeQuotes: return roslynClassificationTypes.XmlLiteralAttributeQuotes; case ClassificationTypeNames.XmlLiteralAttributeValue: return roslynClassificationTypes.XmlLiteralAttributeValue; case ClassificationTypeNames.XmlLiteralCDataSection: return roslynClassificationTypes.XmlLiteralCDataSection; case ClassificationTypeNames.XmlLiteralComment: return roslynClassificationTypes.XmlLiteralComment; case ClassificationTypeNames.XmlLiteralDelimiter: return roslynClassificationTypes.XmlLiteralDelimiter; case ClassificationTypeNames.XmlLiteralEmbeddedExpression: return roslynClassificationTypes.XmlLiteralEmbeddedExpression; case ClassificationTypeNames.XmlLiteralEntityReference: return roslynClassificationTypes.XmlLiteralEntityReference; case ClassificationTypeNames.XmlLiteralName: return roslynClassificationTypes.XmlLiteralName; case ClassificationTypeNames.XmlLiteralProcessingInstruction: return roslynClassificationTypes.XmlLiteralProcessingInstruction; case ClassificationTypeNames.XmlLiteralText: return roslynClassificationTypes.XmlLiteralText; default: Debug.WriteLine($"Unknown ClassificationType = '{cspan.ClassificationType}'"); return null; } }
public abstract ClassifiedSpan AdjustStaleClassification(SourceText text, ClassifiedSpan classifiedSpan);
IClassificationType GetClassificationType(ClassifiedSpan cspan) { IClassificationType classificationType; SymbolResult symRes; switch (cspan.ClassificationType) { case ClassificationTypeNames.ClassName: symRes = GetSymbolResult(cspan.TextSpan); if (symRes.Type != null) { return(symRes.Type); } if (symRes.Symbol?.IsStatic == true) { return(roslynClassificationTypes.StaticType); } if (symRes.Symbol?.IsSealed == true) { return(roslynClassificationTypes.SealedType); } Debug.WriteLineIf(symRes.Symbol == null, "Couldn't get ClassName classification type"); return(roslynClassificationTypes.Type); case ClassificationTypeNames.Comment: return(roslynClassificationTypes.Comment); case ClassificationTypeNames.DelegateName: return(roslynClassificationTypes.Delegate); case ClassificationTypeNames.EnumName: return(roslynClassificationTypes.Enum); case ClassificationTypeNames.ExcludedCode: return(roslynClassificationTypes.ExcludedCode); case ClassificationTypeNames.Identifier: return(GetClassificationType2(cspan)); case ClassificationTypeNames.InterfaceName: return(roslynClassificationTypes.Interface); case ClassificationTypeNames.Keyword: return(roslynClassificationTypes.Keyword); case ClassificationTypeNames.ModuleName: return(roslynClassificationTypes.Module); case ClassificationTypeNames.NumericLiteral: return(roslynClassificationTypes.Number); case ClassificationTypeNames.Operator: return(roslynClassificationTypes.Operator); case ClassificationTypeNames.PreprocessorKeyword: return(roslynClassificationTypes.PreprocessorKeyword); case ClassificationTypeNames.PreprocessorText: return(roslynClassificationTypes.PreprocessorText); case ClassificationTypeNames.Punctuation: return(roslynClassificationTypes.Punctuation); case ClassificationTypeNames.StringLiteral: return(roslynClassificationTypes.String); case ClassificationTypeNames.StructName: return(roslynClassificationTypes.ValueType); case ClassificationTypeNames.Text: return(roslynClassificationTypes.Text); case ClassificationTypeNames.TypeParameterName: classificationType = GetClassificationType2(cspan); Debug.WriteLineIf(classificationType == null, "Couldn't get TypeParameterName color type"); return(classificationType ?? roslynClassificationTypes.TypeGenericParameter); case ClassificationTypeNames.VerbatimStringLiteral: return(roslynClassificationTypes.VerbatimString); case ClassificationTypeNames.WhiteSpace: return(roslynClassificationTypes.Text); case ClassificationTypeNames.XmlDocCommentAttributeName: return(roslynClassificationTypes.XmlDocCommentAttributeName); case ClassificationTypeNames.XmlDocCommentAttributeQuotes: return(roslynClassificationTypes.XmlDocCommentAttributeQuotes); case ClassificationTypeNames.XmlDocCommentAttributeValue: return(roslynClassificationTypes.XmlDocCommentAttributeValue); case ClassificationTypeNames.XmlDocCommentCDataSection: return(roslynClassificationTypes.XmlDocCommentCDataSection); case ClassificationTypeNames.XmlDocCommentComment: return(roslynClassificationTypes.XmlDocCommentComment); case ClassificationTypeNames.XmlDocCommentDelimiter: return(roslynClassificationTypes.XmlDocCommentDelimiter); case ClassificationTypeNames.XmlDocCommentEntityReference: return(roslynClassificationTypes.XmlDocCommentEntityReference); case ClassificationTypeNames.XmlDocCommentName: return(roslynClassificationTypes.XmlDocCommentName); case ClassificationTypeNames.XmlDocCommentProcessingInstruction: return(roslynClassificationTypes.XmlDocCommentProcessingInstruction); case ClassificationTypeNames.XmlDocCommentText: return(roslynClassificationTypes.XmlDocCommentText); case ClassificationTypeNames.XmlLiteralAttributeName: return(roslynClassificationTypes.XmlLiteralAttributeName); case ClassificationTypeNames.XmlLiteralAttributeQuotes: return(roslynClassificationTypes.XmlLiteralAttributeQuotes); case ClassificationTypeNames.XmlLiteralAttributeValue: return(roslynClassificationTypes.XmlLiteralAttributeValue); case ClassificationTypeNames.XmlLiteralCDataSection: return(roslynClassificationTypes.XmlLiteralCDataSection); case ClassificationTypeNames.XmlLiteralComment: return(roslynClassificationTypes.XmlLiteralComment); case ClassificationTypeNames.XmlLiteralDelimiter: return(roslynClassificationTypes.XmlLiteralDelimiter); case ClassificationTypeNames.XmlLiteralEmbeddedExpression: return(roslynClassificationTypes.XmlLiteralEmbeddedExpression); case ClassificationTypeNames.XmlLiteralEntityReference: return(roslynClassificationTypes.XmlLiteralEntityReference); case ClassificationTypeNames.XmlLiteralName: return(roslynClassificationTypes.XmlLiteralName); case ClassificationTypeNames.XmlLiteralProcessingInstruction: return(roslynClassificationTypes.XmlLiteralProcessingInstruction); case ClassificationTypeNames.XmlLiteralText: return(roslynClassificationTypes.XmlLiteralText); default: Debug.WriteLine($"Unknown ClassificationType = '{cspan.ClassificationType}'"); return(null); } }
private static bool IsOutsideLine(ClassifiedSpan classifiedSpan, IDocumentLine documentLine) { return classifiedSpan.TextSpan.Start < documentLine.Offset || classifiedSpan.TextSpan.Start > documentLine.EndOffset || classifiedSpan.TextSpan.End > documentLine.EndOffset; }
private bool TryClassifySymbol( NameSyntax name, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken, out ClassifiedSpan classifiedSpan) { // Classify a reference to an attribute constructor in an attribute location // as if we were classifying the attribute type itself. if (symbol.IsConstructor() && name.IsParentKind(SyntaxKind.Attribute)) { symbol = symbol.ContainingType; } if (name.IsVar && IsInVarContext(name)) { var alias = semanticModel.GetAliasInfo(name, cancellationToken); if (alias == null || alias.Name != "var") { if (!IsSymbolWithName(symbol, "var")) { // We bound to a symbol. If we bound to a symbol called "var" then we want to // classify this appropriately as a type. Otherwise, we want to classify this as // a keyword. classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword); return(true); } } } if (name.IsUnmanaged && name.Parent.IsKind(SyntaxKind.TypeConstraint)) { var alias = semanticModel.GetAliasInfo(name, cancellationToken); if (alias == null || alias.Name != "unmanaged") { if (!IsSymbolWithName(symbol, "unmanaged")) { // We bound to a symbol. If we bound to a symbol called "unmanaged" then we want to // classify this appropriately as a type. Otherwise, we want to classify this as // a keyword. classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword); return(true); } } } // Use .Equals since we can't rely on object identity for constructed types. SyntaxToken token; switch (symbol) { case ITypeSymbol typeSymbol: var classification = GetClassificationForType(typeSymbol); if (classification != null) { token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, classification); return(true); } break; case IFieldSymbol fieldSymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForField(fieldSymbol)); return(true); case IMethodSymbol methodSymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForMethod(methodSymbol)); return(true); case IPropertySymbol propertySymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.PropertyName); return(true); case IEventSymbol eventSymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.EventName); return(true); case IParameterSymbol parameterSymbol: if (parameterSymbol.IsImplicitlyDeclared && parameterSymbol.Name == "value") { break; } token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.ParameterName); return(true); case ILocalSymbol localSymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForLocal(localSymbol)); return(true); } classifiedSpan = default; return(false); }
private static string GetText(ClassifiedSpan tuple) { return "(" + tuple.TextSpan + ", " + tuple.ClassificationType + ")"; }
private static string GetText(ClassifiedSpan tuple) => $"({tuple.TextSpan}, {tuple.ClassificationType})";
public ClassifiedSpan FixClassification(SourceText text, ClassifiedSpan classifiedSpan) => _originalService.FixClassification(text, classifiedSpan);
public ClassifiedSpan AdjustStaleClassification(SourceText text, ClassifiedSpan classifiedSpan) { return(_originalService.AdjustStaleClassification(text, classifiedSpan)); }
internal string GetText(ClassifiedSpan tuple) { return("(" + tuple.TextSpan + ", " + tuple.ClassificationType + ")"); }
private static bool TryClassifySymbol( NameSyntax name, [NotNullWhen(returnValue: true)] ISymbol?symbol, SemanticModel semanticModel, CancellationToken cancellationToken, out ClassifiedSpan classifiedSpan) { // For Namespace parts, we want don't want to classify the QualifiedNameSyntax // nodes, we instead wait for the each IdentifierNameSyntax node to avoid // creating overlapping ClassifiedSpans. if (symbol is INamespaceSymbol namespaceSymbol && name is IdentifierNameSyntax identifierNameSyntax) { // Do not classify the global:: namespace. It is already syntactically classified as a keyword. var isGlobalNamespace = namespaceSymbol.IsGlobalNamespace && identifierNameSyntax.Identifier.IsKind(SyntaxKind.GlobalKeyword); if (isGlobalNamespace) { classifiedSpan = default; return(false); } // Classifies both extern aliases and namespaces. classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.NamespaceName); return(true); } if (name.IsVar && IsInVarContext(name)) { var alias = semanticModel.GetAliasInfo(name, cancellationToken); if (alias == null || alias.Name != "var") { if (!IsSymbolWithName(symbol, "var")) { // We bound to a symbol. If we bound to a symbol called "var" then we want to // classify this appropriately as a type. Otherwise, we want to classify this as // a keyword. classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword); return(true); } } } if (name.IsNint || name.IsNuint) { if (symbol is ITypeSymbol type && type.IsNativeIntegerType) { classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword); return(true); } } if ((name.IsUnmanaged || name.IsNotNull) && name.Parent.IsKind(SyntaxKind.TypeConstraint)) { var nameToCheck = name.IsUnmanaged ? "unmanaged" : "notnull"; var alias = semanticModel.GetAliasInfo(name, cancellationToken); if (alias == null || alias.Name != nameToCheck) { if (!IsSymbolWithName(symbol, nameToCheck)) { // We bound to a symbol. If we bound to a symbol called "unmanaged"/"notnull" then we want to // classify this appropriately as a type. Otherwise, we want to classify this as // a keyword. classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword); return(true); } } } // Use .Equals since we can't rely on object identity for constructed types. SyntaxToken token; switch (symbol) { case ITypeSymbol typeSymbol: var classification = GetClassificationForType(typeSymbol); if (classification != null) { token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, classification); return(true); } break; case IFieldSymbol fieldSymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForField(fieldSymbol)); return(true); case IMethodSymbol methodSymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForMethod(methodSymbol)); return(true); case IPropertySymbol _: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.PropertyName); return(true); case IEventSymbol _: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.EventName); return(true); case IParameterSymbol parameterSymbol: if (parameterSymbol.IsImplicitlyDeclared && parameterSymbol.Name == "value") { break; } token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.ParameterName); return(true); case ILocalSymbol localSymbol: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForLocal(localSymbol)); return(true); case ILabelSymbol _: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.LabelName); return(true); } classifiedSpan = default; return(false); }
object GetClassificationType2(ClassifiedSpan cspan) { var symRes = GetSymbolResult(cspan.TextSpan); if (symRes.Color != null) { return(symRes.Color); } var symbol = symRes.Symbol; if (symbol == null) { return(null); } the_switch: switch (symbol.Kind) { case SymbolKind.Alias: return(roslynClassificationTypes.Namespace); case SymbolKind.ArrayType: case SymbolKind.Assembly: case SymbolKind.DynamicType: case SymbolKind.ErrorType: break; case SymbolKind.Event: var evtSym = (IEventSymbol)symbol; return(evtSym.IsStatic ? roslynClassificationTypes.StaticEvent : roslynClassificationTypes.InstanceEvent); case SymbolKind.Field: var fldSym = (IFieldSymbol)symbol; if (fldSym.ContainingType?.IsScriptClass == true) { return(roslynClassificationTypes.Local); } if (fldSym.ContainingType?.TypeKind == TypeKind.Enum) { return(roslynClassificationTypes.EnumField); } if (fldSym.IsConst) { return(roslynClassificationTypes.LiteralField); } if (fldSym.IsStatic) { return(roslynClassificationTypes.StaticField); } return(roslynClassificationTypes.InstanceField); case SymbolKind.Label: return(roslynClassificationTypes.Label); case SymbolKind.Local: return(roslynClassificationTypes.Local); case SymbolKind.Method: var methSym = (IMethodSymbol)symbol; switch (methSym.MethodKind) { case MethodKind.Constructor: case MethodKind.Destructor: case MethodKind.StaticConstructor: symbol = methSym.ContainingType; goto the_switch; case MethodKind.Ordinary: case MethodKind.DelegateInvoke: case MethodKind.ExplicitInterfaceImplementation: case MethodKind.AnonymousFunction: case MethodKind.Conversion: case MethodKind.EventAdd: case MethodKind.EventRaise: case MethodKind.EventRemove: case MethodKind.UserDefinedOperator: case MethodKind.PropertyGet: case MethodKind.PropertySet: case MethodKind.BuiltinOperator: case MethodKind.DeclareMethod: case MethodKind.LocalFunction: default: if (methSym.IsExtensionMethod) { return(roslynClassificationTypes.ExtensionMethod); } if (methSym.IsStatic) { return(roslynClassificationTypes.StaticMethod); } return(roslynClassificationTypes.InstanceMethod); case MethodKind.ReducedExtension: return(roslynClassificationTypes.ExtensionMethod); } case SymbolKind.NetModule: break; case SymbolKind.NamedType: var nts = (INamedTypeSymbol)symbol; switch (nts.TypeKind) { case TypeKind.Class: if (nts.IsStatic) { return(roslynClassificationTypes.StaticType); } if (nts.IsSealed) { return(roslynClassificationTypes.SealedType); } return(roslynClassificationTypes.Type); case TypeKind.Delegate: return(roslynClassificationTypes.Delegate); case TypeKind.Enum: return(roslynClassificationTypes.Enum); case TypeKind.Interface: return(roslynClassificationTypes.Interface); case TypeKind.Struct: return(roslynClassificationTypes.ValueType); case TypeKind.TypeParameter: if ((symbol as ITypeParameterSymbol)?.DeclaringMethod != null) { return(roslynClassificationTypes.MethodGenericParameter); } return(roslynClassificationTypes.TypeGenericParameter); case TypeKind.Unknown: case TypeKind.Array: case TypeKind.Dynamic: case TypeKind.Error: case TypeKind.Module: case TypeKind.Pointer: case TypeKind.Submission: default: break; } break; case SymbolKind.Namespace: return(roslynClassificationTypes.Namespace); case SymbolKind.Parameter: return(roslynClassificationTypes.Parameter); case SymbolKind.PointerType: break; case SymbolKind.Property: var propSym = (IPropertySymbol)symbol; return(propSym.IsStatic ? roslynClassificationTypes.StaticProperty : roslynClassificationTypes.InstanceProperty); case SymbolKind.RangeVariable: return(roslynClassificationTypes.Local); case SymbolKind.TypeParameter: return((symbol as ITypeParameterSymbol)?.DeclaringMethod != null ? roslynClassificationTypes.MethodGenericParameter : roslynClassificationTypes.TypeGenericParameter); case SymbolKind.Preprocessing: break; case SymbolKind.Discard: break; //TODO: default: Debug.WriteLine($"Unknown SymbolKind: {symbol.Kind}"); break; } return(null); }
private static SymbolSpan CreateSymbolSpan(SyntaxTree syntaxTree, SourceText text, ClassifiedSpan span, ClassificationSpan classificationSpan) { var lineSpan = syntaxTree.GetLineSpan(span.TextSpan); var symbolSpan = new SymbolSpan() { Start = classificationSpan.Start, Length = classificationSpan.Length, }; return(symbolSpan); }
private void AdjustSpans(List<ClassifiedSpan> spans, TextSpan widenedSpan) { for (var i = 0; i < spans.Count; i++) { var span = spans[i]; // Make sure the span actually intersects 'widenedSpan'. If it // does not, just put in an empty length span. It will get ignored later // when we walk through this list. var intersection = span.TextSpan.Intersection(widenedSpan); var newSpan = new ClassifiedSpan(span.ClassificationType, intersection ?? new TextSpan()); spans[i] = newSpan; } }
private void AddClassification(ClassifiedSpan classification) { if (classification.ClassificationType != null) { AddClassification(classification.TextSpan, classification.ClassificationType); } }
internal static ClassifiedSpan AdjustStaleClassification(SourceText rawText, ClassifiedSpan classifiedSpan) { // If we marked this as an identifier and it should now be a keyword // (or vice versa), then fix this up and return it. var classificationType = classifiedSpan.ClassificationType; // Check if the token's type has changed. Note: we don't check for "wasPPKeyword && // !isPPKeyword" here. That's because for fault tolerance any identifier will end up // being parsed as a PP keyword eventually, and if we have the check here, the text // flickers between blue and black while typing. See // http://vstfdevdiv:8080/web/wi.aspx?id=3521 for details. var wasKeyword = classificationType == ClassificationTypeNames.Keyword; var wasIdentifier = classificationType == ClassificationTypeNames.Identifier; // We only do this for identifiers/keywords. if (wasKeyword || wasIdentifier) { // Get the current text under the tag. var span = classifiedSpan.TextSpan; var text = rawText.ToString(span); // Now, try to find the token that corresponds to that text. If // we get 0 or 2+ tokens, then we can't do anything with this. // Also, if that text includes trivia, then we can't do anything. var token = SyntaxFactory.ParseToken(text); if (token.Span.Length == span.Length) { // var and dynamic are not contextual keywords. They are always identifiers // (that we classify as keywords). Because we are just parsing a token we don't // know if we're in the right context for them to be identifiers or keywords. // So, we base on decision on what they were before. i.e. if we had a keyword // before, then assume it stays a keyword if we see 'var' or 'dynamic. var isKeyword = SyntaxFacts.IsKeywordKind(token.CSharpKind()) || (wasKeyword && SyntaxFacts.GetContextualKeywordKind(text) != SyntaxKind.None) || (wasKeyword && token.ToString() == "var") || (wasKeyword && token.ToString() == "dynamic"); var isIdentifier = token.CSharpKind() == SyntaxKind.IdentifierToken; // We only do this for identifiers/keywords. if (isKeyword || isIdentifier) { if ((wasKeyword && !isKeyword) || (wasIdentifier && !isIdentifier)) { // It changed! Return the new type of tagspan. return new ClassifiedSpan( isKeyword ? ClassificationTypeNames.Keyword : ClassificationTypeNames.Identifier, span); } } } } // didn't need to do anything to this one. return classifiedSpan; }
private bool IsClassifiedAsText(ClassifiedSpan partAndSpan) { // Don't take 'text' from the semantic parts. We'll get those for the // spaces between the actual interesting semantic spans, and we don't // want them to override actual good syntax spans. return partAndSpan.ClassificationType == ClassificationTypeNames.Text; }
public string GetText(ClassifiedSpan span) { return(DocumentText.ToString(span.TextSpan)); }
public ClassifiedSpan AdjustStaleClassification(SourceText text, ClassifiedSpan classifiedSpan) => classifiedSpan;
private void Diagnostics(ClassifiedSpan classifiedSpan, SyntaxToken token, ISymbol symbol) { var tokenText = token.ToString(); if (!(symbol is INamedTypeSymbol) || classifiedSpan.ClassificationType == "t" || tokenText == "this" || tokenText == "base" || tokenText == "var") { return; } if (tokenText == "SR" || tokenText == "SR2" || tokenText == "SRID" || tokenText == "Strings" || tokenText == "Res" || tokenText == "VisualStudioVersionInfo" || tokenText == "Error" || tokenText == "Resource" || tokenText == "Resources" || tokenText == "AssemblyRef" || tokenText == "ProjectResources") { return; } var symbolDisplayString = SymbolIdService.GetDisplayString(symbol); if (symbolDisplayString == "System.SR" || symbolDisplayString == "System.Web.SR" || symbolDisplayString == "ThisAssembly") { return; } if (!reportedSymbolDisplayStrings.Add(symbolDisplayString)) { return; } if (reportedDiagnostics) { return; } reportedDiagnostics = true; string message = this.documentDestinationFilePath + "\r\n" + token.ToString() + ", " + token.Span.Start + "\r\n" + (classifiedSpan.ClassificationType ?? "null classification type") + "\r\n" + symbolDisplayString; var diagnostics = this.SemanticModel.GetDiagnostics().Where(d => { var diagnostic = d.GetMessage(); if (diagnostic.Contains("The type or namespace name 'Resources'") || diagnostic.Contains("must declare a body because it is not marked abstract")) { return(false); } return(true); }); if (diagnostics.Any()) { var diagnosticsMessage = string.Join("\r\n", diagnostics.Select(d => d.ToString())); message = message + "\r\n" + diagnosticsMessage; } Log.Exception("Classification: " + message); }
private HtmlElementInfo ProcessReference(Classification.Range range, ISymbol symbol, ReferenceKind kind, bool isLargeFile = false) { ClassifiedSpan classifiedSpan = range.ClassifiedSpan; var methodSymbol = symbol as IMethodSymbol; if (methodSymbol != null && methodSymbol.ReducedFrom != null) { symbol = methodSymbol.ReducedFrom; } HtmlElementInfo result = null; if (symbol.IsImplicitlyDeclared) { if (methodSymbol?.MethodKind == MethodKind.Constructor && symbol.ContainingSymbol != null) { return(ProcessReference(range, symbol.ContainingSymbol, ReferenceKind.Instantiation)); } } if (symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.Parameter || symbol.Kind == SymbolKind.TypeParameter) { if (isLargeFile) { return(null); } return(HighlightReference(symbol)); } if (methodSymbol?.MethodKind == MethodKind.Constructor && methodSymbol.ContainingType != null) { ProcessReference(range, methodSymbol.ContainingType, ReferenceKind.Instantiation); } if ((symbol.Kind == SymbolKind.Event || symbol.Kind == SymbolKind.Field || symbol.Kind == SymbolKind.Method || symbol.Kind == SymbolKind.NamedType || symbol.Kind == SymbolKind.Property) && symbol.Locations.Length >= 1) { var typeSymbol = symbol as ITypeSymbol; string symbolId = SymbolIdService.GetId(symbol); var location = symbol.Locations[0]; string destinationAssemblyName = null; if (location.IsInSource) { result = GenerateHyperlink(symbol, symbolId, location.SourceTree, out destinationAssemblyName); } else if (location.IsInMetadata && location.MetadataModule != null) { var metadataModule = location.MetadataModule; result = GenerateHyperlink(symbolId, symbol, metadataModule, isLargeFile, out destinationAssemblyName); } if (result == null) { return(result); } if (result.Attributes == null || !result.Attributes.TryGetValue("href", out string target) || !target.Contains("@")) { // only register a reference to the symbol if it's not a symbol from an external assembly. // if this links to a symbol in a different index, link target contain @. projectGenerator.AddReference( this.documentDestinationFilePath, Text, destinationAssemblyName, symbol, symbolId, classifiedSpan.TextSpan.Start, classifiedSpan.TextSpan.End, kind); } } // don't make this and var into hyperlinks in large files to save space if (isLargeFile && (range.Text == "this" || range.Text == "var")) { result = null; } return(result); }
internal string GetText(ClassifiedSpan tuple) { return "(" + tuple.TextSpan + ", " + tuple.ClassificationType + ")"; }
public ClassifiedSpan FixClassification(SourceText text, ClassifiedSpan classifiedSpan) { return(_originalService.FixClassification(text, classifiedSpan)); }
private void Diagnostics(ClassifiedSpan classifiedSpan, SyntaxToken token, ISymbol symbol) { var tokenText = token.ToString(); if (!(symbol is INamedTypeSymbol) || classifiedSpan.ClassificationType == "t" || tokenText == "this" || tokenText == "base" || tokenText == "var") { return; } if (tokenText == "SR" || tokenText == "SR2" || tokenText == "SRID" || tokenText == "Strings" || tokenText == "Res" || tokenText == "VisualStudioVersionInfo" || tokenText == "Error" || tokenText == "Resource" || tokenText == "Resources" || tokenText == "AssemblyRef" || tokenText == "ProjectResources") { return; } var symbolDisplayString = SymbolIdService.GetDisplayString(symbol); if (symbolDisplayString == "System.SR" || symbolDisplayString == "System.Web.SR" || symbolDisplayString == "ThisAssembly") { return; } if (!reportedSymbolDisplayStrings.Add(symbolDisplayString)) { return; } if (reportedDiagnostics) { return; } reportedDiagnostics = true; string message = this.documentDestinationFilePath + "\r\n" + token.ToString() + ", " + token.Span.Start + "\r\n" + (classifiedSpan.ClassificationType ?? "null classification type") + "\r\n" + symbolDisplayString; var diagnostics = this.SemanticModel.GetDiagnostics().Where(d => { var diagnostic = d.GetMessage(); if (diagnostic.Contains("The type or namespace name 'Resources'") || diagnostic.Contains("must declare a body because it is not marked abstract")) { return false; } return true; }); if (diagnostics.Any()) { var diagnosticsMessage = string.Join("\r\n", diagnostics.Select(d => d.ToString())); message = message + "\r\n" + diagnosticsMessage; } Log.Exception("Classification: " + message); }
public ClassifiedSpan AdjustStaleClassification(IClassificationService service, SourceText text, ClassifiedSpan classifiedSpan) => service.AdjustStaleClassification(text, classifiedSpan);
private void AddClassifiedSpansForPreviousTree( IEditorClassificationService classificationService, SnapshotSpan span, ITextSnapshot lastSnapshot, Document lastDocument, List<ClassifiedSpan> classifiedSpans) { // Slightly more complicated case. They're asking for the classifications for a // different snapshot than what we have a parse tree for. So we first translate the span // that they're asking for so that is maps onto the tree that we have spans for. We then // get the classifications from that tree. We then take the results and translate them // back to the snapshot they want. Finally, as some of the classifications may have // changed, we check for some common cases and touch them up manually so that things // look right for the user. // Note the handling of SpanTrackingModes here: We do EdgeExclusive while mapping back , // and EdgeInclusive mapping forward. What I've convinced myself is that EdgeExclusive // is best when mapping back over a deletion, so that we don't end up classifying all of // the deleted code. In most addition/modification cases, there will be overlap with // existing spans, and so we'll end up classifying well. In the worst case, there is a // large addition that doesn't exist when we map back, and so we don't have any // classifications for it. That's probably okay, because: // 1. If it's that large, it's likely that in reality there are multiple classification // spans within it. // 2.We'll eventually call ClassificationsChanged and re-classify that region anyway. // When mapping back forward, we use EdgeInclusive so that in the common typing cases we // don't end up with half a token colored differently than the other half. // See bugs like http://vstfdevdiv:8080/web/wi.aspx?id=6176 for an example of what can // happen when this goes wrong. // 1) translate the requested span onto the right span for the snapshot that corresponds // to the syntax tree. var translatedSpan = span.TranslateTo(lastSnapshot, SpanTrackingMode.EdgeExclusive); if (translatedSpan.IsEmpty) { // well, there is no information we can get from previous tree, use lexer to // classify given span. soon we will re-classify the region. AddClassifiedSpansForTokens(classificationService, span, classifiedSpans); return; } var tempList = ClassificationUtilities.GetOrCreateClassifiedSpanList(); AddClassifiedSpansForCurrentTree(classificationService, translatedSpan, lastDocument, tempList); var currentSnapshot = span.Snapshot; var currentText = currentSnapshot.AsText(); foreach (var lastClassifiedSpan in tempList) { // 2) Translate those classifications forward so that they correspond to the true // requested snapshot. var lastSnapshotSpan = lastClassifiedSpan.TextSpan.ToSnapshotSpan(lastSnapshot); var currentSnapshotSpan = lastSnapshotSpan.TranslateTo(currentSnapshot, SpanTrackingMode.EdgeInclusive); var currentClassifiedSpan = new ClassifiedSpan(lastClassifiedSpan.ClassificationType, currentSnapshotSpan.Span.ToTextSpan()); // 3) The classifications may be incorrect due to changes in the text. For example, // if "clss" becomes "class", then we want to changes the classification from // 'identifier' to 'keyword'. currentClassifiedSpan = classificationService.AdjustStaleClassification(currentText, currentClassifiedSpan); classifiedSpans.Add(currentClassifiedSpan); } ClassificationUtilities.ReturnClassifiedSpanList(tempList); }
private static bool IsOutsideLine(ClassifiedSpan classifiedSpan, IDocumentLine documentLine) { return(classifiedSpan.TextSpan.Start < documentLine.Offset || classifiedSpan.TextSpan.Start > documentLine.EndOffset || classifiedSpan.TextSpan.End > documentLine.EndOffset); }
private ITagSpan <IClassificationTag> GetTagSpan(ClassifiedSpan span) { var meta = _thingy.GetMeta(span.TextSpan); var s = meta.ToString(); if (meta.HasSymbol) { var symbol = meta.Symbol; switch (symbol.Kind) { case SymbolKind.Method: if (symbol is IMethodSymbol method) { if (method.IsExtensionMethod && span.ClassificationType == "extension method name") { return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.ExtensionMethd])); } if (method.MethodKind == MethodKind.Constructor && span.ClassificationType == "identifier") { switch (method.ContainingType?.TypeKind) { case TypeKind.Class when method.ContainingType.IsStatic: { return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.StaticClass])); } case TypeKind.Class: return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[ClassificationTypeNames.ClassName])); case TypeKind.Enum: return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[ClassificationTypeNames.EnumName])); case TypeKind.Struct: return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[ClassificationTypeNames.StructName])); default: return(null); } } return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.Method])); } return(null); case SymbolKind.NamedType: if (span.ClassificationType == ClassificationTypeNames.ClassName && symbol is INamedTypeSymbol type && type.TypeKind == TypeKind.Class && type.IsStatic) { return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.StaticClass])); } return(null); case SymbolKind.Field: if (symbol is IFieldSymbol field && field.IsConst || symbol.ContainingType.TypeKind == TypeKind.Enum) { return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.Constant])); } return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.Field])); case SymbolKind.Property: return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.Property])); case SymbolKind.Event: return(span.TextSpan.ToTagSpan(_thingy.Snapshot, _clasificationTypes[TagTypes.Event])); } } return(null); }