Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ModuleMixin.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.Linq;
6 
7 using SiliconStudio.Paradox.Shaders.Parser.Analysis;
8 using SiliconStudio.Paradox.Shaders.Parser.Ast;
9 using SiliconStudio.Shaders.Ast;
10 
11 namespace SiliconStudio.Paradox.Shaders.Parser.Mixins
12 {
13  internal class ModuleMixin
14  {
15  #region Public members
16 
17  /// <summary>
18  /// The name of the mixin
19  /// </summary>
20  public string MixinName;
21 
22  /// <summary>
23  /// The name of the mixin
24  /// </summary>
25  public string MixinGenericName;
26 
27  /// <summary>
28  /// The shader AST
29  /// </summary>
30  public ShaderClassType Shader = null;
31 
32  /// <summary>
33  /// the virtual table before inheritance
34  /// </summary>
35  public MixinVirtualTable LocalVirtualTable = new MixinVirtualTable();
36 
37  /// <summary>
38  /// the virtual table after inheritance
39  /// </summary>
40  public MixinVirtualTable VirtualTable = new MixinVirtualTable();
41 
42  /// <summary>
43  /// List of all the other declarations
44  /// </summary>
45  public List<Node> RemainingNodes = new List<Node>();
46 
47  /// <summary>
48  /// List of all the base mixins
49  /// </summary>
50  public List<ModuleMixin> BaseMixins = new List<ModuleMixin>();
51 
52  /// <summary>
53  /// List of all the classes dependencies
54  /// </summary>
55  public List<ModuleMixin> InheritanceList = new List<ModuleMixin>();
56 
57  /// <summary>
58  /// List of all the needed mixins to perform semantic analysis
59  /// </summary>
60  public HashSet<ModuleMixin> MinimalContext = null;
61 
62  /// <summary>
63  /// List of all the variables dependencies
64  /// </summary>
65  public Dictionary<Variable, ModuleMixin> VariableDependencies = new Dictionary<Variable, ModuleMixin>();
66 
67  /// <summary>
68  /// List of all the variable that are initialized at "stage"
69  /// </summary>
70  public Dictionary<Variable, ModuleMixin> StageInitVariableDependencies = new Dictionary<Variable, ModuleMixin>();
71 
72  /// <summary>
73  /// Current class member references
74  /// </summary>
75  public ReferencesPool ClassReferences = new ReferencesPool();
76 
77  /// <summary>
78  /// Static references
79  /// </summary>
80  public ReferencesPool StaticReferences = new ReferencesPool();
81 
82  /// <summary>
83  /// Static references
84  /// </summary>
85  public ReferencesPool ExternReferences = new ReferencesPool();
86 
87  /// <summary>
88  /// References through stage init variables
89  /// </summary>
90  public ReferencesPool StageInitReferences = new ReferencesPool();
91 
92  /// <summary>
93  /// The result of the parsing
94  /// </summary>
95  public ParadoxParsingInfo ParsingInfo { get; set; }
96 
97  /// <summary>
98  /// Occurence ID in the inheritance tree
99  /// </summary>
100  public int OccurenceId = 0;
101 
102  /// <summary>
103  /// List of variables that share their name i.e. potential conflicting variables
104  /// </summary>
105  public HashSet<Variable> PotentialConflictingVariables = new HashSet<Variable>();
106 
107  /// <summary>
108  /// List of methods that share their signature i.e. potential conflicting methods
109  /// </summary>
110  public HashSet<MethodDeclaration> PotentialConflictingMethods = new HashSet<MethodDeclaration>();
111 
112  /// <summary>
113  /// A boolean stating that all the members are stage
114  /// </summary>
115  public bool StageOnlyClass = false;
116 
117  /// <summary>
118  /// A flag to state if the mixin dependencies has been analyzed yet
119  /// </summary>
120  public AnalysisStatus DependenciesStatus = AnalysisStatus.None;
121 
122  /// <summary>
123  /// A flag to state if the mixin type analysis was performed.
124  /// </summary>
125  public AnalysisStatus TypeAnalysisStatus = AnalysisStatus.None;
126 
127  /// <summary>
128  /// A flag to state if the module mixin was built.
129  /// </summary>
130  public AnalysisStatus ModuleMixinBuildStatus = AnalysisStatus.None;
131 
132  /// <summary>
133  /// A flag to state if the mixin virtual table was created
134  /// </summary>
135  public AnalysisStatus VirtualTableStatus = AnalysisStatus.None;
136 
137  /// <summary>
138  /// A flag to state if the mixin semantic analysis was performed
139  /// </summary>
140  public AnalysisStatus SemanticAnalysisStatus = AnalysisStatus.None;
141 
142  #endregion
143 
144  #region Constructors
145 
146  /// <summary>
147  /// Constructor
148  /// </summary>
149  /// <param name="shader">the shader AST</param>
150  public void SetShaderAst(ShaderClassType shader)
151  {
152  if (Shader != null)
153  throw new Exception("[ModuleMixin.SetShaderAst] Shader has already been set");
154  Shader = shader;
155  MixinName = shader.Name.Text;
156  }
157 
158  #endregion
159 
160  #region Public methods
161 
162  /// <summary>
163  /// Finds the method in the mixin
164  /// </summary>
165  /// <param name="expression">>The expression of the method reference</param>
166  /// <returns>a collection of the base methods if found</returns>
168  {
169  foreach (var method in LocalVirtualTable.Methods)
170  {
171  if (method.Method.IsSameSignature(expression) && method.Method is MethodDefinition)
172  yield return method;
173  }
174  }
175 
176  /// <summary>
177  /// Finds the top method - /!\ this is a hack because the mixin may not be analyzed yet /!\
178  /// </summary>
179  /// <param name="expression">The expression of the method reference</param>
180  /// <returns>The base method if found</returns>
181  public IEnumerable<MethodDeclarationShaderCouple> FindTopThisFunction(MethodInvocationExpression expression)
182  {
183  foreach (var method in FindMethod(expression))
184  yield return method;
185 
186  for (int i = InheritanceList.Count - 1; i >= 0; --i)
187  {
188  foreach (var method in InheritanceList[i].FindMethod(expression))
189  yield return method;
190  }
191  }
192 
193  /// <summary>
194  /// Finds the same variable in the ModuleMixin
195  /// </summary>
196  /// <param name="variableName">the variable name</param>
197  /// <returns>the variable declaration if found</returns>
198  public IEnumerable<VariableShaderCouple> FindVariableByName(string variableName)
199  {
200  return LocalVirtualTable.Variables.Where(x => x.Variable.Name.Text == variableName);
201  }
202 
203  /// <summary>
204  /// Find all the variables with this name
205  /// </summary>
206  /// <param name="variableName">the name of the variable</param>
207  /// <returns>A list of all the variables</returns>
208  public List<VariableShaderCouple> FindAllVariablesByName(string variableName)
209  {
210  var resList = FindVariableByName(variableName).ToList();
211 
212  for (int i = InheritanceList.Count - 1; i >= 0; --i)
213  resList.AddRange(InheritanceList[i].FindVariableByName(variableName));
214 
215  return resList;
216  }
217 
218  /// <summary>
219  /// Get the overloaded method from one of its base declaration
220  /// </summary>
221  /// <param name="methodDeclaration">the MethodDeclaration</param>
222  /// <returns>the overloaded MethodDeclaration</returns>
223  public MethodDeclaration GetMethodFromDeclaration(MethodDeclaration methodDeclaration)
224  {
225  var info = (VTableReference)methodDeclaration.GetTag(ParadoxTags.VirtualTableReference);
226  return VirtualTable.GetMethod(info.Shader, info.Slot);
227  }
228 
229  /// <summary>
230  /// Get the overloaded method from its call
231  /// </summary>
232  /// <param name="expression">the calling Expression</param>
233  /// <returns>the overloaded MethodDeclaration</returns>
234  public MethodDeclaration GetMethodFromExpression(Expression expression)
235  {
236  var info = (VTableReference)expression.GetTag(ParadoxTags.VirtualTableReference);
237  return VirtualTable.GetMethod(info.Shader, info.Slot);
238  }
239 
240  /// <summary>
241  /// Get the base MethodDeclaration from its call and the mixin where the call is performed
242  /// </summary>
243  /// <param name="expression">the calling expression</param>
244  /// <param name="mixin">the mixin where the call is performed</param>
245  /// <returns>the base MethodDeclaration</returns>
246  public MethodDeclaration GetBaseMethodFromExpression(Expression expression, ModuleMixin mixin)
247  {
248  var info = (VTableReference)expression.GetTag(ParadoxTags.VirtualTableReference);
249  var thisMethod = VirtualTable.GetMethod(info.Shader, info.Slot);
250 
251  if (thisMethod == null)
252  return null;
253 
254  var startIndex = mixin == this ? InheritanceList.Count : InheritanceList.IndexOf(mixin);
255 
256  for (int i = startIndex - 1; i >= 0; --i)
257  {
258  var dep = InheritanceList[i];
259  var array = VirtualTable.VirtualTableGroup[dep.MixinName];
260  for (int j = 0; j < array.Length; ++j)
261  {
262  var method = array[j];
263  if (method == thisMethod)
264  return dep.VirtualTable.VirtualTableGroup[dep.MixinName][j];
265  }
266  }
267  return null;
268  }
269 
270  #endregion
271  }
272 
273  /// <summary>
274  /// A status needed to analyze the mixin in the correct order within a compilation module
275  /// </summary>
276  public enum AnalysisStatus
277  {
278  None,
279  InProgress,
280  Cyclic,
281  Error,
282  Complete
283  }
284 }
A method definition with a body of statements.
Toplevel container of a shader parsing result.
Definition: Shader.cs:12
object GetTag(object tagKey)
Gets a tag value associated to this node..
Definition: Node.cs:78
AnalysisStatus
A status needed to analyze the mixin in the correct order within a compilation module ...
Definition: ModuleMixin.cs:276