The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
SSAHelper.cs
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
3 // Project rROTOR
4 // --------------------------------------------------------------------------
5 // File: SSAInfo.cs
6 // Author: Francisco Ortin - francisco.ortin@gmail.com
7 // Description:
8 // This helper class offers static methods to save and update types
9 // of references.
10 // --------------------------------------------------------------------------
11 // Create date: 08-06-2007
12 // Modification date: 08-06-2007
14 
15 using System;
16 using System.Collections.Generic;
17 
18 using AST;
19 using TypeSystem;
20 using Tools;
21 using TypeSystem.Constraints;
22 using ErrorManagement;
23 using TypeSystem.Operations;
24 
25 namespace Semantic.SSAAlgorithm {
29  static class SSAHelper {
30 
31  #region SimplifyReferencesUsedInBodies()
32  public static void SimplifyReferences(IList<SingleIdentifierExpression> references) {
37  for (int i = references.Count - 1; i >= 0; i--) {
38  // * If it is a class or namespace, we can erase it
39  if (references[i].ExpressionType is ClassType || references[i].ExpressionType is NameSpaceType) {
40  references.RemoveAt(i);
41  continue;
42  }
43  TypeExpression symbolType;
44  if (references[i].IdSymbol!=null && (symbolType = references[i].IdSymbol.SymbolType) != null)
45  // * We can erase it if...
46  if (!symbolType.HasTypeVariables() || // it doesn't have free variables
47  symbolType is FieldType || // it is a field
48  symbolType is MethodType || // it is a method
49  symbolType is ArrayType || // it is an array
50  symbolType is PropertyType // it is a property
51  )
52  references.RemoveAt(i);
53  }
54  }
55  #endregion
56 
57  #region CloneTypesOfReferences()
58  public static void CloneTypesOfReferences(IList<SingleIdentifierExpression> references, MethodType methodAnalyzed, IDictionary<SingleIdentifierExpression, TypeExpression> typeExpressions) {
65  IDictionary<int, TypeVariable> clonedTypeVariables = new Dictionary<int, TypeVariable>();
66  IList<EquivalenceClass> equivalenceClasses = new List<EquivalenceClass>();
67 
68  // * Clones each type
69  foreach (SingleIdentifierExpression singleId in references)
70  if (!typeExpressions.ContainsKey(singleId)) // * Previously cloned
71  if (singleId.IdSymbol == null || singleId.IdSymbol.SymbolType == null)
72  typeExpressions[singleId] = null;
73  else
74  typeExpressions[singleId] = singleId.IdSymbol.SymbolType.Clone(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
75 
76  // * Clones and updates the equivalence classes
77  CloneEquivalenceClasses(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
78  }
79  public static void CloneTypesOfReferences(IDictionary<SingleIdentifierExpression, TypeExpression> references, MethodType methodAnalyzed, IDictionary<SingleIdentifierExpression, TypeExpression> typeExpressions) {
80  IList<SingleIdentifierExpression> list = new List<SingleIdentifierExpression>();
81  foreach (KeyValuePair<SingleIdentifierExpression, TypeExpression> pair in references) {
82  pair.Key.IdSymbol.SymbolType = pair.Value;
83  list.Add(pair.Key);
84  }
85  CloneTypesOfReferences(list, methodAnalyzed, typeExpressions);
86  }
87  #endregion
88 
89  #region CloneEquivalenceClasses()
90  private static void CloneEquivalenceClasses(IDictionary<int, TypeVariable> clonedTypeVariables, IList<EquivalenceClass> equivalenceClasses, MethodType methodAnalyzed) {
96  // * Clones and updates the equivalence classes
97  foreach (EquivalenceClass oldEquivalenceClass in equivalenceClasses) {
98  EquivalenceClass newEquivalenceClass = new EquivalenceClass();
99  // * Clones the substitution
100  TypeExpression newSubstitution = null;
101  if (oldEquivalenceClass.Substitution != null)
102  newSubstitution = oldEquivalenceClass.Substitution.Clone(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
103  // * Updates the substitution to the cloned one
104  newEquivalenceClass.add(newSubstitution, SortOfUnification.Equivalent, new List<Pair<TypeExpression, TypeExpression>>());
105  foreach (int typeVariableNumber in oldEquivalenceClass.TypeVariables.Keys) {
106  // * Adds the cloned type variable to the new equivalence class
107  TypeVariable newTypeVariable = clonedTypeVariables[typeVariableNumber];
108  newEquivalenceClass.TypeVariables[newTypeVariable.Variable] = newTypeVariable;
109  // * Sets the class equivalence of the cloned type variable
110  newTypeVariable.EquivalenceClass = newEquivalenceClass;
111  clonedTypeVariables[typeVariableNumber].ValidTypeExpression = false;
112  }
113  }
114  }
115 
116  #endregion
117  #region CloneType()
118  public static TypeExpression CloneType(TypeExpression typeExpression, MethodType methodAnalyzed) {
125  IDictionary<int, TypeVariable> clonedTypeVariables = new Dictionary<int, TypeVariable>();
126  IList<EquivalenceClass> equivalenceClasses = new List<EquivalenceClass>();
127  TypeExpression newTypeExpression = typeExpression.Clone(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
128  CloneEquivalenceClasses(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
129  return newTypeExpression;
130  }
131  #endregion
132 
133  #region GetTypesOfReferences()
134  public static IDictionary<SingleIdentifierExpression, TypeExpression> GetTypesOfReferences(IList<SingleIdentifierExpression> references) {
140  IDictionary<SingleIdentifierExpression, TypeExpression> typeExpressions = new Dictionary<SingleIdentifierExpression, TypeExpression>();
141  foreach (SingleIdentifierExpression singleId in references)
142  if (singleId.IdSymbol!=null)
143  typeExpressions[singleId] = singleId.IdSymbol.SymbolType;
144  return typeExpressions;
145  }
146  #endregion
147 
148 
156  public static IDictionary<SingleIdentifierExpression, TypeExpression> Intersection(IDictionary<SingleIdentifierExpression, TypeExpression> setA, IList<SingleIdentifierExpression> setB) {
157  IDictionary<SingleIdentifierExpression, TypeExpression> typeExpressionIntersectionSet = new Dictionary<SingleIdentifierExpression, TypeExpression>();
158  foreach (KeyValuePair<SingleIdentifierExpression, TypeExpression> pair in setA)
159  if (setB.Contains(pair.Key))
160  typeExpressionIntersectionSet[pair.Key] = pair.Value;
161  return typeExpressionIntersectionSet;
162  }
163 
164 
165  #region SetTypesOfReferences()
166  public static void SetTypesOfReferences(IDictionary<SingleIdentifierExpression, TypeExpression> source, IList<SingleIdentifierExpression> destination) {
173  foreach (SingleIdentifierExpression singleId in destination)
174  if (source.ContainsKey(singleId))
175  singleId.IdSymbol.SymbolType = source[singleId];
176  }
177  #endregion
178 
179  #region SetUnionTypesOfReferences()
180  public static void SetUnionTypesOfReferences(IDictionary<SingleIdentifierExpression, TypeExpression> referencesBeforeIfElse,
191  IDictionary<SingleIdentifierExpression, TypeExpression> referencesAfterIf,
192  IDictionary<SingleIdentifierExpression, TypeExpression> referencesAfterElse,
193  MethodType methodAnalyzed, TypeExpression actualImplicitObject) {
194  IList<SingleIdentifierExpression> alreadyVisited = new List<SingleIdentifierExpression>();
195  foreach (KeyValuePair<SingleIdentifierExpression, TypeExpression> pair in referencesAfterIf) {
196  alreadyVisited.Add(pair.Key);
197  if (referencesAfterElse.ContainsKey(pair.Key))
198  // * Option 1
199  pair.Key.IdSymbol.SymbolType = UnionType.collect(pair.Value, referencesAfterElse[pair.Key]);
200  //pair.Key.IdSymbol.SymbolType.Assignment(UnionType.collect(pair.Value, referencesAfterElse[pair.Key]), AssignmentOperator.Assign, null, SortOfUnification.Override, null, "", 0, 0);
201  // * Option 2
202  pair.Key.IdSymbol.SymbolType = UnionType.collect(pair.Value, referencesBeforeIfElse[pair.Key]);
203  //pair.Key.IdSymbol.SymbolType.Assignment(UnionType.collect(pair.Value, referencesBeforeIfElse[pair.Key]), AssignmentOperator.Assign, null, SortOfUnification.Override, null, "", 0, 0);
204  }
205  foreach (KeyValuePair<SingleIdentifierExpression, TypeExpression> pair in referencesAfterElse) {
206  if (alreadyVisited.Contains(pair.Key))
207  continue;
208  alreadyVisited.Add(pair.Key);
209  // * Option 2
210  pair.Key.IdSymbol.SymbolType = UnionType.collect(pair.Value, referencesBeforeIfElse[pair.Key]);
211  //pair.Key.IdSymbol.SymbolType.Assignment(UnionType.collect(pair.Value, referencesBeforeIfElse[pair.Key]), AssignmentOperator.Assign, null, SortOfUnification.Override, null, "", 0, 0);
212  }
213  }
214  #endregion
215 
216 
227  public static void SetUnionTypesOfReferences(IDictionary<Block, IDictionary<SingleIdentifierExpression, TypeExpression>> typeExpressionsBeforeSwitch,
228  IDictionary<Block, IDictionary<SingleIdentifierExpression, TypeExpression>> typeExpressionsAfterCases,
229  IDictionary<SingleIdentifierExpression, TypeExpression> typeExpressionIntersectionSet,
230  MethodType methodAnalyzed, TypeExpression actualImplicitObject) {
231  // * We set all types to null
232  foreach (KeyValuePair<Block, IDictionary<SingleIdentifierExpression, TypeExpression>> pair1 in typeExpressionsBeforeSwitch)
233  foreach (KeyValuePair<SingleIdentifierExpression, TypeExpression> pair2 in pair1.Value)
234  pair2.Key.IdSymbol.SymbolType = null;
235 
236  // * We set the union types of all the references in a case body
237  foreach (KeyValuePair<Block, IDictionary<SingleIdentifierExpression, TypeExpression>> pair1 in typeExpressionsAfterCases)
238  foreach (KeyValuePair<SingleIdentifierExpression, TypeExpression> pair2 in pair1.Value)
239  pair2.Key.IdSymbol.SymbolType = UnionType.collect(pair2.Key.IdSymbol.SymbolType, pair2.Value);
240 
241  // * We add the initial type to all those symbols that were not used in all the cases
242  foreach (KeyValuePair<Block, IDictionary<SingleIdentifierExpression, TypeExpression>> pair1 in typeExpressionsBeforeSwitch)
243  foreach (KeyValuePair<SingleIdentifierExpression, TypeExpression> pair2 in pair1.Value)
244  if (typeExpressionIntersectionSet == null || !typeExpressionIntersectionSet.ContainsKey(pair2.Key))
245  pair2.Key.IdSymbol.SymbolType = UnionType.collect(pair2.Key.IdSymbol.SymbolType, pair2.Value);
246  }
247 
248  #region AssignAttributes()
249  public static void AssignAttributes(UserType classType, IList<TypeExpression> typesOfThisAfterCases,
257  MethodType methodAnalyzed, SortOfUnification unification, TypeExpression actualImplicitObject,
258  Location location) {
259  if (methodAnalyzed == null)
260  return;
261  foreach (KeyValuePair<string, AccessModifier> pair in classType.Fields) {
262  TypeExpression fieldType = pair.Value.Type;
263  TypeExpression unionType = null;
264  foreach (TypeExpression typeOfThis in typesOfThisAfterCases) {
265  TypeExpression eachFieldType = getFieldType(typeOfThis, pair.Key);
266  unionType = UnionType.collect(unionType, eachFieldType);
267  }
268  fieldType.AcceptOperation(new AssignmentOperation(unionType, AssignmentOperator.Assign, methodAnalyzed, unification, actualImplicitObject, location), null);
269  }
270  }
281  public static void AssignAttributes(UserType classType, TypeExpression typeOfThis1, TypeExpression typeOfThis2,
282  MethodType methodAnalyzed, SortOfUnification unification, TypeExpression actualImplicitObject,
283  Location location) {
284  if (methodAnalyzed == null)
285  return;
286  foreach (KeyValuePair<string, AccessModifier> pair in classType.Fields) {
287  TypeExpression fieldType = pair.Value.Type,
288  fieldType1 = getFieldType(typeOfThis1, pair.Key),
289  fieldType2 = getFieldType(typeOfThis2, pair.Key);
290  TypeExpression unionType = UnionType.collect(fieldType1, fieldType2);
291  fieldType.AcceptOperation(new AssignmentOperation(unionType, AssignmentOperator.Assign, methodAnalyzed, unification, actualImplicitObject, location), null);
292  }
293  }
294  private static TypeExpression getFieldType(TypeExpression type, string fieldName) {
295  ClassType classType = TypeExpression.As<ClassType>(type);
296  if (classType != null) {
297  if (!classType.Fields.ContainsKey(fieldName))
298  return null;
299  TypeExpression field= classType.Fields[fieldName].Type;
300  FieldType fieldType = TypeExpression.As<FieldType>(field);
301  if (fieldType == null)
302  return field;
303  return fieldType.FieldTypeExpression;
304  }
305  UnionType unionType = TypeExpression.As<UnionType>(type);
306  if (unionType != null) {
307  UnionType newUnionType = new UnionType();
308  foreach (TypeExpression typeInUnion in unionType.TypeSet) {
309  TypeExpression newType = SSAHelper.getFieldType(typeInUnion, fieldName);
310  newUnionType.AddType(newType);
311  }
312  return newUnionType;
313  }
314  return null;
315  }
316 
317  #endregion
318  }
319 }
Dictionary< string, AccessModifier > Fields
Gets the field list
Definition: UserType.cs:82
Representa a union type.
Definition: UnionType.cs:36
Encapsulates a block of statements.
Definition: Block.cs:34
TypeExpression Substitution
A equivalence class could be bounded to a unique no variable type
Representa an array type.
Definition: ArrayType.cs:35
This class encapsulates a location in a specific file. Implements an Inmutable pattern. So it can be used in any context, that is his internal fields never change.
Definition: Location.cs:24
IDictionary< int, TypeVariable > TypeVariables
All the type variables that must be substituted with the same value
Abstract class that represents all different types.
Represents a generic type expression
Definition: TypeVariable.cs:36
WriteType of a namespace
Encapsulates a identifier expression of our programming language.
Implements Double dispatcher Pattern. The class encapsulates encapsulates all it&#39;s needed to perform ...
virtual bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
Representa a property type.
Definition: PropertyType.cs:34
Representa a method type.
Definition: MethodType.cs:37
Symbol IdSymbol
Gets or sets the symbol of the identifier.
IList< TypeExpression > TypeSet
Gets the list of type expressions
Definition: UnionType.cs:57
Represents a class type.
Definition: ClassType.cs:35
Representa a field type.
Definition: FieldType.cs:37
static TypeExpression collect(TypeExpression collection, TypeExpression newType)
This static helper method group a newType into a union collection of types.
Definition: UnionType.cs:672
AssignmentOperator
Assignment binary operators
Represents a class or interface type.
Definition: UserType.cs:31