Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ShaderWriter.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 GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.IO;
6 using System.Text;
7 using SiliconStudio.Shaders.Ast;
8 using SiliconStudio.Shaders.Visitor;
9 
10 namespace SiliconStudio.Shaders.Writer
11 {
12  /// <summary>
13  /// A writer for a shader.
14  /// </summary>
15  public class ShaderWriter : ShaderVisitor
16  {
17  private bool isInVariableGroup;
18  private bool isVisitingMethodDeclaration;
19 
20  private int lineCount;
21 
22  #region Constructors and Destructors
23 
24  /// <summary>
25  /// Initializes a new instance of the <see cref="ShaderWriter"/> class.
26  /// </summary>
27  /// <param name="buildScopeDeclaration">if set to <c>true</c> [build scope declaration].</param>
28  /// <param name="useNodeStack">if set to <c>true</c> [use node stack].</param>
29  public ShaderWriter(bool buildScopeDeclaration = false, bool useNodeStack = false)
30  : base(buildScopeDeclaration, useNodeStack)
31  {
32  StringBuilder = new StringBuilder();
33  EnableNewLine = true;
34  lineCount = 1;
35  SourceLocations = new List<SourceLocation>();
36  }
37 
38  #endregion
39 
40  #region Public Properties
41 
42  public List<SourceLocation> SourceLocations { get; set; }
43 
44  /// <summary>
45  /// Gets the text.
46  /// </summary>
47  public string Text
48  {
49  get
50  {
51  return StringBuilder.ToString();
52  }
53  }
54 
55  #endregion
56 
57  #region Properties
58 
59  public bool EnablePreprocessorLine { get; set; }
60 
61  /// <summary>
62  /// Gets or sets a value indicating whether [enable new line].
63  /// </summary>
64  /// <value>
65  /// <c>true</c> if [enable new line]; otherwise, <c>false</c>.
66  /// </value>
67  protected bool EnableNewLine { get; set; }
68 
69  /// <summary>
70  /// Gets or sets the indent level.
71  /// </summary>
72  /// <value>
73  /// The indent level.
74  /// </value>
75  private int IndentLevel { get; set; }
76 
77  /// <summary>
78  /// Gets or sets a value indicating whether [new line].
79  /// </summary>
80  /// <value>
81  /// <c>true</c> if [new line]; otherwise, <c>false</c>.
82  /// </value>
83  private bool NewLine { get; set; }
84 
85  /// <summary>
86  /// Gets or sets the string builder.
87  /// </summary>
88  /// <value>
89  /// The string builder.
90  /// </value>
91  private StringBuilder StringBuilder { get; set; }
92 
93  protected Stack<bool> IsDeclaratingVariable = new Stack<bool>();
94 
95  #endregion
96 
97  #region Public Methods
98 
99  /// <summary>
100  /// Indents this instance.
101  /// </summary>
102  /// <returns>
103  /// this instance
104  /// </returns>
106  {
107  IndentLevel++;
108  return this;
109  }
110 
111  /// <summary>
112  /// Outdents this instance.
113  /// </summary>
114  /// <returns>
115  /// this instance
116  /// </returns>
118  {
119  IndentLevel--;
120  return this;
121  }
122 
123  /// <summary>
124  /// Visits the specified shader.
125  /// </summary>
126  /// <param name="shader">The shader.</param>
127  /// <returns></returns>
128  [Visit]
129  public virtual void Visit(Shader shader)
130  {
131  Visit((Node)shader);
132  }
133 
134  /// <inheritdoc />
135  [Visit]
136  public virtual void Visit(StructType structType)
137  {
138  WriteLinkLine(structType);
139 
140  // Pre Attributes
141  Write(structType.Attributes, true);
142 
143  WriteLinkLine(structType);
144  Write("struct");
145  if (structType.Name != null)
146  {
147  Write(" ");
148  Write(structType.Name);
149  WriteSpace();
150  }
151 
152  // Post Attributes
153  Write(structType.Attributes, false);
154 
155  OpenBrace();
156 
157  foreach (var variableDeclaration in structType.Fields)
158  VisitDynamic(variableDeclaration);
159 
160  CloseBrace(false).Write(";").WriteLine();
161  }
162 
163  /// <inheritdoc />
164  [Visit]
165  public virtual void Visit(WhileStatement whileStatement)
166  {
167  WriteLinkLine(whileStatement);
168  Visit((Statement)whileStatement);
169 
170  if (whileStatement.IsDoWhile)
171  {
172  Write("do").WriteSpace();
173  WriteStatementContent(whileStatement.Statement);
174  Write("while").WriteSpace().Write("(");
175  VisitDynamic(whileStatement.Condition);
176  Write(")");
177  Write(";");
178  WriteLine();
179  }
180  else
181  {
182  Write("while").WriteSpace().Write("(");
183  VisitDynamic(whileStatement.Condition);
184  Write(")");
185  WriteStatementContent(whileStatement.Statement);
186  }
187 
188  WriteLine();
189  }
190 
191  /// <inheritdoc />
192  [Visit]
193  public virtual void Visit(ArrayInitializerExpression arrayInitializerExpression)
194  {
195  Write("{").WriteSpace();
196  for (int i = 0; i < arrayInitializerExpression.Items.Count; i++)
197  {
198  var expression = arrayInitializerExpression.Items[i];
199  if (i > 0) Write(",").WriteSpace();
200 
201  VisitDynamic(expression);
202  }
203 
204  Write("}");
205  }
206 
207  /// <inheritdoc />
208  [Visit]
209  public virtual void Visit(BlockStatement blockStatement)
210  {
211  OpenBrace();
212  foreach (var statement in blockStatement.Statements)
213  {
214  VisitDynamic(statement);
215  }
216 
217  CloseBrace();
218  }
219 
220  /// <inheritdoc />
221  [Visit]
222  public virtual void Visit(AssignmentExpression assignmentExpression)
223  {
224  VisitDynamic(assignmentExpression.Target);
225  WriteSpace().Write(assignmentExpression.Operator.ConvertToString()).WriteSpace();
226  VisitDynamic(assignmentExpression.Value);
227  }
228 
229  /// <inheritdoc />
230  [Visit]
231  public virtual void Visit(BinaryExpression binaryExpression)
232  {
233  VisitDynamic(binaryExpression.Left);
234  WriteSpace().Write(binaryExpression.Operator.ConvertToString()).WriteSpace();
235  VisitDynamic(binaryExpression.Right);
236  }
237 
238  /// <inheritdoc />
239  [Visit]
240  public virtual void Visit(CaseStatement statement)
241  {
242  WriteLinkLine(statement);
243  if (statement.Case == null) WriteLine("default:");
244  else
245  {
246  Write("case").Write(" ");
247  VisitDynamic(statement.Case);
248  WriteLine(":");
249  }
250  }
251 
252  /// <inheritdoc/>
253  [Visit]
254  public virtual void Visit(ArrayType arrayType)
255  {
256  VisitDynamic(arrayType.Type);
257  WriteRankSpecifiers(arrayType.Dimensions);
258  }
259 
260  /// <inheritdoc />
261  [Visit]
262  public virtual void Visit(ExpressionStatement expressionStatement)
263  {
264  WriteLinkLine(expressionStatement);
265  VisitDynamic(expressionStatement.Expression);
266  WriteLine(";");
267  }
268 
269  /// <inheritdoc />
270  [Visit]
271  public virtual void Visit(ForStatement forStatement)
272  {
273  WriteLine();
274  WriteLinkLine(forStatement);
275  Visit((Statement)forStatement);
276  Write("for").WriteSpace().Write("(");
277  EnableNewLine = false;
278  VisitDynamic(forStatement.Start);
279  WriteSpace();
280  VisitDynamic(forStatement.Condition);
281  Write(";");
282  WriteSpace();
283  VisitDynamic(forStatement.Next);
284  EnableNewLine = true;
285  Write(")");
286  WriteStatementContent(forStatement.Body);
287  }
288 
289  /// <inheritdoc />
290  [Visit]
291  public virtual void Visit(Identifier identifier)
292  {
293  Write(identifier);
294  }
295 
296  /// <inheritdoc/>
297  [Visit]
298  public virtual void Visit(Statement statement)
299  {
300  Write(statement.Attributes, true);
301  }
302 
303  /// <inheritdoc/>
304  [Visit]
305  public virtual void Visit(StatementList statementList)
306  {
307  foreach (var statement in statementList)
308  VisitDynamic(statement);
309  }
310 
311  /// <inheritdoc />
312  [Visit]
313  public virtual void Visit(IfStatement ifStatement)
314  {
315  WriteLinkLine(ifStatement);
316  Visit((Statement)ifStatement);
317 
318  Write("if").WriteSpace().Write("(");
319  VisitDynamic(ifStatement.Condition);
320  Write(")");
321  WriteStatementContent(ifStatement.Then);
322  if (ifStatement.Else != null)
323  {
324  WriteLinkLine(ifStatement.Else);
325  Write("else");
326  var nestedIfStatement = ifStatement.Else as IfStatement;
327  if (nestedIfStatement != null && nestedIfStatement.Attributes.Count == 0)
328  {
329  Write(" ");
330  Visit(nestedIfStatement);
331  }
332  else WriteStatementContent(ifStatement.Else);
333  }
334  }
335 
336  /// <inheritdoc />
337  [Visit]
338  public virtual void Visit(IndexerExpression indexerExpression)
339  {
340  VisitDynamic(indexerExpression.Target);
341  Write("[");
342  VisitDynamic(indexerExpression.Index);
343  Write("]");
344  }
345 
346  /// <inheritdoc />
347  [Visit]
348  public virtual void Visit(MemberReferenceExpression memberReferenceExpression)
349  {
350  VisitDynamic(memberReferenceExpression.Target);
351  Write(".");
352  VisitDynamic(memberReferenceExpression.Member);
353  }
354 
355  /// <inheritdoc />
356  [Visit]
357  public virtual void Visit(MethodInvocationExpression methodInvocationExpression)
358  {
359  VisitDynamic(methodInvocationExpression.Target);
360  Write("(");
361  for (int i = 0; i < methodInvocationExpression.Arguments.Count; i++)
362  {
363  var expression = methodInvocationExpression.Arguments[i];
364  if (i > 0) Write(",").WriteSpace();
365 
366  VisitDynamic(expression);
367  }
368 
369  Write(")");
370  }
371 
372  /// <inheritdoc />
373  [Visit]
374  public virtual void Visit(Parameter parameter)
375  {
376  WriteVariable(parameter);
377  }
378 
379  /// <inheritdoc />
380  [Visit]
381  public virtual void Visit(ParenthesizedExpression parenthesizedExpression)
382  {
383  Write("(");
384  VisitDynamic(parenthesizedExpression.Content);
385  Write(")");
386  }
387 
388  /// <inheritdoc />
389  [Visit]
390  public virtual void Visit(ExpressionList expressionList)
391  {
392  for (int i = 0; i < expressionList.Count; i++)
393  {
394  var expression = expressionList[i];
395  if (i > 0) Write(",").WriteSpace();
396  VisitDynamic(expression);
397  }
398  }
399 
400  /// <inheritdoc />
401  [Visit]
402  public virtual void Visit(ReturnStatement returnStatement)
403  {
404  WriteLinkLine(returnStatement);
405  Write("return");
406  if (returnStatement.Value != null)
407  {
408  Write(" ");
409  VisitDynamic(returnStatement.Value);
410  }
411 
412  WriteLine(";");
413  }
414 
415  /// <inheritdoc />
416  [Visit]
417  public virtual void Visit(ConditionalExpression conditionalExpression)
418  {
419  VisitDynamic(conditionalExpression.Condition);
420  WriteSpace().Write("?").WriteSpace();
421  VisitDynamic(conditionalExpression.Left);
422  WriteSpace().Write(":").WriteSpace();
423  VisitDynamic(conditionalExpression.Right);
424  }
425 
426  /// <inheritdoc />
427  [Visit]
428  public virtual void Visit(UnaryExpression unaryExpression)
429  {
430  if (unaryExpression.Operator.IsPostFix())
431  {
432  VisitDynamic(unaryExpression.Expression);
433  Write(unaryExpression.Operator.ConvertToString());
434  }
435  else
436  {
437  Write(unaryExpression.Operator.ConvertToString());
438  VisitDynamic(unaryExpression.Expression);
439  }
440  }
441 
442  /// <inheritdoc />
443  [Visit]
444  public virtual void Visit(SwitchStatement switchStatement)
445  {
446  WriteLinkLine(switchStatement);
447  Write("switch").WriteSpace().Write("(");
448  VisitDynamic(switchStatement.Condition);
449  Write(")");
450  WriteLine();
451  OpenBrace();
452 
453  VisitDynamicList(switchStatement.Groups);
454 
455  CloseBrace();
456  }
457 
458  /// <inheritdoc />
459  [Visit]
460  public virtual void Visit(SwitchCaseGroup switchCaseGroup)
461  {
462  VisitDynamicList(switchCaseGroup.Cases);
463  Indent();
464  VisitDynamic(switchCaseGroup.Statements);
465  Outdent();
466  }
467 
468  /// <inheritdoc />
469  [Visit]
470  public virtual void Visit(DeclarationStatement declarationStatement)
471  {
472  WriteLinkLine(declarationStatement);
473  VisitDynamic(declarationStatement.Content);
474  }
475 
476  /// <inheritdoc />
477  [Visit]
478  public virtual void Visit(MethodDeclaration methodDeclaration)
479  {
480  WriteLinkLine(methodDeclaration);
481  WriteMethodDeclaration(methodDeclaration).WriteLine(";");
482  }
483 
484  /// <inheritdoc />
485  [Visit]
486  public virtual void Visit(MethodDefinition methodDefinition)
487  {
488  WriteLinkLine(methodDefinition);
489  WriteMethodDeclaration(methodDefinition);
490 
491  OpenBrace();
492  foreach (var statement in methodDefinition.Body)
493  VisitDynamic(statement);
494  CloseBrace();
495  }
496 
497  /// <inheritdoc />
498  [Visit]
499  public virtual void Visit(Variable variable)
500  {
501  WriteLinkLine(variable);
502  WriteVariable(variable);
503  }
504 
505  /// <inheritdoc />
506  [Visit]
507  public virtual void Visit(ObjectType typeBase)
508  {
509  Write(typeBase.Name);
510  }
511 
512  /// <inheritdoc />
513  [Visit]
514  public virtual void Visit(TypeName typeBase)
515  {
516  Write(typeBase.Name);
517  }
518 
519  /// <inheritdoc />
520  [Visit]
521  public virtual void Visit(ScalarType scalarType)
522  {
523  Write(scalarType.Qualifiers, true);
524  Write(scalarType.Name);
525  }
526 
527  /// <inheritdoc />
528  [Visit]
529  public virtual void Visit(GenericType genericType)
530  {
531  Write(genericType.Name).Write("<");
532  for (int i = 0; i < genericType.Parameters.Count; i++)
533  {
534  var parameter = genericType.Parameters[i];
535  if (i > 0) Write(",").WriteSpace();
536 
537  VisitDynamic(parameter);
538  }
539 
540  Write(">");
541  }
542 
543  /// <inheritdoc />
544  [Visit]
545  public virtual void Visit(Literal literal)
546  {
547  if (literal == null)
548  {
549  return;
550  }
551 
552  var isStringLiteral = literal.Value is string && !literal.Text.StartsWith("\"");
553  if (isStringLiteral)
554  {
555  Write("\"");
556  }
557  if (literal.SubLiterals != null && literal.SubLiterals.Count > 0)
558  {
559  foreach (var subLiteral in literal.SubLiterals) Write(subLiteral.Text);
560  }
561  else Write(literal.Text);
562  if (isStringLiteral)
563  {
564  Write("\"");
565  }
566  }
567 
568  /// <inheritdoc />
569  [Visit]
570  public virtual void Visit(Qualifier qualifier)
571  {
572  // Each qualifier should have a custom visit instead of using this default one.
573  Write(qualifier.Key.ToString());
574  }
575 
576  /// <inheritdoc />
577  [Visit]
578  public virtual void Visit(ParameterQualifier parameterQualifier)
579  {
580  Write(parameterQualifier.Key.ToString());
581  }
582 
583  /// <inheritdoc />
584  [Visit]
585  public virtual void Visit(StorageQualifier storageQualifier)
586  {
587  Write(storageQualifier.Key.ToString());
588  }
589 
590  /// <summary>
591  /// Writes the specified qualifier.
592  /// </summary>
593  /// <param name="qualifiers">
594  /// The qualifier.
595  /// </param>
596  /// <param name="writePreQualifiers">
597  /// if set to <c>true</c> [write pre qualifiers].
598  /// </param>
599  /// <returns>
600  /// This instance
601  /// </returns>
602  public ShaderWriter Write(Qualifier qualifiers, bool writePreQualifiers)
603  {
604  if (qualifiers == Qualifier.None) return this;
605 
606  foreach (var genericQualifier in qualifiers.Values)
607  {
608  var qualifier = (Qualifier)genericQualifier;
609 
610  if (qualifier == Qualifier.None || qualifier.IsPost == writePreQualifiers)
611  continue;
612 
613  if (qualifier.IsPost)
614  Write(" ");
615 
616  VisitDynamic(qualifier);
617 
618  if (!qualifier.IsPost)
619  Write(" ");
620  }
621 
622  return this;
623  }
624 
625  /// <summary>
626  /// Writes the specified attributes.
627  /// </summary>
628  /// <param name="attributes">
629  /// The attributes.
630  /// </param>
631  /// <param name="writePreQualifiers">
632  /// if set to <c>true</c> [write pre qualifiers].
633  /// </param>
634  /// <returns>
635  /// This instance
636  /// </returns>
637  public ShaderWriter Write(List<AttributeBase> attributes, bool writePreQualifiers)
638  {
639  if (attributes == null || attributes.Count == 0) return this;
640 
641  foreach (var attribute in attributes)
642  {
643  if (attribute is PostAttributeBase == writePreQualifiers)
644  continue;
645 
646  VisitDynamic(attribute);
647  }
648 
649  return this;
650  }
651 
652  /// <summary>
653  /// Writes the specified text.
654  /// </summary>
655  /// <param name="text">
656  /// The text.
657  /// </param>
658  /// <returns>
659  /// this instance
660  /// </returns>
661  public ShaderWriter Write(string text)
662  {
663  PrefixIndent();
664  Append(text);
665  return this;
666  }
667 
668  /// <summary>
669  /// Writes the initializer.
670  /// </summary>
671  /// <param name="expression">
672  /// The expression.
673  /// </param>
674  public virtual void WriteInitializer(Expression expression)
675  {
676  if (expression == null) return;
677 
678  WriteSpace().Write("=");
679  WriteSpace();
680  VisitDynamic(expression);
681  }
682 
683  /// <summary>
684  /// Writes the line.
685  /// </summary>
686  /// <returns>
687  /// This instance
688  /// </returns>
690  {
691  if (EnableNewLine)
692  {
693  StringBuilder.AppendLine();
694  NewLine = true;
695  lineCount++;
696  }
697 
698  return this;
699  }
700 
701  /// <summary>
702  /// Writes the line.
703  /// </summary>
704  /// <param name="text">
705  /// The text.
706  /// </param>
707  /// <returns>
708  /// this instance
709  /// </returns>
710  public ShaderWriter WriteLine(string text)
711  {
712  if (EnableNewLine)
713  {
714  PrefixIndent();
715  StringBuilder.AppendLine(text);
716  NewLine = true;
717  lineCount++;
718  }
719  else StringBuilder.Append(text);
720 
721  return this;
722  }
723 
724  private string previousSourceFileName = null;
725 
726  /// <summary>
727  /// Writes a link line using #line preprocessing directive with the specified node
728  /// </summary>
729  /// <param name="node">The node to use the Span.</param>
730  /// <returns>This instance</returns>
732  {
733  if (!EnablePreprocessorLine || node.Span.Location.Line == 0)
734  return this;
735 
736  var newSourceFile = node.Span.Location.FileSource;
737  var sourceLocation = string.Empty;
738  if (previousSourceFileName != newSourceFile)
739  {
740  sourceLocation = string.Format(" \"{0}\"", newSourceFile);
741  previousSourceFileName = newSourceFile;
742  }
743 
744  Append(Environment.NewLine).Append("#line {0}{1}", node.Span.Location.Line, sourceLocation).Append(Environment.NewLine);
745  NewLine = true;
746  lineCount++;
747  return this;
748  }
749 
750  /// <summary>
751  /// Writes the space.
752  /// </summary>
753  /// <returns>
754  /// this instance
755  /// </returns>
757  {
758  Append(" ");
759  return this;
760  }
761 
762  #endregion
763 
764  #region Methods
765 
766  /// <summary>
767  /// Appends the specified text.
768  /// </summary>
769  /// <param name="text">
770  /// The text.
771  /// </param>
772  /// <returns>
773  /// this instance
774  /// </returns>
775  protected ShaderWriter Append(string text)
776  {
777  StringBuilder.Append(text);
778  return this;
779  }
780 
781  /// <summary>
782  /// Appends the specified formatted text.
783  /// </summary>
784  /// <param name="format">The formatted text.</param>
785  /// <param name="args">The args to apply to the formatted text.</param>
786  /// <returns>This instance</returns>
787  protected ShaderWriter Append(string format, params object[] args)
788  {
789  PrefixIndent();
790  StringBuilder.AppendFormat(format, args);
791  return this;
792  }
793 
794  /// <summary>
795  /// Closes the brace.
796  /// </summary>
797  /// <param name="newLine">
798  /// if set to <c>true</c> [new line].
799  /// </param>
800  /// <returns>
801  /// This instance
802  /// </returns>
803  protected ShaderWriter CloseBrace(bool newLine = true)
804  {
805  Outdent();
806  Write("}");
807  if (newLine) WriteLine();
808 
809  return this;
810  }
811 
812  /// <summary>
813  /// Opens the brace.
814  /// </summary>
815  /// <returns>
816  /// This instance
817  /// </returns>
819  {
820  WriteLine();
821  Write("{");
822  WriteLine();
823  Indent();
824  return this;
825  }
826 
827  /// <summary>
828  /// Writes the specified identifier.
829  /// </summary>
830  /// <param name="identifier">
831  /// The identifier.
832  /// </param>
833  /// <returns>
834  /// This instance
835  /// </returns>
836  protected virtual ShaderWriter Write(Identifier identifier)
837  {
838  if (identifier.IsSpecialReference)
839  Write("<");
840 
841  Write(identifier.Text);
842 
843  if (identifier.HasIndices)
844  WriteRankSpecifiers(identifier.Indices);
845 
846  if (identifier.IsSpecialReference)
847  Write(">");
848 
849  return this;
850  }
851 
852  /// <summary>
853  /// Writes the specified method declaration.
854  /// </summary>
855  /// <param name="methodDeclaration">
856  /// The method declaration.
857  /// </param>
858  /// <returns>
859  /// This instance
860  /// </returns>
861  protected virtual ShaderWriter WriteMethodDeclaration(MethodDeclaration methodDeclaration)
862  {
863  isVisitingMethodDeclaration = true;
864 
865  // Pre Attributes
866  Write(methodDeclaration.Attributes, true);
867 
868  // Pre Qualifiers
869  Write(methodDeclaration.Qualifiers, true);
870 
871  VisitDynamic(methodDeclaration.ReturnType);
872 
873  Write(" ");
874  Write(methodDeclaration.Name);
875 
876  Write("(");
877 
878  for (int i = 0; i < methodDeclaration.Parameters.Count; i++)
879  {
880  var parameter = methodDeclaration.Parameters[i];
881  if (i > 0) Write(",").WriteSpace();
882 
883  VisitDynamic(parameter);
884  }
885 
886  Write(")");
887 
888  // Post Qualifiers
889  Write(methodDeclaration.Qualifiers, false);
890 
891  // Post Attributes
892  Write(methodDeclaration.Attributes, false);
893 
894  isVisitingMethodDeclaration = false;
895  return this;
896  }
897 
898  /// <summary>
899  /// Writes the rank specifiers.
900  /// </summary>
901  /// <param name="expressionList">
902  /// The expression list.
903  /// </param>
904  /// <returns>
905  /// This instance
906  /// </returns>
908  {
909  foreach (var expression in expressionList)
910  {
911  Write("[");
912  VisitDynamic(expression);
913  Write("]");
914  }
915 
916  return this;
917  }
918 
919  /// <summary>
920  /// Writes the content of the statement.
921  /// </summary>
922  /// <param name="statement">
923  /// The statement.
924  /// </param>
925  protected void WriteStatementContent(Statement statement)
926  {
927  if (statement is BlockStatement)
928  {
929  VisitDynamic(statement);
930  }
931  else
932  {
933  bool needBraces = (statement is StatementList && ((StatementList)statement).Count > 1);
934 
935  if (needBraces)
936  {
937  OpenBrace();
938  VisitDynamic(statement);
939  CloseBrace();
940  }
941  else
942  {
943  WriteLine();
944  Indent();
945  VisitDynamic(statement);
946  Outdent();
947  }
948  }
949  }
950 
951  /// <summary>
952  /// Writes the variable.
953  /// </summary>
954  /// <param name="variable">The variable.</param>
955  protected void WriteVariable(Variable variable)
956  {
957  // Pre Attributes
958  Write(variable.Attributes, true);
959 
960  // Pre qualifiers
961  Write(variable.Qualifiers, true);
962 
963  var arrayType = variable.Type as ArrayType;
964  var baseType = arrayType == null ? variable.Type : arrayType.Type;
965 
966  // If this is a variable declarator not attached to a group, output the type
967  if (!isInVariableGroup)
968  {
969  IsDeclaratingVariable.Push(true);
970  VisitDynamic(baseType);
971  IsDeclaratingVariable.Pop();
972  WriteSpace();
973  }
974 
975  if (variable.IsGroup)
976  {
977  // Enter a variable group
978  isInVariableGroup = true;
979 
980  for (int i = 0; i < variable.SubVariables.Count; i++)
981  {
982  var subVariable = variable.SubVariables[i];
983  if (i > 0)
984  Write(",").WriteSpace();
985  VisitDynamic(subVariable);
986  }
987 
988  isInVariableGroup = false;
989  }
990  else
991  {
992  Write(variable.Name);
993  }
994 
995  if (arrayType != null)
996  {
997  WriteRankSpecifiers(arrayType.Dimensions);
998  }
999 
1000  // Post qualifiers
1001  Write(variable.Qualifiers, false);
1002 
1003  // Post Attributes
1004  Write(variable.Attributes, false);
1005 
1006  WriteInitializer(variable.InitialValue);
1007 
1008  // A variable can be a parameter or a grouped variable.
1009  // If this is a parameter and we are visiting a method declaration, don't output the ";"
1010  // If we are inside a group variable, don't output ";" as the upper level will add "," to separate variables.
1011  if (!isInVariableGroup && !isVisitingMethodDeclaration)
1012  WriteLine(";");
1013 
1014  }
1015 
1016  private void PrefixIndent()
1017  {
1018  if (NewLine)
1019  {
1020  for (int i = 0; i < IndentLevel; ++i)
1021  Append(" ");
1022 
1023  NewLine = false;
1024  }
1025  }
1026 
1027  protected override bool PreVisitNode(Node node)
1028  {
1029  var fileSource = Path.GetFileName(node.Span.Location.FileSource);
1030 
1031  if (string.Compare(fileSource, "internal_hlsl_declarations.hlsl", true) != 0 && node.Span.Length > 0)
1032  {
1033  while (SourceLocations.Count < lineCount)
1034  {
1035  SourceLocations.Add(new SourceLocation(node.Span.Location.FileSource, node.Span.Location.Position, node.Span.Location.Line, 1));
1036  }
1037  }
1038 
1039  return base.PreVisitNode(node);
1040  }
1041 
1042  #endregion
1043  }
1044 }
ShaderWriter Write(string text)
Writes the specified text.
Expression Right
Gets or sets the right expression.
Expression Case
Gets or sets the case.
virtual void Visit(UnaryExpression unaryExpression)
Identifier Name
Gets or sets the name.
Definition: Variable.cs:77
int Position
Absolute position in the file.
Expression Content
Gets or sets the expression.
virtual void Visit(DeclarationStatement declarationStatement)
Describes a binary expression.
virtual void Visit(ArrayType arrayType)
ShaderWriter(bool buildScopeDeclaration=false, bool useNodeStack=false)
Initializes a new instance of the ShaderWriter class.
Definition: ShaderWriter.cs:29
virtual void Visit(ExpressionList expressionList)
object Key
Gets or sets the key.
virtual void Visit(ParameterQualifier parameterQualifier)
A typeless reference.
Definition: TypeName.cs:10
int Line
Line in the file (1-based).
virtual void Visit(Variable variable)
virtual void Visit(MemberReferenceExpression memberReferenceExpression)
virtual void Visit(CaseStatement statement)
bool IsSpecialReference
Gets or sets a value indicating whether this instance is a special reference using < > ...
Definition: Identifier.cs:69
string Text
Gets or sets the text.
Definition: Literal.cs:48
virtual void Visit(AssignmentExpression assignmentExpression)
virtual void Visit(Statement statement)
SourceSpan Span
Gets or sets the source span.
Definition: Node.cs:37
string Text
Gets or sets the name.
Definition: Identifier.cs:77
virtual void Visit(Shader shader)
Visits the specified shader.
Qualifier Qualifiers
Gets or sets the qualifiers.
Definition: Variable.cs:53
virtual void Visit(IfStatement ifStatement)
While and Do-While statement.
virtual void Visit(BinaryExpression binaryExpression)
virtual void Visit(Literal literal)
Expression used to initliaze an array {...expressions,}
void WriteStatementContent(Statement statement)
Writes the content of the statement.
ShaderWriter Append(string format, params object[] args)
Appends the specified formatted text.
virtual void WriteInitializer(Expression expression)
Writes the initializer.
Identifier Name
Gets or sets the name.
Expression Condition
Gets or sets the condition.
Expression Index
Gets or sets the index.
Expression Left
Gets or sets the left expression.
virtual void Visit(Qualifier qualifier)
virtual void Visit(SwitchStatement switchStatement)
virtual void Visit(TypeName typeBase)
ShaderWriter WriteLine()
Writes the line.
virtual void Visit(ForStatement forStatement)
virtual ShaderWriter Write(Identifier identifier)
Writes the specified identifier.
Expression Target
Gets or sets the target receving the assigment.
StatementList Statements
Gets or sets the statements.
virtual void Visit(ObjectType typeBase)
Expression Expression
Gets or sets the expression.
virtual void Visit(BlockStatement blockStatement)
An expression surrounded by parenthesis.
A method definition with a body of statements.
An abstract class for a post attribute definition.
Abstract node.
Definition: Node.cs:15
UnaryOperator Operator
Gets or sets the operator.
ShaderWriter Write(Qualifier qualifiers, bool writePreQualifiers)
Writes the specified qualifier.
virtual void Visit(ExpressionStatement expressionStatement)
virtual void Visit(IndexerExpression indexerExpression)
Expression Value
Gets or sets the value of the assigment..
virtual void Visit(MethodDefinition methodDefinition)
ShaderWriter OpenBrace()
Opens the brace.
List< AttributeBase > Attributes
Gets or sets the attributes.
Definition: Statement.cs:27
Qualifier Qualifiers
Gets or sets the qualifiers.
Definition: TypeBase.cs:85
override bool PreVisitNode(Node node)
Called before visiting the node.
bool IsPost
Gets or sets a value indicating whether this instance is a post qualifier.
Definition: Qualifier.cs:52
virtual void Visit(ReturnStatement returnStatement)
Statement()
Initializes a new instance of the Statement class.
Definition: Statement.cs:16
virtual void Visit(StructType structType)
List< SwitchCaseGroup > Groups
Gets or sets the cases.
TypeBase ReturnType
Gets or sets the type of the return.
Expression Expression
Gets or sets the expression.
virtual void Visit(MethodDeclaration methodDeclaration)
A variable declaration.
Definition: Variable.cs:11
List< AttributeBase > Attributes
Gets or sets the attributes.
Definition: TypeBase.cs:61
Base root class for all statements.
Definition: Statement.cs:11
A single parameter declaration.
Definition: Parameter.cs:10
Expression Value
Gets or sets the value.
virtual void Visit(MethodInvocationExpression methodInvocationExpression)
Expression Target
Gets or sets the target.
A member reference in the form {this}.{Name}
virtual void Visit(StatementList statementList)
List< Expression > Dimensions
Gets or sets the dimensions.
Definition: ArrayType.cs:48
List< Literal > SubLiterals
Gets or sets the sub literals.
Definition: Literal.cs:79
virtual void Visit(GenericType genericType)
SourceLocation Location
Location of this span.
Definition: SourceSpan.cs:17
virtual void Visit(Identifier identifier)
virtual ShaderWriter WriteMethodDeclaration(MethodDeclaration methodDeclaration)
Writes the specified method declaration.
A group of cases and default attached to their statements.
Base class for all generic types.
Definition: GenericType.cs:14
ShaderWriter Append(string text)
Appends the specified text.
Toplevel container of a shader parsing result.
Definition: Shader.cs:12
List< AttributeBase > Attributes
Definition: Variable.cs:45
virtual void Visit(ScalarType scalarType)
Expression InitialValue
Gets or sets the initial value.
Definition: Variable.cs:69
ShaderWriter Write(List< AttributeBase > attributes, bool writePreQualifiers)
Writes the specified attributes.
bool IsGroup
Gets a value indicating whether this instance is group.
Definition: Variable.cs:94
List< AttributeBase > Attributes
Gets or sets the attributes.
TypeBase Type
Gets or sets the type.
Definition: ArrayType.cs:68
ShaderWriter WriteLine(string text)
Writes the line.
List< CaseStatement > Cases
Gets or sets the cases.
ShaderWriter WriteRankSpecifiers(IEnumerable< Expression > expressionList)
Writes the rank specifiers.
ShaderWriter Indent()
Indents this instance.
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
virtual void Visit(ParenthesizedExpression parenthesizedExpression)
Qualifier Qualifiers
Gets or sets the storage class.
List< Expression > Indices
Gets or sets the indices.
Definition: Identifier.cs:61
virtual void Visit(StorageQualifier storageQualifier)
ShaderWriter WriteSpace()
Writes the space.
Identifier Name
Gets or sets the type name.
Definition: TypeBase.cs:77
Expression Condition
Gets or sets the condition.
virtual void Visit(Parameter parameter)
ShaderWriter WriteLinkLine(Node node)
Writes a link line using #line preprocessing directive with the specified node
static readonly Qualifier None
None Enum.
Definition: Qualifier.cs:18
A single case or default statement.
bool HasIndices
Gets a value indicating whether this instance has indices.
Definition: Identifier.cs:45
virtual void Visit(ConditionalExpression conditionalExpression)
A field of a struct.
Definition: Literal.cs:13
virtual void Visit(SwitchCaseGroup switchCaseGroup)
virtual void Visit(ArrayInitializerExpression arrayInitializerExpression)
void WriteVariable(Variable variable)
Writes the variable.
virtual void Visit(WhileStatement whileStatement)
ShaderWriter Outdent()
Outdents this instance.
ShaderWriter CloseBrace(bool newLine=true)
Closes the brace.