Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AssetObjectEditorProvider.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under MIT License. See LICENSE.md for details.
3 //
4 // This file is part of YamlDotNet - A .NET library for YAML.
5 // Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry
6 
7 // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 // this software and associated documentation files (the "Software"), to deal in
9 // the Software without restriction, including without limitation the rights to
10 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 // of the Software, and to permit persons to whom the Software is furnished to do
12 // so, subject to the following conditions:
13 
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 
25 using System;
26 using System.Collections.Generic;
27 using System.ComponentModel.Composition;
28 using System.Diagnostics;
29 using Microsoft.VisualStudio.Language.StandardClassification;
30 using Microsoft.VisualStudio.Text;
31 using Microsoft.VisualStudio.Text.Adornments;
32 using Microsoft.VisualStudio.Text.Classification;
34 using System.IO;
35 using System.Text.RegularExpressions;
36 using SharpYaml;
37 using SharpYaml.Schemas;
38 using SharpYaml.Tokens;
39 
40 namespace SiliconStudio.Paradox.VisualStudio.Assets
41 {
42 
43  #region Provider definition
44  /// <summary>
45  /// This class causes a classifier to be added to the set of classifiers. Since
46  /// the content type is set to "text", this classifier applies to all text files
47  /// </summary>
48  [Export(typeof(IClassifierProvider))]
49  [ContentType(Constants.ContentType)]
50  internal class AssetObjectEditorProvider : IClassifierProvider
51  {
52  /// <summary>
53  /// Import the classification registry to be used for getting a reference
54  /// to the custom classification type later.
55  /// </summary>
56  [Import]
57  internal IClassificationTypeRegistryService ClassificationRegistry = null; // Set via MEF
58 
59  public IClassifier GetClassifier(ITextBuffer buffer)
60  {
61  return buffer.Properties.GetOrCreateSingletonProperty<AssetObjectEditor>(delegate { return new AssetObjectEditor(ClassificationRegistry); });
62  }
63  }
64  #endregion //provider def
65 
66  #region Classifier
67  /// <summary>
68  /// Classifier that classifies all text as an instance of the OrinaryClassifierType
69  /// </summary>
71  {
72  private readonly CoreSchema schema;
73  private readonly IClassificationType _comment;
74  private readonly IClassificationType _anchor;
75  private readonly IClassificationType _alias;
76  private readonly IClassificationType _key;
77  private readonly IClassificationType _value;
78  private readonly IClassificationType _bool;
79  private readonly IClassificationType _number;
80  private readonly IClassificationType _string;
81  private readonly IClassificationType _tag;
82  private readonly IClassificationType _symbol;
83  private readonly IClassificationType _directive;
84  private readonly IClassificationType _tab;
85 
86  internal AssetObjectEditor(IClassificationTypeRegistryService registry)
87  {
88  schema = new CoreSchema();
89  _comment = registry.GetClassificationType(PredefinedClassificationTypeNames.Comment);
90  _anchor = registry.GetClassificationType(AssetObjectDefinitions.AnchorClassificationName);
91  _alias = registry.GetClassificationType(AssetObjectDefinitions.AliasClassificationName);
92  _key = registry.GetClassificationType(AssetObjectDefinitions.KeyClassificationName);
93  _value = registry.GetClassificationType(PredefinedClassificationTypeNames.Identifier);
94  _number = registry.GetClassificationType(AssetObjectDefinitions.NumberClassificationName);
95  _string = registry.GetClassificationType(PredefinedClassificationTypeNames.String);
96  _bool = registry.GetClassificationType(PredefinedClassificationTypeNames.Keyword);
97  _tag = registry.GetClassificationType(PredefinedClassificationTypeNames.SymbolDefinition);
98  _symbol = registry.GetClassificationType(PredefinedClassificationTypeNames.Operator);
99  _directive = registry.GetClassificationType(PredefinedClassificationTypeNames.PreprocessorKeyword);
100  _tab = registry.GetClassificationType(AssetObjectDefinitions.ErrorClassificationName);
101  }
102 
103  /// <summary>
104  /// This method scans the given SnapshotSpan for potential matches for this classification.
105  /// In this instance, it classifies everything and returns each span as a new ClassificationSpan.
106  /// </summary>
107  /// <param name="trackingSpan">The span currently being classified</param>
108  /// <returns>A list of ClassificationSpans that represent spans identified to be of this classification</returns>
109  public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
110  {
111  var classifications = new List<ClassificationSpan>();
112 
113  var text = span.GetText();
114 
115  var commentIndex = text.IndexOf('#');
116  if (commentIndex >= 0)
117  {
118  classifications.Add(
119  new ClassificationSpan(
120  new SnapshotSpan(
121  span.Snapshot,
122  new Span(span.Start + commentIndex, span.Length - commentIndex)
123  ),
124  _comment
125  )
126  );
127 
128  text = text.Substring(0, commentIndex);
129  }
130 
131  var match = Regex.Match(text, @"^( *(\t+))+");
132  if (match.Success)
133  {
134  foreach (Capture capture in match.Groups[2].Captures)
135  {
136  classifications.Add(
137  new ClassificationSpan(
138  new SnapshotSpan(
139  span.Snapshot,
140  new Span(span.Start + capture.Index, capture.Length)
141  ),
142  _tab
143  )
144  );
145  }
146  }
147 
148  try
149  {
150  var scanner = new Scanner(new StringReader(text));
151 
152  Type previousTokenType = null;
153  while (scanner.MoveNext())
154  {
155  IClassificationType classificationType = null;
156 
157  var currentTokenType = scanner.Current.GetType();
158  var tokenLength = scanner.Current.End.Index - scanner.Current.Start.Index;
159 
160  if (currentTokenType == typeof(Anchor))
161  {
162  classificationType = _anchor;
163  }
164  else if (currentTokenType == typeof(AnchorAlias))
165  {
166  classificationType = _alias;
167  }
168  else if (currentTokenType == typeof(Scalar))
169  {
170  if (previousTokenType == typeof (Key))
171  {
172  classificationType = _key;
173  }
174  else
175  {
176  // Decode the scalar
177  var scalarToken = (Scalar) scanner.Current;
178  var scalar = new SharpYaml.Events.Scalar(scalarToken.Value);
179  switch (schema.GetDefaultTag(scalar))
180  {
181  case JsonSchema.BoolShortTag:
182  classificationType = _bool;
183  break;
184  case JsonSchema.FloatShortTag:
185  case JsonSchema.IntShortTag:
186  classificationType = _number;
187  break;
188  case SchemaBase.StrShortTag:
189  classificationType = scalarToken.Style == ScalarStyle.DoubleQuoted || scalarToken.Style == ScalarStyle.SingleQuoted ? _string : _value;
190  break;
191  default:
192  classificationType = _value;
193  break;
194  }
195  }
196 
197  }
198  else if (currentTokenType == typeof(Tag))
199  {
200  classificationType = _tag;
201  }
202  else if (currentTokenType == typeof(TagDirective))
203  {
204  classificationType = _directive;
205  }
206  else if (currentTokenType == typeof(VersionDirective))
207  {
208  classificationType = _directive;
209  }
210  else if (tokenLength > 0)
211  {
212  classificationType = _symbol;
213  }
214 
215  previousTokenType = currentTokenType;
216 
217  if (classificationType != null && tokenLength > 0)
218  {
219  classifications.Add(
220  new ClassificationSpan(
221  new SnapshotSpan(
222  span.Snapshot,
223  new Span(span.Start + scanner.Current.Start.Index, tokenLength)
224  ),
225  classificationType
226  )
227  );
228  }
229  }
230  }
231  catch (Exception ex)
232  {
233  Trace.WriteLine("Exception in AssetObjectEditor " + ex);
234  }
235 
236  return classifications;
237  }
238 
239 #pragma warning disable 67
240  // This event gets raised if a non-text change would affect the classification in some way,
241  // for example typing /* would cause the classification to change in C# without directly
242  // affecting the span.
243  public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
244 #pragma warning restore 67
245  }
246  #endregion //Classifier
247 }
IList< ClassificationSpan > GetClassificationSpans(SnapshotSpan span)
This method scans the given SnapshotSpan for potential matches for this classification. In this instance, it classifies everything and returns each span as a new ClassificationSpan.
EventHandler< ClassificationChangedEventArgs > ClassificationChanged
global::MonoTouch.Constants Constants
Definition: TouchRunner.cs:42
SiliconStudio.Core.Utilities Utilities
Definition: Texture.cs:29
Classifier that classifies all text as an instance of the OrinaryClassifierType
Tokens
Summary Canonical example of MPLEX automaton