The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
ConstrainedDot.cs
Go to the documentation of this file.
1 using TypeSystem;
2 using AST;
3 using ErrorManagement;
4 using DynVarManagement;
5 using TypeSystem.Constraints;
6 using System.Collections.Generic;
7 //TODO: HAbrĂ¡ que ver que se hace con StringtYPE, con el NULL
8 namespace TypeSystem.Operations {
22  public override DotKind kindOfDot {
23  get { return DotKind.Constrained; }
24  }
25 
26  #region Fields
27  protected string memberName;
38  protected IList<TypeExpression> previousDot;
39  protected bool showErrorMessage;
43  protected Location location;
44 
45  #endregion
46 
47  #region Constructors
48  public ConstrainedDotOperation(string memberName, MethodType methodAnalyzed, IList<TypeExpression> previousDot, Location loc) {
56  this.memberName = memberName;
57  this.methodAnalyzed = methodAnalyzed;
58  this.previousDot = previousDot; // * We only save the reference to promote throughput.
59  this.location = loc;
60  }
61 
62  #endregion
63 
64  #region arrayType.member
65 
71  public override object Exec(ArrayType d, object arg) {
72  return d.AsClassType().AcceptOperation(this, arg);
73  }
74  #endregion
75 
76  #region BCLClassType.member
77  public override object Exec(BCLClassType d, object arg) {
85  TypeExpression member = (TypeExpression)d.AcceptOperation(new UnconstrainedDotOperation(this.memberName, this.previousDot), arg);
86  if (member == null)
87  ErrorManager.Instance.NotifyError(new UnknownMemberError(this.memberName, this.location));
88  return member;
89  }
90  #endregion
91 
92  #region BoolType.member
93 
101  public override object Exec(BoolType d, object arg) {
102  return d.AsClassType().AcceptOperation(this, arg);
103  }
104  #endregion
105 
106  #region CharType.member
107  public override object Exec(CharType d, object arg) {
108  return d.AsClassType().AcceptOperation(this, arg);
109  }
110  #endregion
111 
112  #region ClassType.member
113  public override object Exec(ClassType d, object arg) {
114  TypeExpression member = (TypeExpression)d.AcceptOperation(new UnconstrainedDotOperation(memberName, this.previousDot), arg);
115  if (member == null) {
116  ErrorManager.Instance.NotifyError(new UnknownMemberError(this.memberName, this.location));
117  return null;
118  }
119  if (!d.validAccess(member)) {
120  ErrorManager.Instance.NotifyError(new ProtectionLevelError(this.memberName, this.location));
121  return null;
122  }
123  return member;
124  }
125  #endregion
126 
127  #region ClassTypeProxy.member
128  public override object Exec(ClassTypeProxy d, object arg) {
129  return d.RealType.AcceptOperation(this, arg);
130  }
131  #endregion
132 
133  #region Double.member
134  public override object Exec(DoubleType d, object arg) {
135  return d.AsClassType().AcceptOperation(this, arg);
136  }
137  #endregion
138 
139  #region FieldType.member
140 
141  public override object Exec(FieldType d, object arg) {
142  if (d.FieldTypeExpression != null) {
143  // * If the field type is a dynamic union type, so it is the union
144  UnionType unionType = TypeExpression.As<UnionType>(d.FieldTypeExpression);
145  if (unionType != null)
146  DynVarOptions.Instance.AssignDynamism(d.FieldTypeExpression, d.IsDynamic);
147  return d.FieldTypeExpression.AcceptOperation(this, arg);
148  }
149  return null;
150  }
151  #endregion
152 
153  #region IntType.member
154  public override object Exec(IntType d, object arg) {
155  return d.AsClassType().AcceptOperation(this, arg);
156  }
157  #endregion
158 
159  #region Property.member
160  public override object Exec(PropertyType d, object arg) {
161  if (d.PropertyTypeExpression != null)
162  return d.PropertyTypeExpression.AcceptOperation(this, arg);
163  return null;
164  }
165  #endregion
166 
167  #region String.member
168  public override object Exec(StringType d, object arg) {
169  return d.AsClassType().AcceptOperation(this, arg);
170  }
171  #endregion
172 
173  #region TypeExpression.member
174  public override object Exec(TypeExpression d, object arg) {
175  return ReportError(d);
176  }
177  #endregion
178 
179  #region InterfaceType.member
180  // Try to find the appropriate attribute
181  public override object Exec(InterfaceType d, object arg) {
182  UnconstrainedDotOperation uo = new UnconstrainedDotOperation(this.memberName, this.previousDot);
183  TypeExpression member = (TypeExpression)d.AcceptOperation(uo, arg);
184  if (member == null)
185  // * Otherwise, error
186  ErrorManager.Instance.NotifyError(new UnknownMemberError(this.memberName, this.location));
187  return member;
188  }
189 
190  #endregion
191 
192  #region TypeVariable.member
193  public override object Exec(TypeVariable d, object arg) {
194  if (d.Substitution != null) {
195  DynVarOptions.Instance.AssignDynamism(d.Substitution, d.IsDynamic);
196  return d.Substitution.AcceptOperation(this, arg);
197  }
198  if (methodAnalyzed != null) {
199  // * A attribute access constraint is added to the method analyzed
200  DotConstraint constraint = new DotConstraint(d, this.memberName, this.location);
201  methodAnalyzed.AddConstraint(constraint);
202  return constraint.ReturnType;
203  }
204  ErrorManager.Instance.NotifyError(new OperationNotAllowedError(".", d.FullName, this.location));
205  return null;
206  }
207  #endregion
208 
209  #region UnionType.member
210  public override object Exec(UnionType d, object arg) {
211  // * Infinite loop detection
212  if (previousDot.Contains(d))
213  return new UnionType();
214  previousDot.Add(d);
215 
216  // * If all the types in typeset generate a constraint, we simply generate one constraint using the whole union type
217  if (d.IsFreshVariable() && methodAnalyzed != null) {
218  // * A constraint is added to the method analyzed
219  DotConstraint constraint = new DotConstraint(d, this.memberName, this.location);
220  methodAnalyzed.AddConstraint(constraint);
221  return constraint.ReturnType;
222  }
223  TypeExpression returnType = null;
224  foreach (TypeExpression type in d.TypeSet) {
225  TypeExpression ret;
226  if (!d.IsDynamic) {
227  // * Static Behaviour: All the types must accept the attribute access
228  ret = (TypeExpression)type.AcceptOperation(this, arg);
229  if (ret == null) {
230  return null;
231  }
232  } else
233  // * Dynamic Behaviour: Only one type must accept the attribute access
234  ret = (TypeExpression)type.AcceptOperation(new UnconstrainedDotOperation(this.memberName, previousDot), arg);
235  if (ret != null)
236  returnType = UnionType.collect(returnType, ret);
237  }
238  // * If it is a dynamic union, one type must accept the attribute access
239  if (returnType == null)
240  ErrorManager.Instance.NotifyError(new NoTypeHasMember(d.FullName, this.memberName, this.location));
241  return returnType;
242  }
243  #endregion
244 
245  #region Report Errors
246 
252  // in our case we only notify operations not allowed
253  // for other pruposes invoke explicitly another kind of error
254 
255  public override object ReportError(TypeExpression tE) {
256  if (this.showErrorMessage)
257  ErrorManager.Instance.NotifyError(new OperationNotAllowedError(".", tE.FullName, this.location));
258  return null;
259  }
260  #endregion
261 
262  }
263 }
bool validAccess(TypeExpression member)
Validates the correct access to members, taking into account the information hiding level...
Definition: ClassType.cs:262
override object Exec(ClassType d, object arg)
This class generatess constraits, and raises error if something is wrong. Implements a double dispatc...
override object AcceptOperation(TypeSystemOperation op, object arg)
override string FullName
The full name in type variables is calculated just in time
Representa a union type.
Definition: UnionType.cs:36
Represents a error produced when tries to make an operation not allowed for the specified type...
Representa an array type.
Definition: ArrayType.cs:35
override object Exec(InterfaceType d, object arg)
Represent a string type.
Definition: StringType.cs:36
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
override object Exec(PropertyType d, object arg)
override object Exec(BoolType d, object arg)
Delegate its behaviour to the BCLClassType, chaining its message to the later.
override object Exec(ArrayType d, object arg)
Delegate its behaviour to the BCLClassType, chaining its message to the later.
override object Exec(TypeExpression d, object arg)
Represents a interface type.
Represent a character type.
Definition: CharType.cs:38
override object Exec(DoubleType d, object arg)
Abstract class that represents all different types.
Represents a generic type expression
Definition: TypeVariable.cs:36
Represents a proxy of a class type. It implements the unfold operatations of theoretical type systes...
virtual string FullName
Gets the full name of the type Note: WriteType expression is the longest recursive representation of ...
override object ReportError(TypeExpression tE)
If showMessages is true it raises and error. It returns null
Implements a factory method pattern. Virtual constructor. Role: factory Implements a double dispatche...
Definition: DotOperation.cs:11
Represent a integer type.
Definition: IntType.cs:37
override object Exec(IntType d, object arg)
Location location
The location (file, line, column) of text being analyzed.
Represents a double type.
Definition: DoubleType.cs:36
TypeExpression FieldTypeExpression
Gets the field type.
Definition: FieldType.cs:58
override object Exec(ClassTypeProxy d, object arg)
virtual bool IsDynamic
Indicates if the type has been set as dynamic
MethodType methodAnalyzed
The method that is being analyzed when the operation is performed.
Represents a error produced when a dynamic union type has no valid type to be applied an operation ...
override bool IsFreshVariable()
To know if it is a type variable with no substitution
Definition: UnionType.cs:630
Representa a property type.
Definition: PropertyType.cs:34
Representa a method type.
Definition: MethodType.cs:37
override object AcceptOperation(TypeSystemOperation op, object arg)
override object Exec(CharType d, object arg)
override object Exec(TypeVariable d, object arg)
TypeExpression Substitution
Gets the substitution; null if it does not exist
Represent a bool type.
Definition: BoolType.cs:36
Represents a error produced when a member cannot be access due to its protection level.
TypeExpression PropertyTypeExpression
Gets the property type.
Definition: PropertyType.cs:64
Represents a class type.
Definition: ClassType.cs:35
IList< TypeExpression > previousDot
To detect infinite loops. The types that have been previously passed the dot message. Used for union types.
override object AcceptOperation(TypeSystemOperation op, object arg)
Definition: ClassType.cs:177
Representa a field type.
Definition: FieldType.cs:37
Represents a error produced when the attribute identifier is not defined.
override object Exec(UnionType d, object arg)
virtual object AcceptOperation(TypeSystemOperation op, object arg)
override object Exec(StringType d, object arg)
It represents constraints of the form: ret := op1 . memberName
override object Exec(FieldType d, object arg)