4 using System.Collections.Generic;
6 using SiliconStudio.Paradox.Shaders.Parser.Analysis;
7 using SiliconStudio.Paradox.Shaders.Parser.Ast;
8 using SiliconStudio.Paradox.Shaders.Parser.Utility;
9 using SiliconStudio.Shaders.Ast;
10 using SiliconStudio.Shaders.Ast.Hlsl;
11 using SiliconStudio.Shaders.Utility;
12 using SiliconStudio.Shaders.Visitor;
14 namespace SiliconStudio.
Paradox.Shaders.Parser.Mixins
18 #region Private members
23 private StreamUsage currentStreamUsage = StreamUsage.Read;
28 private List<StreamUsageInfo> currentStreamUsageList = null;
33 private List<MethodDeclaration> alreadyAddedMethodsList = null;
38 private AssignmentOperatorStatus currentAssignmentOperatorStatus = AssignmentOperatorStatus.Read;
48 private string shaderName =
"Mix";
52 #region Public members
57 public HashSet<AssignmentExpression> StreamAssignations =
new HashSet<AssignmentExpression>();
62 public HashSet<AssignmentExpression> AssignationsToStream =
new HashSet<AssignmentExpression>();
67 public Dictionary<MethodDeclaration, List<StreamUsageInfo>> StreamsUsageByMethodDefinition =
new Dictionary<MethodDeclaration, List<StreamUsageInfo>>();
72 public HashSet<MethodInvocationExpression> AppendMethodCalls =
new HashSet<MethodInvocationExpression>();
88 shaderName = shaderClassType.Name.Text;
89 Visit(shaderClassType);
92 #region Private methods
101 currentStreamUsageList =
new List<StreamUsageInfo>();
102 alreadyAddedMethodsList =
new List<MethodDeclaration>();
104 Visit((
Node)methodDefinition);
106 if (currentStreamUsageList.Count > 0)
107 StreamsUsageByMethodDefinition.Add(methodDefinition, currentStreamUsageList);
117 Visit((
Node)expression);
119 var methodDecl = expression.Target.TypeInference.Declaration as
MethodDeclaration;
121 if (methodDecl != null)
127 if (!alreadyAddedMethodsList.Contains(methodDecl))
129 currentStreamUsageList.Add(
new StreamUsageInfo { CallType = StreamCallType.Method, MethodDeclaration = methodDecl,
Expression = expression });
130 alreadyAddedMethodsList.Add(methodDecl);
133 for (
int i = 0; i < expression.Arguments.Count; ++i)
137 if (arg != null && IsStreamMember(arg))
139 var isOut = methodDecl.Parameters[i].Qualifiers.Contains(SiliconStudio.Shaders.Ast.ParameterQualifier.Out);
144 var usage = methodDecl.Parameters[i].Qualifiers.Contains(SiliconStudio.Shaders.Ast.ParameterQualifier.Out) ?
StreamUsage.Write :
StreamUsage.Read;
145 AddStreamUsage(arg.TypeInference.Declaration as
Variable, arg, usage);
151 if (expression.
Target is MemberReferenceExpression && (expression.
Target as MemberReferenceExpression).Target.TypeInference.TargetType is
ClassType && (expression.Target as MemberReferenceExpression).
Member.Text ==
"Append")
152 AppendMethodCalls.Add(expression);
155 private static bool IsStreamMember(MemberReferenceExpression expression)
171 Visit((
Node)variableReferenceExpression);
173 var name = variableReferenceExpression.Name.Text;
174 if (name ==
"streams")
176 if (!(ParentNode is MemberReferenceExpression))
177 currentStreamUsageList.Add(
new StreamUsageInfo { CallType = StreamCallType.Direct, Variable = ParadoxSemanticAnalysis.StreamsVariable,
Expression = variableReferenceExpression, Usage = currentStreamUsage });
182 protected void Visit(MemberReferenceExpression memberReferenceExpression)
184 Visit((
Node)memberReferenceExpression);
187 if (IsStreamMember(memberReferenceExpression))
188 AddStreamUsage(memberReferenceExpression.
TypeInference.
Declaration as Variable, memberReferenceExpression, currentStreamUsage);
194 var prevStreamUsage = currentStreamUsage;
195 currentStreamUsage = StreamUsage.Read;
196 Visit((
Node)expression);
197 currentStreamUsage = prevStreamUsage;
203 var prevStreamUsage = currentStreamUsage;
204 currentStreamUsage = StreamUsage.Read;
205 Visit((
Node)expression);
206 currentStreamUsage = prevStreamUsage;
216 if (currentAssignmentOperatorStatus != AssignmentOperatorStatus.Read)
217 errorWarningLog.Error(ParadoxMessageCode.ErrorNestedAssignment, assignmentExpression.Span, assignmentExpression, shaderName);
219 var prevStreamUsage = currentStreamUsage;
220 currentStreamUsage = StreamUsage.Read;
221 assignmentExpression.Value = (
Expression)VisitDynamic(assignmentExpression.Value);
222 currentAssignmentOperatorStatus = (assignmentExpression.Operator != AssignmentOperator.Default) ? AssignmentOperatorStatus.ReadWrite : AssignmentOperatorStatus.Write;
225 assignmentExpression.Target = (
Expression)VisitDynamic(assignmentExpression.Target);
227 currentAssignmentOperatorStatus = AssignmentOperatorStatus.Read;
228 currentStreamUsage = prevStreamUsage;
233 StreamAssignations.Add(assignmentExpression);
234 else if (assignmentExpression.Value is VariableReferenceExpression && (assignmentExpression.Value as VariableReferenceExpression).Name.Text ==
"streams")
235 AssignationsToStream.Add(assignmentExpression);
245 private void AddStreamUsage(Variable variable, SiliconStudio.Shaders.Ast.Expression expression,
StreamUsage usage)
247 currentStreamUsageList.Add(
new StreamUsageInfo { CallType = StreamCallType.Member, Variable = variable,
Expression = expression, Usage = usage });
273 public Variable Variable = null;
274 public MethodDeclaration MethodDeclaration = null;
Describes a binary expression.
SiliconStudio.Core.Diagnostics.LoggerResult LoggerResult
string Text
Gets or sets the name.
A class to collect parsing/expression messages.
AssignmentOperator
Assignment operator used in assignment expression (a = b) or statements (a = b;)
A method definition with a body of statements.
IDeclaration Declaration
Gets or sets the declaration.
TypeInference TypeInference
Gets or sets the type reference.
Flags
Enumeration of the new Assimp's flags.
Identifier Name
Gets or sets the name.
Expression Target
Gets or sets the target.
A member reference in the form {this}.{Name}
A reference to a variable.