4 using System.Collections.Generic;
7 using SiliconStudio.Shaders.Ast;
8 using SiliconStudio.Shaders.Visitor;
10 namespace SiliconStudio.Shaders.Writer
17 private bool isInVariableGroup;
18 private bool isVisitingMethodDeclaration;
20 private int lineCount;
22 #region Constructors and Destructors
29 public ShaderWriter(
bool buildScopeDeclaration =
false,
bool useNodeStack =
false)
30 : base(buildScopeDeclaration, useNodeStack)
32 StringBuilder =
new StringBuilder();
35 SourceLocations =
new List<SourceLocation>();
40 #region Public Properties
42 public List<SourceLocation> SourceLocations {
get; set; }
51 return StringBuilder.ToString();
59 public bool EnablePreprocessorLine {
get; set; }
67 protected bool EnableNewLine {
get; set; }
75 private int IndentLevel {
get; set; }
83 private bool NewLine {
get; set; }
91 private StringBuilder StringBuilder {
get; set; }
93 protected Stack<bool> IsDeclaratingVariable =
new Stack<bool>();
97 #region Public Methods
138 WriteLinkLine(structType);
143 WriteLinkLine(structType);
145 if (structType.
Name != null)
148 Write(structType.
Name);
157 foreach (var variableDeclaration
in structType.Fields)
158 VisitDynamic(variableDeclaration);
160 CloseBrace(
false).Write(
";").WriteLine();
167 WriteLinkLine(whileStatement);
170 if (whileStatement.IsDoWhile)
172 Write(
"do").WriteSpace();
173 WriteStatementContent(whileStatement.
Statement);
174 Write(
"while").WriteSpace().Write(
"(");
175 VisitDynamic(whileStatement.Condition);
182 Write(
"while").WriteSpace().Write(
"(");
183 VisitDynamic(whileStatement.Condition);
185 WriteStatementContent(whileStatement.
Statement);
195 Write(
"{").WriteSpace();
196 for (
int i = 0; i < arrayInitializerExpression.Items.Count; i++)
198 var expression = arrayInitializerExpression.Items[i];
199 if (i > 0) Write(
",").WriteSpace();
201 VisitDynamic(expression);
212 foreach (var statement
in blockStatement.Statements)
214 VisitDynamic(statement);
224 VisitDynamic(assignmentExpression.
Target);
225 WriteSpace().Write(assignmentExpression.Operator.ConvertToString()).WriteSpace();
226 VisitDynamic(assignmentExpression.
Value);
233 VisitDynamic(binaryExpression.
Left);
234 WriteSpace().Write(binaryExpression.Operator.ConvertToString()).WriteSpace();
235 VisitDynamic(binaryExpression.
Right);
242 WriteLinkLine(statement);
243 if (statement.
Case == null) WriteLine(
"default:");
246 Write(
"case").Write(
" ");
247 VisitDynamic(statement.
Case);
256 VisitDynamic(arrayType.
Type);
264 WriteLinkLine(expressionStatement);
274 WriteLinkLine(forStatement);
276 Write(
"for").WriteSpace().Write(
"(");
277 EnableNewLine =
false;
278 VisitDynamic(forStatement.Start);
280 VisitDynamic(forStatement.Condition);
283 VisitDynamic(forStatement.Next);
284 EnableNewLine =
true;
286 WriteStatementContent(forStatement.Body);
307 foreach (var statement
in statementList)
308 VisitDynamic(statement);
315 WriteLinkLine(ifStatement);
318 Write(
"if").WriteSpace().Write(
"(");
319 VisitDynamic(ifStatement.Condition);
321 WriteStatementContent(ifStatement.Then);
322 if (ifStatement.Else != null)
324 WriteLinkLine(ifStatement.Else);
326 var nestedIfStatement = ifStatement.Else as
IfStatement;
327 if (nestedIfStatement != null && nestedIfStatement.Attributes.Count == 0)
330 Visit(nestedIfStatement);
332 else WriteStatementContent(ifStatement.Else);
340 VisitDynamic(indexerExpression.
Target);
342 VisitDynamic(indexerExpression.
Index);
350 VisitDynamic(memberReferenceExpression.
Target);
352 VisitDynamic(memberReferenceExpression.
Member);
359 VisitDynamic(methodInvocationExpression.
Target);
361 for (
int i = 0; i < methodInvocationExpression.Arguments.Count; i++)
363 var expression = methodInvocationExpression.Arguments[i];
364 if (i > 0) Write(
",").WriteSpace();
366 VisitDynamic(expression);
376 WriteVariable(parameter);
384 VisitDynamic(parenthesizedExpression.
Content);
392 for (
int i = 0; i < expressionList.Count; i++)
394 var expression = expressionList[i];
395 if (i > 0) Write(
",").WriteSpace();
396 VisitDynamic(expression);
404 WriteLinkLine(returnStatement);
406 if (returnStatement.
Value != null)
409 VisitDynamic(returnStatement.
Value);
419 VisitDynamic(conditionalExpression.
Condition);
420 WriteSpace().Write(
"?").WriteSpace();
421 VisitDynamic(conditionalExpression.
Left);
422 WriteSpace().Write(
":").WriteSpace();
423 VisitDynamic(conditionalExpression.
Right);
430 if (unaryExpression.
Operator.IsPostFix())
433 Write(unaryExpression.
Operator.ConvertToString());
437 Write(unaryExpression.
Operator.ConvertToString());
446 WriteLinkLine(switchStatement);
447 Write(
"switch").WriteSpace().Write(
"(");
453 VisitDynamicList(switchStatement.
Groups);
462 VisitDynamicList(switchCaseGroup.
Cases);
472 WriteLinkLine(declarationStatement);
473 VisitDynamic(declarationStatement.
Content);
480 WriteLinkLine(methodDeclaration);
481 WriteMethodDeclaration(methodDeclaration).WriteLine(
";");
488 WriteLinkLine(methodDefinition);
489 WriteMethodDeclaration(methodDefinition);
492 foreach (var statement
in methodDefinition.Body)
493 VisitDynamic(statement);
501 WriteLinkLine(variable);
502 WriteVariable(variable);
509 Write(typeBase.
Name);
516 Write(typeBase.
Name);
524 Write(scalarType.
Name);
531 Write(genericType.
Name).Write(
"<");
532 for (
int i = 0; i < genericType.Parameters.Count; i++)
534 var parameter = genericType.Parameters[i];
535 if (i > 0) Write(
",").WriteSpace();
537 VisitDynamic(parameter);
552 var isStringLiteral = literal.Value is
string && !literal.Text.StartsWith(
"\"");
559 foreach (var subLiteral
in literal.
SubLiterals) Write(subLiteral.Text);
561 else Write(literal.
Text);
573 Write(qualifier.
Key.ToString());
580 Write(parameterQualifier.
Key.ToString());
587 Write(storageQualifier.
Key.ToString());
606 foreach (var genericQualifier
in qualifiers.Values)
608 var qualifier = (
Qualifier)genericQualifier;
613 if (qualifier.IsPost)
616 VisitDynamic(qualifier);
618 if (!qualifier.IsPost)
639 if (attributes == null || attributes.Count == 0)
return this;
641 foreach (var attribute
in attributes)
646 VisitDynamic(attribute);
676 if (expression == null)
return;
678 WriteSpace().Write(
"=");
680 VisitDynamic(expression);
693 StringBuilder.AppendLine();
715 StringBuilder.AppendLine(text);
719 else StringBuilder.Append(text);
724 private string previousSourceFileName = null;
736 var newSourceFile = node.Span.Location.FileSource;
737 var sourceLocation = string.Empty;
738 if (previousSourceFileName != newSourceFile)
740 sourceLocation = string.Format(
" \"{0}\"", newSourceFile);
741 previousSourceFileName = newSourceFile;
744 Append(Environment.NewLine).Append(
"#line {0}{1}", node.Span.Location.Line, sourceLocation).Append(Environment.NewLine);
777 StringBuilder.Append(text);
790 StringBuilder.AppendFormat(
format, args);
807 if (newLine) WriteLine();
841 Write(identifier.
Text);
844 WriteRankSpecifiers(identifier.
Indices);
863 isVisitingMethodDeclaration =
true;
874 Write(methodDeclaration.
Name);
878 for (
int i = 0; i < methodDeclaration.Parameters.Count; i++)
880 var parameter = methodDeclaration.Parameters[i];
881 if (i > 0) Write(
",").WriteSpace();
883 VisitDynamic(parameter);
894 isVisitingMethodDeclaration =
false;
909 foreach (var expression
in expressionList)
912 VisitDynamic(expression);
929 VisitDynamic(statement);
938 VisitDynamic(statement);
945 VisitDynamic(statement);
963 var arrayType = variable.Type as
ArrayType;
964 var baseType = arrayType == null ? variable.Type : arrayType.Type;
967 if (!isInVariableGroup)
969 IsDeclaratingVariable.Push(
true);
970 VisitDynamic(baseType);
971 IsDeclaratingVariable.Pop();
978 isInVariableGroup =
true;
980 for (
int i = 0; i < variable.SubVariables.Count; i++)
982 var subVariable = variable.SubVariables[i];
984 Write(
",").WriteSpace();
985 VisitDynamic(subVariable);
988 isInVariableGroup =
false;
992 Write(variable.
Name);
995 if (arrayType != null)
997 WriteRankSpecifiers(arrayType.Dimensions);
1011 if (!isInVariableGroup && !isVisitingMethodDeclaration)
1016 private void PrefixIndent()
1020 for (
int i = 0; i < IndentLevel; ++i)
1029 var fileSource = Path.GetFileName(node.Span.Location.FileSource);
1031 if (
string.Compare(fileSource,
"internal_hlsl_declarations.hlsl",
true) != 0 && node.Span.Length > 0)
1033 while (SourceLocations.Count < lineCount)
1039 return base.PreVisitNode(node);
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.
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.
virtual void Visit(ExpressionList expressionList)
object Key
Gets or sets the key.
virtual void Visit(ParameterQualifier parameterQualifier)
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 < > ...
string Text
Gets or sets the text.
virtual void Visit(AssignmentExpression assignmentExpression)
virtual void Visit(Statement statement)
SourceSpan Span
Gets or sets the source span.
string Text
Gets or sets the name.
virtual void Visit(Shader shader)
Visits the specified shader.
Qualifier Qualifiers
Gets or sets the qualifiers.
Identifier Member
Gets or sets the member.
virtual void Visit(IfStatement ifStatement)
While and Do-While statement.
virtual void Visit(BinaryExpression binaryExpression)
virtual void Visit(Literal literal)
Node Content
Gets or sets the content.
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)
Expression Left
Gets or sets the left.
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.
string FileSource
Filename source.
An abstract class for a post attribute definition.
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.
A declaration inside a statement.
List< AttributeBase > Attributes
Gets or sets the attributes.
Qualifier Qualifiers
Gets or sets the qualifiers.
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.
virtual void Visit(ReturnStatement returnStatement)
Statement()
Initializes a new instance of the Statement class.
virtual void Visit(StructType structType)
List< SwitchCaseGroup > Groups
Gets or sets the cases.
Expression Right
Gets or sets the right.
TypeBase ReturnType
Gets or sets the type of the return.
Expression Expression
Gets or sets the expression.
virtual void Visit(MethodDeclaration methodDeclaration)
List< AttributeBase > Attributes
Gets or sets the attributes.
Base root class for all statements.
Expression Target
Gets or sets the target.
A single parameter declaration.
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.
List< Literal > SubLiterals
Gets or sets the sub literals.
virtual void Visit(GenericType genericType)
SourceLocation Location
Location of this span.
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.
ShaderWriter Append(string text)
Appends the specified text.
Toplevel container of a shader parsing result.
List< AttributeBase > Attributes
virtual void Visit(ScalarType scalarType)
Expression InitialValue
Gets or sets the initial value.
ShaderWriter Write(List< AttributeBase > attributes, bool writePreQualifiers)
Writes the specified attributes.
bool IsGroup
Gets a value indicating whether this instance is group.
List< AttributeBase > Attributes
Gets or sets the attributes.
TypeBase Type
Gets or sets the type.
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
virtual void Visit(ParenthesizedExpression parenthesizedExpression)
Qualifier Qualifiers
Gets or sets the storage class.
List< Expression > Indices
Gets or sets the indices.
virtual void Visit(StorageQualifier storageQualifier)
ShaderWriter WriteSpace()
Writes the space.
Identifier Name
Gets or sets the type name.
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.
Expression Target
Gets or sets the this.
A single case or default statement.
bool HasIndices
Gets a value indicating whether this instance has indices.
virtual void Visit(ConditionalExpression conditionalExpression)
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.