Пример #1
0
        private SitecoreService BuildSitecoreService(Type controllerType)
        {
            var controller = new TypeViewer(controllerType);

            var service = new SitecoreService
            {
                Name           = RemoveControllerSuffix(controllerType.FullName),
                Url            = GetRouteFromType(controllerType),
                Definition     = controller.ToJson(),
                CsrfProtection = controller.CheckForMitigations(ControllerType.WebAPI),
                Authorise      = controller.CheckForAuthorise(ControllerType.WebAPI)
            };

            var entityService = controllerType.GetGenericInterface(typeof(IEntityService <>));

            if (entityService != null)
            {
                var pocoObject = entityService.GetGenericArguments()[0];

                service.IsEntityService = true;
                service.Metadata        = GetMetadata(pocoObject);
            }

            return(service);
        }
Пример #2
0
        public void check_for_authorise_finds_derived_authorization_attributes()
        {
            var controllerViewer = new TypeViewer(typeof(AnalyticsDataController));

            controllerViewer.CheckForAuthorise(ControllerType.WebAPI)
            .ShouldBeTrue();
        }
Пример #3
0
        private static Controller BuildController(ControllerWrapper wrapper)
        {
            System.Diagnostics.Debug.Assert(wrapper.ControllerType.HasValue);

            var typeViewer = new TypeViewer(wrapper.Type);

            return(new Controller(
                       wrapper.Type.FullName,
                       wrapper.ControllerType.Value,
                       typeViewer.ToJson(),
                       typeViewer.CheckForMitigations(wrapper.ControllerType.Value),
                       typeViewer.CheckForAuthorise(wrapper.ControllerType.Value)));
        }
Пример #4
0
        public static bool CheckForAuthorise(this TypeViewer typeViewer, ControllerType controllerType)
        {
            var webApiAuthorizeAttributeName = typeof(System.Web.Http.AuthorizeAttribute).Name;

            var mvcAuthorizeAttributeName = typeof(System.Web.Mvc.AuthorizeAttribute).Name;

            var attributeToDetect = (controllerType == ControllerType.MVC)
                                    ? mvcAuthorizeAttributeName
                                    : webApiAuthorizeAttributeName;

            var classValidation  = typeViewer.HasClassAttribute(attributeToDetect);
            var methodValidation = typeViewer.HasMethodAttribute(attributeToDetect);

            return(classValidation || methodValidation);
        }
Пример #5
0
        public static Csrf CheckForMitigations(this TypeViewer typeViewer, ControllerType controllerType)
        {
            const string webApiAntiForgeryAttributeName = "ValidateHttpAntiForgeryTokenAttribute";

            var mvcAntiForgeryAttributeName = typeof(System.Web.Mvc.ValidateAntiForgeryTokenAttribute).Name;

            var attributeToDetect = (controllerType == ControllerType.MVC)
                        ? mvcAntiForgeryAttributeName
                        : webApiAntiForgeryAttributeName;

            var classValidation  = typeViewer.HasClassAttribute(attributeToDetect);
            var methodValidation = typeViewer.HasMethodAttribute(attributeToDetect);

            return(classValidation ? Csrf.Class
                : methodValidation?Csrf.Method
                   : Csrf.None);
        }
Пример #6
0
        private void ShowViewer(TypeViewer viewer, ResourceData data)
        {
#if !DEBUG
            try {
                viewer.RenderResource(data);
            } catch (AnolisException ex) {
                String exTemplate = "\r\nMessage:\r\n{0}\r\n\r\nStack Trace:\r\n{1}";
                String message    = "An unhandled exception was thrown whilst trying to load the resource.\r\n";

                Exception e = ex;
                while (e != null)
                {
                    message += String.Format(exTemplate, ex.Message, ex.StackTrace);
                    e        = e.InnerException;
                }

                DialogResult result = MessageBox.Show(this, message, "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error, MessageBoxDefaultButton.Button2);
                if (result == DialogResult.Cancel)
                {
                    return;
                }
                else
                {
                    ShowViewer(viewer, data);
                }
            }
#else
            viewer.RenderResource(data);
#endif

            // don't load it if it's already the currently displayed viewer
            if (_currentViewer != viewer)
            {
                viewer.Dock = DockStyle.Fill;

                __viewer.Controls.Clear();
                __viewer.Controls.Add(viewer);

                _currentViewer = viewer;
            }
        }
Пример #7
0
        private void __viewers_SelectionChangeCommitted(object sender, EventArgs e)
        {
            TypeViewer viewer = (__viewers.SelectedItem as TypeViewerWrapper).Viewer;

            ShowViewer(viewer, _data);
        }
Пример #8
0
 public virtual TypeNode GetStreamElementType(Expression x, TypeViewer typeViewer){
   x = this.GetInnerExpression(x);
   if (x == null) return null;
   if (x.NodeType == NodeType.Composition) x = ((Composition)x).Expression;
   if (x == null) return null;
   TypeNode xt = TypeNode.StripModifiers(x.Type);
   TypeNode t = this.GetCollectionElementType(xt, typeViewer);
   if (t != null && (t != SystemTypes.Object || xt == SystemTypes.IEnumerable)) return t;
   t = this.GetStreamElementType(xt, typeViewer);
   if (t != xt && t != SystemTypes.Object) return t;
   switch (x.NodeType){
     case NodeType.MethodCall:
     case NodeType.Call:
     case NodeType.Calli:
     case NodeType.Callvirt: {
       MethodCall mc = (MethodCall) x;
       MemberBinding mb = mc.Callee as MemberBinding;
       if (mb != null) {
         TypeNode mt = this.GetMemberElementType(mb.BoundMember, typeViewer);
         if (mt != null && mt != SystemTypes.Object) return mt;
       }
       break;
     }
     case NodeType.MemberBinding: {
       TypeNode mt = this.GetMemberElementType(((MemberBinding)x).BoundMember, typeViewer);
       if (mt != null && mt != SystemTypes.Object) return mt;
       break;
     }
   }
   return t;
 }
Пример #9
0
 public virtual Cardinality GetCardinality(Expression collection, TypeViewer typeViewer) {
   if (collection == null) return Cardinality.None;
   if (collection is Literal && collection.Type == SystemTypes.Type) {
     return Cardinality.One;
   }
   TypeNode type = collection.Type;
   TypeAlias ta = type as TypeAlias;
   if (ta != null) type = ta.AliasedType;
   Cardinality card = this.GetCardinality(type, typeViewer);
   if ((card == Cardinality.None || card == Cardinality.One) && 
     !(this.IsStructural(type) || type == SystemTypes.GenericNonNull)) {
     TypeNode elementType = this.GetStreamElementType(collection, typeViewer);
     if (elementType != type) {
       return Cardinality.ZeroOrMore;
     }     
   }
   return card;
 }
Пример #10
0
    /// <summary>
    /// Computes an upper bound in the type hierarchy for the set of argument types.
    /// This upper bound is a type that all types in the list are assignable to.
    /// If the types are all classes, then *the* least-upper-bound in the class
    /// hierarchy is returned.
    /// If the types contain at least one interface, then *a* deepest upper-bound
    /// is found from the intersection of the upward closure of each type.
    /// Note that if one of the types is System.Object, then that is immediately
    /// returned as the unified type without further examination of the list.
    /// </summary>
    /// <param name="ts">A list containing the set of types from which to compute the unified type.</param>
    /// <returns>The type corresponding to the least-upper-bound.</returns>
    public virtual TypeNode UnifiedType(TypeNodeList ts, TypeViewer typeViewer){
      if (ts == null || ts.Count == 0) return null;
      TypeNode unifiedType = SystemTypes.Object; // default unified type
      bool atLeastOneInterface = false;
      #region If at least one of the types is System.Object, then that is the unified type
      for (int i = 0, n = ts.Count; i < n; i++){
        TypeNode t = this.Unwrap(ts[i]);
        if (t == SystemTypes.Object){
          return SystemTypes.Object;
        }
      }
      #endregion If at least one of the types is System.Object, then that is the unified type
      // assert forall{TypeNode t in ts; t != SystemTypes.Object};
      #region See if any of the types are interfaces
      for (int i = 0, n = ts.Count; i < n; i++){
        TypeNode t = this.Unwrap(ts[i]);
        if (t.NodeType == NodeType.Interface){
          atLeastOneInterface = true;
          break;
        }
      }
      #endregion See if any of the types are interfaces

      #region Find the LUB in the class hierarchy (if there are no interfaces)
      if (!atLeastOneInterface){
        TrivialHashtable h = new TrivialHashtable(ts.Count);
        // Create the list [s, .., t] for each element t of ts where for each item
        // in the list, t_i, t_i = t_{i+1}.BaseType. (s.BaseType == SystemTypes.Object)
        // Store the list in a hashtable keyed by t.
        // Do this only for classes. Handle interfaces in a different way because of
        // multiple inheritance.
        for (int i = 0, n = ts.Count; i < n; i++){
          TypeNodeList tl = new TypeNodeList();
          TypeNode t = this.Unwrap(ts[i]);
          tl.Add(t);
          TypeNode t2 = t.BaseType;
          while (t2 != null && t2 != SystemTypes.Object){ // avoid including System.Object in the list for classes
            tl.Insert(t2,0);
            t2 = this.Unwrap(t2.BaseType);
          }
          h[ts[i].UniqueKey] = tl;
        }
        bool stop = false;
        int depth = 0;
        while (!stop){
          TypeNode putativeUnifiedType = null;
          int i = 0;
          int n = ts.Count;
          putativeUnifiedType = ((TypeNodeList) h[ts[0].UniqueKey])[depth];
          while (i < n){
            TypeNode t = ts[i];
            TypeNodeList subTypes = (TypeNodeList) h[t.UniqueKey];
            if (subTypes.Count <= depth || subTypes[depth] != putativeUnifiedType){
              // either reached the top of the hierarchy for t_i or it is on a different branch
              // than the current one.
              stop = true;
              break;
            }
            i++;
          }
          if (i == n){ // made it all the way through: all types are subtypes of the current one
            unifiedType = putativeUnifiedType;
          }
          depth++;
        }
      }
      #endregion Find the LUB in the class hierarchy (if there are no interfaces)
      #region Find *a* LUB in the interface hierarchy (if there is at least one interface or current LUB is object)
      if (unifiedType == SystemTypes.Object || atLeastOneInterface){
        TrivialHashtable interfaces = new TrivialHashtable();
        for (int i = 0, n = ts.Count; i < n; i++){
          InterfaceList il = new InterfaceList();
          interfaces[ts[i].UniqueKey] = il;
          this.SupportedInterfaces(ts[i],il,typeViewer); // side-effect: il gets added to
        }
        // interfaces[ts[i]] is the upward closure of all of the interfaces supported by ts[i]
        // compute the intersection of all of the upward closures
        // might as well start with the first type in the list ts
        InterfaceList intersection = new InterfaceList();
        InterfaceList firstIfaceList = (InterfaceList)interfaces[ts[0].UniqueKey];
        for (int i = 0, n = firstIfaceList.Count; i < n; i++){
          Interface iface = firstIfaceList[i];
          bool found = false;
          int j = 1; // start at second type in the list ts
          while (j < ts.Count){
            InterfaceList cur = (InterfaceList)interfaces[ts[j].UniqueKey];
            found = false;
            for (int k = 0, p = cur.Count; k < p; k++){
              if (cur[k] == iface){
                found = true;
                break;
              }
            }
            if (!found){
              // then the j-th type doesn't support iface, don't bother looking in the rest
              break;
            }
            j++;
          }
          if (found){
            intersection.Add(iface);
          }
        }
        // TODO: take the "deepest" interface in the intersection.
        // "deepest" means that if any other type in the intersection is a subtype
        // of it, then *don't* consider it.
        if (intersection.Count > 0){
          InterfaceList finalIntersection = new InterfaceList(intersection.Count);
          Interface iface = intersection[0];
          for (int i = 0, n = intersection.Count; i < n; i++){
            Interface curFace = intersection [i];
            int j = 0;
            int m = intersection.Count;
            while (j < m){
              if (j != i){
                Interface jFace = intersection[j];
                if (TypeViewer.GetTypeView(typeViewer, jFace).IsAssignableTo(curFace))
                  break;
              }
              j++;
            }
            if (j == m){ // made it all the way through, no other iface is a subtype of curFace
              finalIntersection.Add(curFace);
            }
          }
          if (finalIntersection.Count > 0){
            unifiedType = finalIntersection[0]; // heuristic: just take the first one
          }
        }
      }
      #endregion Find *a* LUB in the interface hierarchy (if there is at least one interface or current LUB is object)
      return unifiedType;
    }
Пример #11
0
 public virtual TypeNode GetStreamElementType(TypeNode t, TypeViewer typeViewer){
   TypeNode originalT = t;
   TypeAlias ta = t as TypeAlias;
   while (ta != null) { t = ta.AliasedType; ta = t as TypeAlias; }
   if (t == null) return null;
   ArrayType aType = t as ArrayType; //REVIEW: should [] and {} participate in this?
   if (aType != null) return aType.ElementType;
   TypeNode template = t.Template;
   if (template == SystemTypes.GenericIEnumerable || template == SystemTypes.GenericIEnumerator || template == SystemTypes.GenericIList ||
     template == SystemTypes.GenericList || template == SystemTypes.GenericNonEmptyIEnumerable ||
     template == SystemTypes.GenericBoxed || template == SystemTypes.GenericNonNull || template == SystemTypes.GenericInvariant){
     if (t.TemplateArguments != null && t.TemplateArguments.Count > 0)
       return t.TemplateArguments[0];
   }
   if (TypeViewer.GetTypeView(typeViewer, t).IsAssignableTo(SystemTypes.Range)) return SystemTypes.Int32;
   if (TypeViewer.GetTypeView(typeViewer, t).IsAssignableTo(SystemTypes.IList)) return SystemTypes.Object;
   if (TypeViewer.GetTypeView(typeViewer, t).IsAssignableTo(SystemTypes.IDictionary)) return SystemTypes.Object;
   if (t is Interface) return originalT;
   InterfaceList ifaces = TypeViewer.GetTypeView(typeViewer, t).Interfaces;
   for (int i = 0, n = ifaces == null ? 0 : ifaces.Count; i < n; i++){
     Interface iface = ifaces[i];
     if (iface == null) continue;
     TypeNode eType = this.GetStreamElementType(iface, typeViewer);
     if (eType != iface) return eType;
   }
   return originalT;
   
 }
Пример #12
0
 public virtual Literal ImplicitLiteralCoercion(Literal lit, TypeNode sourceType, TypeNode targetType, TypeViewer typeViewer) {
   try{
     object val = System.Convert.ChangeType(lit.Value, targetType.TypeCode);
     return new Literal(val, targetType);
   }catch(InvalidCastException){
   }catch(OverflowException){
   }catch(FormatException){}
   this.HandleError(lit, Error.NoImplicitCoercionFromConstant, lit.SourceContext.SourceText, this.GetTypeName(targetType));
   return null;
 }
Пример #13
0
 /// <summary>
 /// Returns true if conversion from t3 to t1 exists and is better (closer) than the conversion from t3 to t2
 /// Call this only if both conversions exist.
 /// </summary>
 public virtual bool IsBetterMatch(TypeNode t1, TypeNode t2, TypeNode t3, TypeViewer typeViewer){
   if (t1 == null) return false;
   if (t2 == null || t2 == TypeSystem.DoesNotMatchAnyType) return true; //this type always loses
   if (t1 == t2) return false;
   if (t1 == t3) return true; //t2 is different from t3 while t1 == t3, so t1 must be a better match
   if (t2 == t3) return false; //t1 is different from t3, while t2 == t3, so t1 cannot be a better match
   //t3 can go to t1 and t2 only via conversions. Try to establish which conversion is better (closer).
   bool t1tot2 = this.ImplicitCoercionFromTo(t1, t2, typeViewer);
   bool t2tot1 = this.ImplicitCoercionFromTo(t2, t1, typeViewer);
   if (t1tot2 && !t2tot1) return this.ImplicitCoercionFromTo(t3, t1, typeViewer); //Can get from t3 to t2 via t1, but can't get from t3 to t1 via t2, so t3 is closer to t1
   if (t2tot1 && !t1tot2) return !this.ImplicitCoercionFromTo(t3, t2, typeViewer); //Get get from t3 to t1 via t2, but can't get from t3 to t2 via t1, so t2 is closer to t1
   //Special rule for integer types:
   //Prefer conversions to signed integers over conversions to unsigned integers.
   //But always prefer smaller int over larger int.
   switch (t1.TypeCode){
     case TypeCode.SByte:
       switch (t2.TypeCode){
         case TypeCode.Byte:
         case TypeCode.UInt16:
         case TypeCode.UInt32:
         case TypeCode.UInt64:
         case TypeCode.Int16:
         case TypeCode.Int32:
         case TypeCode.Int64:
           return true;
       }
       break;
     case TypeCode.Byte:
       switch (t2.TypeCode){
         case TypeCode.UInt16:
         case TypeCode.UInt32:
         case TypeCode.UInt64:
           return true;
         case TypeCode.SByte:
         case TypeCode.Int16:
         case TypeCode.Int32:
         case TypeCode.Int64:
           return false;
       }
       break;
     case TypeCode.Int16:
       switch (t2.TypeCode){
         case TypeCode.Byte:
         case TypeCode.UInt16:
         case TypeCode.UInt32:
         case TypeCode.UInt64:
         case TypeCode.Int32:
         case TypeCode.Int64:
           return true;  
         case TypeCode.SByte:
           return false;
       }
       break;
     case TypeCode.UInt16:
       switch (t2.TypeCode){
         case TypeCode.UInt32:
         case TypeCode.UInt64:
           return true;  
         case TypeCode.Byte:
         case TypeCode.SByte:
         case TypeCode.Int16:
         case TypeCode.Int32:
         case TypeCode.Int64:
           return false;
       }
       break;
     case TypeCode.Int32:
       switch (t2.TypeCode){
         case TypeCode.Byte:
         case TypeCode.UInt16:
         case TypeCode.UInt32:
         case TypeCode.UInt64:
         case TypeCode.Int64:
           return true;
         case TypeCode.SByte:
         case TypeCode.Int16:
           return false;
       }
       break;
     case TypeCode.UInt32:
       switch (t2.TypeCode){
         case TypeCode.UInt64:
           return true;
         case TypeCode.Byte:
         case TypeCode.UInt16:
         case TypeCode.SByte:
         case TypeCode.Int16:
         case TypeCode.Int32:
         case TypeCode.Int64:
           return false;
       }
       break;
     case TypeCode.Int64:
       switch (t2.TypeCode){
         case TypeCode.Byte:
         case TypeCode.UInt16:
         case TypeCode.UInt32:
         case TypeCode.UInt64:
           return true;
         case TypeCode.SByte:
         case TypeCode.Int16:
         case TypeCode.Int32:
           return false;
       }
       break;
     case TypeCode.UInt64:
       switch (t2.TypeCode){
         case TypeCode.Byte:
         case TypeCode.UInt16:
         case TypeCode.UInt32:
         case TypeCode.SByte:
         case TypeCode.Int16:
         case TypeCode.Int32:
         case TypeCode.Int64:
           return false;
       }
       break;
   }
   if (!t1.IsValueType && t2.IsValueType && t3 == SystemTypes.Object) return true;
   if (t1 is Pointer && !(t2 is Pointer) && t3 is Pointer && ((Pointer)t3).ElementType == SystemTypes.Void)
     return true;
   return false;
 }
Пример #14
0
 protected virtual Expression StandardImplicitCoercion(Expression source, bool sourceIsNonNullType, TypeNode sourceType, bool targetIsNonNullType, TypeNode targetType, TypeNode originalTargetType, TypeViewer typeViewer){
   if (Literal.IsNullLiteral(source)) {
     if (this.IsNullableType(targetType)) {
       Local temp = new Local(targetType);
       StatementList statements = new StatementList();
       BlockExpression result = new BlockExpression(new Block(statements));
       statements.Add(new AssignmentStatement(new AddressDereference(new UnaryExpression(temp, NodeType.AddressOf), targetType), new Literal(null, CoreSystemTypes.Object)));
       statements.Add(new ExpressionStatement(temp));
       return result;
     }
     if (targetType.IsTemplateParameter && !targetType.IsReferenceType) {
       // Check for reference constraint
       this.HandleError(source, Error.TypeVarCantBeNull, targetType.Name.Name);
       return new Local(targetType);
     }
   }
   //Identity coercion
   if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))) return source;
   ITypeParameter stp = sourceType as ITypeParameter;
   ITypeParameter ttp = targetType as ITypeParameter;
   if (stp != null && ttp != null && stp.ParameterListIndex == ttp.ParameterListIndex && stp.DeclaringMember == ttp.DeclaringMember &&
     (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))) return source;
   if (source is This && targetType != null && sourceType == targetType.Template && targetType.IsNotFullySpecialized)
     //TODO: add check for sourceType.TemplateParameters == targetType.TemplateArguments
     return source;
   //Dereference source
   Reference sr = sourceType as Reference;
   if (sr != null){
     sourceType = sr.ElementType;
     Pointer pType = targetType as Pointer;
     if (pType != null && this.StandardImplicitCoercionFromTo(null, sourceType, pType.ElementType, typeViewer))
       return source;
     else if (pType != null && pType.ElementType == SystemTypes.Void)
       return source;
     bool sourceIsThis = source is This;
     source = new AddressDereference(source, sourceType, source.SourceContext);
     source.Type = sourceType;
     sourceIsNonNullType = this.IsNonNullType(sourceType);
     sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NonNullType);
     //Special case for coercion of this in template class
     if (sourceIsThis && targetType != null && sourceType == targetType.Template && targetType.IsNotFullySpecialized)
       //TODO: add check for sourceType.TemplateParameters == targetType.TemplateArguments
       return source;
   }
   //Identity coercion after dereference
   if (sourceType == targetType && (!targetIsNonNullType || (targetIsNonNullType == sourceIsNonNullType))) return source;
   //Special case for null literal
   if (Literal.IsNullLiteral(source)){
     if (targetIsNonNullType) 
       return ImplicitNonNullCoercion(this.ErrorHandler, source, originalTargetType);
     if (targetType is ITypeParameter && this.useGenerics)
       return new BinaryExpression(source, new Literal(targetType, SystemTypes.Type), NodeType.UnboxAny);
     if (!targetType.IsValueType || targetType.Template == SystemTypes.GenericBoxed)
       return new Literal(null, targetType, source.SourceContext);
     if (this.IsNullableType(targetType))
       return new Local(StandardIds.NewObj, targetType, source.SourceContext);
     TypeAlias tAlias = targetType as TypeAlias;
     if (tAlias != null){
       if (tAlias.RequireExplicitCoercionFromUnderlyingType) return null;
       source = this.ImplicitCoercion(source, tAlias.AliasedType, typeViewer);
       if (source == null) return null;
       Method coercion = this.UserDefinedImplicitCoercionMethod(source, tAlias.AliasedType, targetType, false, typeViewer);
       if (coercion != null){
         ExpressionList args = new ExpressionList(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
         return new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType);
       }
     }else{
       Method coercion = this.UserDefinedImplicitCoercionMethod(source, source.Type, targetType, true, typeViewer);
       if (coercion != null){
         ExpressionList args = new ExpressionList(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
         return new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType);
       }
     }
     this.HandleError(source, Error.CannotCoerceNullToValueType, this.GetTypeName(targetType));
     return new Local(targetType);
   }
   //Special case for string literal
   if (source.NodeType == NodeType.Literal && sourceType == SystemTypes.String &&
       (targetType.Template == SystemTypes.GenericNonNull || targetType.Template == SystemTypes.GenericInvariant) && 
       this.GetStreamElementType(targetType, typeViewer) == SystemTypes.String)
       return this.ExplicitCoercion(source, targetType, typeViewer);
   //Implicit numeric coercions + implicit enumeration coercions + implicit constant expression coercions
   if (sourceType.IsPrimitive && sourceType != SystemTypes.String && (targetType.IsPrimitive || targetType == SystemTypes.Decimal || targetType is EnumNode)){
     Expression primitiveCoercion = this.ImplicitPrimitiveCoercion(source, sourceType, targetType, typeViewer);
     if (primitiveCoercion != null) return primitiveCoercion;
   }
   //Implicit coercion from string literal to numbers or eums
   if (this.allowStringLiteralToOtherPrimitiveCoercion && sourceType == SystemTypes.String && (targetType.IsPrimitive || targetType == SystemTypes.Decimal || targetType is EnumNode)){
     Expression primitiveCoercion = this.ImplicitPrimitiveCoercion(source, sourceType, targetType, typeViewer);
     if (primitiveCoercion != null) return primitiveCoercion;
   }
   
   //Implicit reference coercions
   if (TypeViewer.GetTypeView(typeViewer, sourceType).IsAssignableTo(targetType)){
     if (targetIsNonNullType && !(sourceIsNonNullType) && !sourceType.IsValueType) {
       //Handling for non null types
       return ImplicitNonNullCoercion(this.ErrorHandler, source, originalTargetType);
     }else if (sourceType.IsValueType && !targetType.IsValueType){
       if (sourceType.NodeType == NodeType.TypeUnion){
         Debug.Assert(targetType == SystemTypes.Object);
         return this.CoerceTypeUnionToObject(source, typeViewer);
       }
       if (sourceType is TupleType){
         if (targetType == SystemTypes.Object)
           return this.TupleCoercion(source, sourceType, targetType, false, typeViewer);
       }else if (targetType.Template != SystemTypes.GenericIEnumerable && this.GetStreamElementType(sourceType, typeViewer) != sourceType)
         return this.ExplicitCoercion(this.CoerceStreamToObject(source, sourceType, typeViewer), targetType, typeViewer);
       Expression e = new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, targetType, source.SourceContext);
       e.Type = targetType;
       return e;
     }else if (this.useGenerics && (sourceType is TypeParameter || sourceType is ClassParameter)){
       source = new BinaryExpression(source, new MemberBinding(null, sourceType), NodeType.Box, sourceType);
       if (targetType == SystemTypes.Object) return source;
       return new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.UnboxAny, targetType);
     }
     else if (this.useGenerics && sourceType is ArrayType) {
       ArrayType sat = (ArrayType)sourceType;
       while (sat.ElementType is ArrayType) sat = (ArrayType)sat.ElementType;
       if (sat.ElementType is ITypeParameter)
         return new BinaryExpression(source, new MemberBinding(null, targetType), NodeType.Castclass, targetType, source.SourceContext);
       return source;
     }else
       return source;
   }
   //Special case for delegates
   if (targetType is DelegateNode)
     return this.CoerceToDelegate(source, sourceType, (DelegateNode)targetType, false, typeViewer);
   //Special case for type union to common base type
   if (sourceType.NodeType == NodeType.TypeUnion)
     return this.CoerceFromTypeUnion(source, (TypeUnion)sourceType, targetType, false, originalTargetType, typeViewer);
   //Special case for Type intersection target type
   if (targetType.NodeType == NodeType.TypeIntersection)
     return this.CoerceToTypeIntersection(source, sourceType, (TypeIntersection)targetType, false, typeViewer);
   //Special cases for typed streams
   Expression streamCoercion = this.StreamCoercion(source, sourceType, targetType, false, originalTargetType, typeViewer);
   if (streamCoercion != null) return streamCoercion;
   //Implicit tuple coercions
   return this.TupleCoercion(source, sourceType, targetType, false, typeViewer);
 }
Пример #15
0
 public virtual Expression TupleCoercion(Expression source, TypeNode sourceType, TypeNode targetType, bool explicitCoercion, TypeViewer typeViewer){
   TupleType sTuple = sourceType as TupleType;
   TupleType tTuple = targetType as TupleType; 
   if (sTuple == null){
     if (!explicitCoercion) return null;
     if (tTuple == null) return null;
     MemberList tMems = tTuple.Members;
     if (tMems == null || tMems.Count != 3) return null;
     ConstructTuple consTuple = new ConstructTuple();
     consTuple.Type = tTuple;
     Field f = (Field)tMems[0].Clone();
     consTuple.Fields = new FieldList(f);
     if (f.Type is TypeAlias)
       f.Initializer = this.ExplicitCoercion(source, f.Type, typeViewer);
     else
       f.Initializer = this.StandardExplicitCoercion(source, this.IsNonNullType(sourceType), sourceType, this.IsNonNullType(f.Type), f.Type, f.Type, typeViewer);
     if (f.Initializer == null) return null;
     return consTuple;
   }
   MemberList sMembers = sTuple.Members;
   if (sMembers == null) return null;
   int n = sMembers.Count;
   if (tTuple == null){
     if (n == 3){
       TypeUnion tUnion = targetType as TypeUnion;
       if (tUnion != null){
         Method coercion = this.UserDefinedImplicitCoercionMethod(source, sourceType, targetType, true, typeViewer);
         if (coercion != null) 
           return new MethodCall(new MemberBinding(null, coercion), new ExpressionList(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer)), 
             NodeType.Call, coercion.ReturnType, source.SourceContext);
       }
       Field sField = sMembers[0] as Field;
       if (sField == null || (!explicitCoercion && !this.ImplicitCoercionFromTo(sField.Type, targetType, typeViewer))) return null;
       if (!sField.IsAnonymous && targetType == SystemTypes.Object)
         return new BinaryExpression(source, new MemberBinding(null, sTuple), NodeType.Box, SystemTypes.Object);
       ConstructTuple cTuple = source as ConstructTuple;
       if (cTuple != null){
         //TODO: give a warning
         source = cTuple.Fields[0].Initializer;
       }else{
         MemberBinding mb = new MemberBinding(new UnaryExpression(source, NodeType.AddressOf), sField);
         mb.Type = sField.Type;
         source = mb;
       }
       if (explicitCoercion)
         return this.ExplicitCoercion(source, targetType, typeViewer);
       else
         return this.ImplicitCoercion(source, targetType, typeViewer);
     }
     if (targetType == SystemTypes.Object)
       return new BinaryExpression(source, new MemberBinding(null, sTuple), NodeType.Box, SystemTypes.Object);
     return null;
   }
   MemberList tMembers = tTuple.Members;
   if (sMembers == tMembers) return source;
   if (tMembers == null) return null;
   if (n != tMembers.Count) return null;
   n-=2;
   ConstructTuple consTup = source as ConstructTuple;
   if (consTup != null){
     FieldList consFields = consTup.Fields;
     for (int i = 0; i < n; i++){
       Field cField = consFields[i];
       if (cField == null) continue;
       Field tField = tMembers[i] as Field;
       if (tField == null) return null;
       if (explicitCoercion)
         cField.Initializer = this.ExplicitCoercion(cField.Initializer, tField.Type, typeViewer);
       else{
         if (!tField.IsAnonymous && tField.Name != null && 
           (cField.IsAnonymous || cField.Name == null || cField.Name.UniqueIdKey != tField.Name.UniqueIdKey)) return null;
         cField.Initializer = this.ImplicitCoercion(cField.Initializer, tField.Type, typeViewer);
       }
       if (cField.Initializer == null) return null;
       cField.Type = tField.Type;
     }
     consTup.Type = tTuple;
     return consTup;
   }
   Local loc = new Local(sTuple);
   CoerceTuple cTup = new CoerceTuple();
   cTup.OriginalTuple = source;
   cTup.Temp = loc;
   cTup.Type = tTuple;
   FieldList cFields = cTup.Fields = new FieldList(n);
   for (int i = 0; i < n; i++){
     Field sField = sMembers[i] as Field;
     if (sField == null) return null;
     Field tField = tMembers[i] as Field;
     if (tField == null) return null;
     Field cField = new Field();
     cField.Type = tField.Type;
     MemberBinding mb = new MemberBinding(loc, sField);
     if (explicitCoercion)
       cField.Initializer = this.ExplicitCoercion(mb, tField.Type, typeViewer);
     else{
       if (!tField.IsAnonymous && tField.Name != null && 
         (sField.IsAnonymous || sField.Name == null || sField.Name.UniqueIdKey != tField.Name.UniqueIdKey)) return null;
       cField.Initializer = this.ImplicitCoercion(mb, tField.Type, typeViewer);
     }
     if (cField.Initializer == null) return null;
     cFields.Add(cField);
   }
   return cTup;
 }
Пример #16
0
    public virtual Expression ImplicitCoercion(Expression source, TypeNode targetType, TypeViewer typeViewer){
      TypeNode originalTargetType = targetType;
      if (targetType == null || targetType.Name == Looker.NotFound) return source;
      if (source == null) return null;
      //HS D
      if (source is Hole)
          {
              source.Type = targetType;
              return source;
          }
      //HS D
      if (source is LambdaHole)
          {
              if (targetType == SystemTypes.Boolean)
                  source = new LambdaHole(source, new Literal(0), NodeType.Ge, source.SourceContext);                      
              source.Type = targetType;
              return source;
          }
      Literal sourceLit = source as Literal;
      if (sourceLit != null && sourceLit.Value is TypeNode){
        this.HandleError(source, Error.TypeInVariableContext, this.GetTypeName((TypeNode)sourceLit.Value), "class", "variable");
        return null;
      }
      //Ignore parentheses
      if (source.NodeType == NodeType.Parentheses){
        UnaryExpression uex = (UnaryExpression)source;
        uex.Operand = this.ImplicitCoercion(uex.Operand, targetType, typeViewer);
        if (uex.Operand == null) return null;
        uex.Type = uex.Operand.Type;
        return uex;
      }
      bool targetIsNonNullType = this.IsNonNullType(targetType);
      targetType = TypeNode.StripModifier(targetType, SystemTypes.NonNullType);
      targetType = TypeNode.StripModifier(targetType, SystemTypes.NullableType);
      //TODO: handle SkipCheck and EnforceCheck
      //Special case for closure expressions
      if (source.NodeType == NodeType.AnonymousNestedFunction)
        return this.CoerceAnonymousNestedFunction((AnonymousNestedFunction)source, targetType, false, typeViewer);
      TypeNode sourceType = source.Type;
      if (sourceType == null) sourceType = SystemTypes.Object;
      bool sourceIsNonNullType = this.IsNonNullType(source.Type);
      sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NonNullType);
      sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NullableType);
      if (sourceType == SystemTypes.String && !sourceIsNonNullType && source is Literal)
        sourceIsNonNullType = ((Literal)source).Value != null;
      if (this.currentParameter != null && targetType is Reference){
        UnaryExpression uex = source as UnaryExpression;
        if (uex != null){
          if (sourceIsNonNullType && !targetIsNonNullType){
            string ttypeName = this.GetTypeName(targetType);
            string stypeName = this.GetTypeName(source.Type);
            this.HandleError(source, Error.NoImplicitCoercion, stypeName, ttypeName);
            return null;
          }
          if (!sourceIsNonNullType && targetIsNonNullType){
            string ttypeName = this.GetTypeName(targetType);
            string stypeName = this.GetTypeName(source.Type);
            this.HandleError(source, Error.NoImplicitCoercion, stypeName, ttypeName);
            return null;
          }
          if (uex.NodeType == NodeType.OutAddress){
            if ((this.currentParameter.Flags & ParameterFlags.Out) == 0){
              this.currentParameter.Flags |= ParameterFlags.Out;
              string stypeName = this.GetTypeName(sourceType);
              this.currentParameter.Flags &= ~ParameterFlags.Out;
              this.HandleError(source, Error.NoImplicitCoercion, stypeName, this.GetTypeName(targetType));
              return null;
            }
          }else if (uex.NodeType == NodeType.RefAddress){
            if ((this.currentParameter.Flags & ParameterFlags.Out) != 0){
              this.currentParameter.Flags &= ~ParameterFlags.Out;
              string stypeName = this.GetTypeName(sourceType);
              this.currentParameter.Flags |= ParameterFlags.Out;
              this.HandleError(source, Error.NoImplicitCoercion, stypeName, this.GetTypeName(targetType));
              return null;
            }
          }
        }
      }
      Expression result = this.StandardImplicitCoercion(source, sourceIsNonNullType, sourceType, targetIsNonNullType, targetType, originalTargetType, typeViewer);
      if (result != null) return result;
      Method coercion = this.UserDefinedImplicitCoercionMethod(source, sourceType, targetType, true, typeViewer);
      if (coercion != null){
        if (this.IsNullableType(targetType) && this.IsNullableType(sourceType) && !this.IsNullableType(coercion.Parameters[0].Type))
          return this.CoerceWithLiftedCoercion(source, sourceType, targetType, coercion, false, typeViewer);
        ExpressionList args = new ExpressionList(1);
        args.Add(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
        return this.ImplicitCoercion(new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType, source.SourceContext), targetType, typeViewer);
      }
      if (sourceType == SystemTypes.Type && source is Literal)
        this.HandleError(source, Error.TypeInVariableContext, this.GetTypeName((TypeNode)((Literal)source).Value), "class", "variable");
      else if (this.IsNullableType(sourceType) && this.IsNullableType(targetType) && this.ImplicitCoercionFromTo(this.RemoveNullableWrapper(sourceType), this.RemoveNullableWrapper(targetType))) {
        TypeNode usType = this.RemoveNullableWrapper(sourceType);
        TypeNode utType = this.RemoveNullableWrapper(targetType);

        Local tempSrc = new Local(sourceType);
        Local tempTar = new Local(targetType);
        StatementList statements = new StatementList();
        BlockExpression result1 = new BlockExpression(new Block(statements));
        statements.Add(new AssignmentStatement(tempSrc, source));

        Method hasValue = sourceType.GetMethod(StandardIds.getHasValue);
        Method getValueOrDefault = sourceType.GetMethod(StandardIds.GetValueOrDefault);
        Method ctor = targetType.GetMethod(StandardIds.Ctor, utType);
        Block pushValue = new Block();
        Block done = new Block();

        Expression tempHasValue = new MethodCall(new MemberBinding(new UnaryExpression(tempSrc, NodeType.AddressOf), hasValue), null);
        tempHasValue.Type = SystemTypes.Boolean;
        statements.Add(new Branch(tempHasValue, pushValue));
        statements.Add(new AssignmentStatement(new AddressDereference(new UnaryExpression(tempTar, NodeType.AddressOf), targetType), new Literal(null, CoreSystemTypes.Object)));
        statements.Add(new Branch(null, done));
        statements.Add(pushValue);
        Expression value = new MethodCall(new MemberBinding(new UnaryExpression(tempSrc, NodeType.AddressOf), getValueOrDefault), null);
        value.Type = usType;
        value = this.ImplicitCoercion(value, utType);
        Construct cons = new Construct(new MemberBinding(null, ctor), new ExpressionList(value));
        result1.Type = ctor.DeclaringType;
        statements.Add(new AssignmentStatement(tempTar, cons));
        statements.Add(done);

        statements.Add(new ExpressionStatement(tempTar));
        return result1;
      }else
        this.HandleError(source, Error.NoImplicitCoercion, this.GetTypeName(sourceType), this.GetTypeName(originalTargetType));
      return null;
    }
Пример #17
0
 public virtual Expression CoerceWithLiftedCoercion(Expression source, TypeNode sourceType, TypeNode targetType, Method coercion, bool explicitCoercion, TypeViewer typeViewer){
   if (source == null || sourceType == null || targetType == null || coercion == null){Debug.Assert(false); return null;}
   Block nullCase = new Block(new StatementList(1));
   Block nonNullCase = new Block(new StatementList(1));
   Block done = new Block();
   Block coercionBlock = new Block(new StatementList(7));
   Local copyOfSource = new Local(source.Type);
   Local result = new Local(targetType);
   //null case
   StatementList statements = nullCase.Statements;
   statements.Add(new AssignmentStatement(result, new Local(StandardIds.NewObj, targetType)));
   //nonNull case
   statements = nonNullCase.Statements;
   Method getValue = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(Identifier.For("get_Value"));
   Expression getVal = new MethodCall(
     new MemberBinding(new UnaryExpression(copyOfSource, NodeType.AddressOf, TypeViewer.GetTypeView(typeViewer, sourceType).GetReferenceType()), getValue), null, NodeType.Call, getValue.ReturnType);
   if (explicitCoercion)
     getVal = this.ExplicitCoercion(getVal, coercion.Parameters[0].Type, typeViewer);
   else
     getVal = this.ImplicitCoercion(getVal, coercion.Parameters[0].Type, typeViewer);
   if (getVal == null) return null;
   Expression nonNullVal = new MethodCall(new MemberBinding(null, coercion), new ExpressionList(getVal), NodeType.Call, coercion.ReturnType);
   statements.Add(new AssignmentStatement(result, this.ImplicitCoercion(nonNullVal, targetType, typeViewer)));
   //coercion block
   statements = coercionBlock.Statements;
   statements.Add(new AssignmentStatement(copyOfSource, source));
   Method hasValue = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(StandardIds.getHasValue);
   if (hasValue == null){Debug.Assert(false); return null;}
   Expression ifNonNull = new MethodCall(
     new MemberBinding(new UnaryExpression(copyOfSource, NodeType.AddressOf, TypeViewer.GetTypeView(typeViewer, sourceType).GetReferenceType()), hasValue), null, NodeType.Call);
   statements.Add(new Branch(ifNonNull, nonNullCase));
   statements.Add(nullCase);
   statements.Add(new Branch(null, done));
   statements.Add(nonNullCase);
   statements.Add(done);
   statements.Add(new ExpressionStatement(result));
   return new BlockExpression(coercionBlock, targetType);
 }
Пример #18
0
 public virtual Expression TryImplicitCoercion(Expression source, TypeNode targetType, TypeViewer typeViewer) {
   ErrorHandler oldEH = this.ErrorHandler;
   this.ErrorHandler = null;
   Expression e = null;
   try { e = this.ImplicitCoercion(source, targetType, typeViewer); }
   finally {
     this.ErrorHandler = oldEH;
   };
   return e;
 }
Пример #19
0
 protected virtual Method UserDefinedExplicitCoercionMethod(Expression source, TypeNode sourceType, TypeNode targetType, bool tryStandardCoercions, TypeNode originalTargetType, TypeViewer typeViewer){
   Reference rtype = sourceType as Reference;
   if (rtype != null) sourceType = rtype.ElementType;
   if (sourceType == targetType) return null;
   //First do efficient searches for a method that coerces directly between source and target type
   //If the source type knows how to convert to the target type, give it preference
   Method coercion = TypeViewer.GetTypeView(typeViewer, sourceType).GetExplicitCoercionToMethod(targetType);
   if (coercion != null) return coercion;
   coercion = TypeViewer.GetTypeView(typeViewer, sourceType).GetImplicitCoercionToMethod(targetType);
   if (coercion != null) return coercion;
   //If the target type knows how to convert from the source type, that is dandy too
   coercion = TypeViewer.GetTypeView(typeViewer, targetType).GetExplicitCoercionFromMethod(sourceType);
   if (coercion != null) return coercion;
   coercion = TypeViewer.GetTypeView(typeViewer, targetType).GetImplicitCoercionFromMethod(sourceType);
   if (coercion != null) return coercion;
   //Perhaps the base type can convert to the target type, or the target type can convert from the base type
   if (sourceType.BaseType != null){
     coercion = this.UserDefinedExplicitCoercionMethod(source, sourceType.BaseType, targetType, false, originalTargetType, typeViewer);
     if (coercion != null) return coercion;
   }
   if (!tryStandardCoercions) return null;
   //Now resort to desperate measures
   //See if the target type has a conversion that can convert the source after a standard coercion has been applied
   MemberList coercions = TypeViewer.GetTypeView(typeViewer, targetType).ExplicitCoercionMethods;
   for (int i = 0, n = coercions == null ? 0 : coercions.Count; i < n; i++){
     coercion = coercions[i] as Method;
     if (coercion == null) continue;
     if (coercion.ReturnType != targetType) continue;
     ParameterList pars = coercion.Parameters;
     if (pars == null || pars.Count != 1) continue;
     Parameter par = pars[0];
     if (par == null) continue;
     if (sourceType == par.Type) return coercion;
     if (this.StandardExplicitCoercion(source, this.IsNonNullType(sourceType), sourceType, this.IsNonNullType(par.Type), par.Type, par.Type, typeViewer) != null) return coercion;
     //REVIEW: choose the best of the bunch?
   }
   coercions = TypeViewer.GetTypeView(typeViewer, targetType).ImplicitCoercionMethods;
   for (int i = 0, n = coercions == null ? 0 : coercions.Count; i < n; i++){
     coercion = coercions[i] as Method;
     if (coercion == null) continue;
     if (coercion.ReturnType != targetType) continue;
     ParameterList pars = coercion.Parameters;
     if (pars == null || pars.Count != 1) continue;
     Parameter par = pars[0];
     if (par == null) continue;
     if (sourceType == par.Type) return coercion;
     if (this.StandardExplicitCoercion(source, this.IsNonNullType(sourceType), sourceType, this.IsNonNullType(par.Type), par.Type, par.Type, typeViewer) != null) return coercion;
     //REVIEW: choose the best of the bunch?
   }
   //See if the source type has a conversion that results in a type that can be converted to the target type via a standard coercion
   TypeNode tgtType = targetType;
   if (targetType is EnumNode) tgtType = ((EnumNode)targetType).UnderlyingType;
   coercions = TypeViewer.GetTypeView(typeViewer, sourceType).ExplicitCoercionMethods;
   TypeNode bestSoFar = null;
   coercion = null;
   for (int i = 0, n = coercions == null ? 0 : coercions.Count; i < n; i++){
     Method m = coercions[i] as Method;
     if (m == null) continue;
     TypeNode rType = m.ReturnType;
     if (rType == sourceType) continue;
     if (this.StandardImplicitCoercionFromTo(null, rType, targetType, typeViewer)) return m;
     if (this.StandardExplicitCoercion(source, this.IsNonNullType(rType), rType, this.IsNonNullType(targetType), targetType, originalTargetType, typeViewer) != null){
       //Possible information loss, try to choose the least bad coercion
       if (bestSoFar == null || this.IsBetterMatch(tgtType, bestSoFar, rType, typeViewer)){
         coercion = m;
         bestSoFar = rType;
       }
     }
   }
   coercions = TypeViewer.GetTypeView(typeViewer, sourceType).ImplicitCoercionMethods;
   for (int i = 0, n = coercions == null ? 0 : coercions.Count; i < n; i++){
     Method m = coercions[i] as Method;
     if (m == null) continue;
     TypeNode rType = m.ReturnType;
     if (rType == sourceType) continue;
     if (this.StandardImplicitCoercionFromTo(null, rType, targetType, typeViewer)) return m;
     if (this.StandardExplicitCoercion(source, this.IsNonNullType(rType), rType, this.IsNonNullType(targetType), targetType, originalTargetType, typeViewer) != null){
       if (bestSoFar == null || this.IsBetterMatch(tgtType, bestSoFar, rType, typeViewer)){
         coercion = m;
         bestSoFar = rType;
       }
     }
   }
   if (coercion != null) return coercion; //TODO: pass this into the recursive call
   //Perhaps the base type can convert to the target type, or the target type can convert from the base type, via standard coercions
   if (sourceType.BaseType != null){
     coercion = this.UserDefinedExplicitCoercionMethod(source, sourceType.BaseType, targetType, true, originalTargetType, typeViewer);
     if (coercion != null) return coercion;
   }
   //Since this is an explicit coercion, try converting to the base type of the target type
   if (targetType.BaseType != null){
     coercion = this.UserDefinedExplicitCoercionMethod(source, sourceType, targetType.BaseType, true, originalTargetType, typeViewer);
     if (coercion != null) return coercion;
   }
   return null;
 }
Пример #20
0
 public override Literal ImplicitLiteralCoercion(Literal lit, TypeNode sourceType, TypeNode targetType, TypeViewer typeViewer)
 {
     return(this.LiteralCoercion(lit, sourceType, targetType, false, targetType, typeViewer, false));
 }
Пример #21
0
        private Literal LiteralCoercion(Literal /*!*/ lit, TypeNode sourceType, TypeNode targetType, bool explicitCoercion, TypeNode originalTargetType, TypeViewer typeViewer, bool forLabel)
        {
            if (sourceType == targetType)
            {
                if (sourceType == lit.Type)
                {
                    return(lit);
                }
                return(new Literal(Convert.ChangeType(lit.Value, sourceType.TypeCode), sourceType, lit.SourceContext));
            }
            object   val = lit.Value;
            EnumNode eN  = targetType as EnumNode;

            if (eN != null)
            {
                if (sourceType.IsPrimitiveInteger && val is IConvertible && ((IConvertible)val).ToDouble(null) == 0.0)
                {
                    if (eN.UnderlyingType == SystemTypes.Int64 || eN.UnderlyingType == SystemTypes.UInt64)
                    {
                        val = 0L;
                    }
                    else
                    {
                        val = 0;
                    }
                    return(new Literal(val, eN, lit.SourceContext));
                }
                goto error;
            }
            if (targetType.TypeCode == TypeCode.Boolean)
            {
                this.HandleError(lit, Error.ConstOutOfRange, lit.SourceContext.SourceText, "bool");
                lit.SourceContext.Document = null;
                return(null);
            }
            if (targetType.TypeCode == TypeCode.String)
            {
                if (val != null || lit.Type != SystemTypes.Object)
                {
                    this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType));
                    lit.SourceContext.Document = null;
                    return(null);
                }
                return(lit);
            }
            if (targetType.TypeCode == TypeCode.Object)
            {
                if (val == null && sourceType == SystemTypes.Object && (explicitCoercion || !this.IsNonNullType(targetType)))
                {
                    return(lit);
                }
                if (val is string && this.IsNonNullType(targetType) && TypeNode.StripModifiers(targetType) == SystemTypes.String)
                {
                    return(lit);
                }
                Method coercion = null;
                if (explicitCoercion)
                {
                    coercion = this.UserDefinedExplicitCoercionMethod(lit, sourceType, targetType, true, originalTargetType, typeViewer);
                }
                else
                {
                    coercion = this.UserDefinedImplicitCoercionMethod(lit, sourceType, targetType, true, typeViewer);
                }
                if (coercion != null)
                {
                    return(null);
                }
                this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType));
                lit.SourceContext.Document = null;
                return(null);
            }
            if ((targetType.TypeCode == TypeCode.Char || sourceType.TypeCode == TypeCode.Boolean || sourceType.TypeCode == TypeCode.Decimal) && !forLabel)
            {
                goto error;
            }
            switch (sourceType.TypeCode)
            {
            case TypeCode.Double:
                switch (targetType.TypeCode)
                {
                case TypeCode.Single: this.HandleError(lit, Error.LiteralDoubleCast, "float", "F"); return(lit);

                case TypeCode.Decimal: this.HandleError(lit, Error.LiteralDoubleCast, "decimal", "M"); return(lit);

                default:
                    this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType));
                    lit.SourceContext.Document = null;
                    return(null);
                }

            case TypeCode.Single:
                switch (targetType.TypeCode)
                {
                case TypeCode.Double: break;

                default:
                    this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType));
                    lit.SourceContext.Document = null;
                    return(null);
                }
                break;

            case TypeCode.Int64:
            case TypeCode.UInt64:
                switch (targetType.TypeCode)
                {
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Decimal:
                case TypeCode.Single:
                case TypeCode.Double:
                    break;

                default:
                    if (explicitCoercion || !lit.TypeWasExplicitlySpecifiedInSource)
                    {
                        break;
                    }
                    this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType));
                    lit.SourceContext.Document = null;
                    return(null);
                }
                break;
            }
            try{
                if (val == null)
                {
                    if (targetType.IsValueType)
                    {
                        goto error;
                    }
                }
                else
                {
                    val = System.Convert.ChangeType(val, targetType.TypeCode);
                }
                return(new Literal(val, targetType, lit.SourceContext));
            }catch (InvalidCastException) {
            }catch (OverflowException) {
            }catch (FormatException) {}
error:
            if (sourceType.IsPrimitiveNumeric && lit.SourceContext.Document != null)
            {
                Error e = Error.ConstOutOfRange;
                if (explicitCoercion)
                {
                    e = Error.ConstOutOfRangeChecked;
                }
                this.HandleError(lit, e, lit.SourceContext.SourceText, this.GetTypeName(targetType));
            }
            else
            {
                this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType));
            }
            if (this.ErrorHandler != null)
            {
                lit.SourceContext.Document = null;
            }
            return(null);
        }
Пример #22
0
 public virtual bool ImplicitCoercionToIntersection(TypeNode sourceType, TypeIntersection intersect, TypeViewer typeViewer){
   if (intersect == null) return false;
   TypeNodeList types = intersect.Types;
   for (int i = 0, n = types == null ? 0 : types.Count; i < n; i++){
     TypeNode t = types[i];
     if (t == null) continue;
     if (!this.ImplicitCoercionFromTo(sourceType, t, typeViewer)) return false;
   }
   return true;
 }
Пример #23
0
 public virtual Expression ImplicitPrimitiveCoercion(Expression source, TypeNode sourceType, TypeNode targetType, TypeViewer typeViewer){
   if (this.insideUnsafeCode && (targetType == SystemTypes.IntPtr || targetType == SystemTypes.UIntPtr))
     return this.ImplicitPrimitiveCoercionHelper(source, sourceType, targetType);
   Literal lit = source as Literal;
   if (lit != null) return this.ImplicitLiteralCoercion(lit, sourceType, targetType, typeViewer);
   Expression result = this.ImplicitPrimitiveCoercionHelper(source, sourceType, targetType);
   if (result != null) result.Type = targetType;
   return result;
 }
Пример #24
0
 public virtual Expression CoerceToTypeIntersection(Expression source, TypeNode sourceType, TypeIntersection targetType, bool explicitCoercion, TypeViewer typeViewer){
   if (source == null || sourceType == null || targetType == null) return null;
   if (!explicitCoercion){
     TypeNodeList types = targetType.Types;
     for (int i = 0, n = types == null ? 0 : types.Count; i < n; i++){
       TypeNode t = types[i]; if (t == null) continue;
       if (!TypeViewer.GetTypeView(typeViewer, sourceType).IsAssignableTo(t)) return null;
     }
   }
   Method fromObject = TypeViewer.GetTypeView(typeViewer, targetType).GetMethod(StandardIds.FromObject, SystemTypes.Object);
   Method getType = Runtime.GetType;
   MethodCall fromObjectCall = new MethodCall(new MemberBinding(null, fromObject), new ExpressionList(source), NodeType.Call);
   fromObjectCall.Type = targetType;
   return fromObjectCall;
 }
Пример #25
0
 public virtual Method UserDefinedImplicitCoercionMethod(Expression source, TypeNode sourceType, TypeNode targetType, bool tryStandardCoercions, TypeViewer typeViewer){
   Reference rtype = sourceType as Reference;
   if (rtype != null) sourceType = rtype.ElementType;
   if (tryStandardCoercions && this.IsNullableType(sourceType) && this.IsNullableType(targetType)) {
     sourceType = sourceType.TemplateArguments[0];
     targetType = targetType.TemplateArguments[0];
   }
   //First do efficient searches for a method that implicitly coerces directly between source and target type
   //If the source type knows how to convert to the target type, give it preference
   Method coercion = TypeViewer.GetTypeView(typeViewer, sourceType).GetImplicitCoercionToMethod(targetType);
   if (coercion != null) return coercion;
   //If the target type knows how to convert from the source type, that is dandy too
   coercion = TypeViewer.GetTypeView(typeViewer, targetType).GetImplicitCoercionFromMethod(sourceType);
   if (coercion != null) return coercion;
   //Perhaps the base type can convert to the target type, or the target type can convert from the base type
   if (sourceType.BaseType != null && sourceType != SystemTypes.Object){
     coercion = this.UserDefinedImplicitCoercionMethod(source, sourceType.BaseType, targetType, tryStandardCoercions, typeViewer);
     if (coercion != null) return coercion;
   }
   if (!tryStandardCoercions) return null;
   //Now resort to desperate measures
   //See if the source type has a conversion that results in a type that can be converted to the target type via a standard coercion
   MemberList coercions = TypeViewer.GetTypeView(typeViewer, sourceType).ImplicitCoercionMethods;
   for (int i = 0, n = coercions == null ? 0 : coercions.Count; i < n; i++){
     coercion = coercions[i] as Method;
     if (coercion == null) continue;
     if (coercion.ReturnType == sourceType) continue;
     if (this.StandardImplicitCoercionFromTo(source, coercion.ReturnType, targetType, typeViewer)) return coercion;
   }
   //See if the target type has a conversion that can convert the source after a standard coercion has been applied
   coercions = TypeViewer.GetTypeView(typeViewer, targetType).ImplicitCoercionMethods;
   for (int i = 0, n = coercions == null ? 0 : coercions.Count; i < n; i++){
     coercion = coercions[i] as Method;
     if (coercion == null) continue;
     if (coercion.ReturnType != targetType) continue;
     ParameterList pars = coercion.Parameters;
     if (pars == null || pars.Count != 1) continue;
     Parameter par = pars[0];
     if (par.Type == null) continue;
     if (this.StandardImplicitCoercionFromTo(source, sourceType, par.Type, typeViewer)) return coercion;
   }
   return null;
 }
Пример #26
0
 public virtual Expression CoerceObjectToTypeUnion(Expression source, TypeUnion targetType, TypeViewer typeViewer){
   Method fromObject = TypeViewer.GetTypeView(typeViewer, targetType).GetMethod(StandardIds.FromObject, SystemTypes.Object, SystemTypes.Type);
   Method getType = Runtime.GetType;
   ExpressionList arguments = new ExpressionList(2);
   arguments.Add(source);
   arguments.Add(new MethodCall(new MemberBinding(new Expression(NodeType.Dup), getType), null, NodeType.Call));
   MethodCall fromObjectCall = new MethodCall(new MemberBinding(null, fromObject), arguments, NodeType.Call);
   fromObjectCall.Type = targetType;
   return fromObjectCall;
 }
Пример #27
0
 public virtual TypeNode UnifiedType(Literal lit, TypeNode t, TypeViewer typeViewer){
   if (lit == null || lit.Type == null || t == null){Debug.Assert(false); return SystemTypes.Object;}
   t = this.Unwrap(t);
   MemberList coercions = TypeViewer.GetTypeView(typeViewer, t).ImplicitCoercionMethods;
   for (int i = 0, n = coercions == null ? 0 : coercions.Count; i < n; i++){
     Method coercion = coercions[i] as Method;
     if (coercion == null) continue;
     TypeNode t2 = coercion.ReturnType;
     if (t2 == t || t2 == null || !t2.IsPrimitive) continue;
     if (this.ImplicitLiteralCoercionFromTo(lit, lit.Type, t2)) return t2;
   }
   return this.UnifiedType(lit.Type, t);
 }
Пример #28
0
 public virtual Expression CoerceToTypeUnion(Expression source, TypeNode sourceType, TypeUnion targetType, TypeViewer typeViewer){
   if (source == null || sourceType == null || targetType == null) return null;
   if (this.UserDefinedImplicitCoercionMethod(source, sourceType, targetType, true, typeViewer) != null) return null;
   TypeUnion tType = targetType.UnlabeledUnion;
   if (tType == null) return null;
   Method coercion = this.UserDefinedImplicitCoercionMethod(source, sourceType, tType, true, typeViewer);
   if (coercion == null) return null; //No coercion possible
   TypeNode chosenType = coercion.Parameters[0].Type;
   TypeNodeList types1 = tType.Types;
   TypeNodeList types2 = targetType.Types;
   for (int i = 0, n = types1.Count; i < n; i++){
     TypeNode t = types1[i];
     if (t == chosenType){
       source = this.ExplicitCoercion(source, types2[i], typeViewer);
       if (source == null) return null;
       return this.ExplicitCoercion(source, targetType, typeViewer);
     }
   }
   Debug.Assert(false);
   return null;
 }
Пример #29
0
 public virtual void SupportedInterfaces(TypeNode t, InterfaceList ifaceList, TypeViewer typeViewer){
   if (ifaceList == null) return;
   TypeNode unwrappedT = this.Unwrap(t);
   Interface iface = unwrappedT as Interface;
   if (iface != null){
     // possibly not needed, but seems better to keep ifaceList as a set
     int i = 0;
     while (i < ifaceList.Count){
       if (ifaceList[i] == iface)
         break;
       i++;
     }
     if (i == ifaceList.Count) // not found
       ifaceList.Add(iface);
   }else{
     // nop
   }
   InterfaceList ifaces = TypeViewer.GetTypeView(typeViewer, unwrappedT).Interfaces;
   for (int i = 0, n = ifaces == null ? 0 : ifaces.Count; i < n; i++){
     this.SupportedInterfaces(ifaces[i],ifaceList,typeViewer);
   }
   return;
 }
Пример #30
0
 public static bool NotAccessible(Member member, ref TypeNode qualifierType, Module currentModule, TypeNode currentType, TypeViewer typeViewer) {
   if (member == null) return false;
   switch (member.NodeType) {
     case NodeType.Field:
       return Checker.NotAccessible(member, ref qualifierType, (int)(((Field)member).Flags & FieldFlags.FieldAccessMask), currentModule, currentType, typeViewer);
     case NodeType.InstanceInitializer:
     case NodeType.Method:
       return Checker.NotAccessible(member, ref qualifierType, (int)(((Method)member).Flags & MethodFlags.MethodAccessMask), currentModule, currentType, typeViewer);
     case NodeType.Property:
       Property p = (Property)member;
       return Checker.NotAccessible(member, ref qualifierType, (int)(Method.GetVisibilityUnion(p.Getter, p.Setter) & MethodFlags.MethodAccessMask), currentModule, currentType, typeViewer);
     case NodeType.Event:
       Event e = (Event)member;
       return Checker.NotAccessible(member, ref qualifierType, (int)(Method.GetVisibilityUnion(e.HandlerAdder, e.HandlerRemover) & MethodFlags.MethodAccessMask), currentModule, currentType, typeViewer);
   }
   return false;
 }
Пример #31
0
 public virtual TypeNode GetCollectionElementType(TypeNode t, TypeViewer typeViewer){
   bool foundObject = false;
   TypeAlias ta = t as TypeAlias;
   while (ta != null){t = ta.AliasedType; ta = t as TypeAlias;}
   if (t == null || t == SystemTypes.String || t is TupleType) return null;
   // look for get_Item indexer
   MemberList list = TypeViewer.GetTypeView(typeViewer, t).GetMembersNamed(StandardIds.getItem);
   if (list != null) {
     for( int i = 0, n = list.Count; i < n; i++ ) {
       Method m = list[i] as Method;
       if (m == null) continue;
       if (m.ReturnType != SystemTypes.Object) return m.ReturnType;
       foundObject = true;
     }
   }
   // look for enumerable pattern
   Method mge = TypeViewer.GetTypeView(typeViewer, t).GetMethod(StandardIds.GetEnumerator);
   if (mge != null) {
     Method mgc = TypeViewer.GetTypeView(typeViewer, mge.ReturnType).GetMethod(StandardIds.getCurrent);
     if (mgc != null) {
       if (mgc.ReturnType != SystemTypes.Object) return mgc.ReturnType;
       foundObject = true;
     }
   }
   InterfaceList ilist = TypeViewer.GetTypeView(typeViewer, t).Interfaces;
   if (ilist != null) {
     for( int i = 0, n = ilist.Count; i < n; i++ ) {
       Interface iface = ilist[i];
       if (iface == null) continue;
       TypeNode tn = this.GetCollectionElementType(iface, typeViewer);
       if (tn == null) continue;
       if (tn != SystemTypes.Object) return tn;
       foundObject = true;
     }
   }
   if (foundObject) return SystemTypes.Object;
   if (t.BaseType != null && t.BaseType != SystemTypes.Object) {
     return this.GetCollectionElementType(t.BaseType, typeViewer);
   }
   return null;
 }
Пример #32
0
 public static bool NotAccessible(Member member, TypeNode type, ref TypeNode qualifierType, int visibility, Module currentModule, TypeNode currentType, TypeViewer typeViewer) {
   if (type == null) return false;
   TypeNode effectiveType = type.EffectiveTypeNode;
   if ((object)effectiveType != (object)type) {
     // the member being accessed is declared in a type extension; also see whether the member
     // would be accessible if it were considered declared in the extendee type
     if (!NotAccessible(member, effectiveType, ref qualifierType, visibility, currentModule, currentType, typeViewer)) {
       return false;
     }
   }
   TypeNode effectiveCurrentType = currentType == null ? null : currentType.EffectiveTypeNode;
   if ((object)effectiveCurrentType != (object)currentType) {
     // the member is being accessed from a type extension; see whether the member
     // would be accessible if it were being accessed from the extendee type
     // [v-craigc-TODO: consider inaccessible any members not visible according to the 
     // accessibility claimed by the extension; the current code implicitly grants private
     // access to extensions]
     if (!NotAccessible(member, type, ref qualifierType, visibility, currentModule, effectiveCurrentType, typeViewer)) {
       return false;
     }
   }
   TypeNode template = type;
   while (template.Template != null) {
     if (template.Template == template) {
       Debug.Assert(false);
       template.Template = null;
       break;
     }
     template = template.Template;
   }
   TypeNode t = currentType;
   while (t != null && t.Template != null) {
     if (t.Template == t) {
       Debug.Assert(false);
       t.Template = null;
       break;
     }
     t = t.Template;
   }
   while (t != null) {
     if (t == template) {
       switch ((FieldFlags)visibility) {
         case FieldFlags.FamANDAssem:
         case FieldFlags.Family:
           while (qualifierType != null && qualifierType.Template != null)
             qualifierType = qualifierType.Template;
           if (qualifierType != null && !TypeViewer.GetTypeView(typeViewer, qualifierType).IsAssignableTo(t) && !TypeViewer.GetTypeView(typeViewer, qualifierType).IsAssignableToInstanceOf(t)) {
             qualifierType = null;
             return true;
           }
           break;
       }
       return false;
     }
     t = t.DeclaringType;
   }
   switch ((FieldFlags)visibility) {
     case FieldFlags.Assembly:
       return !Checker.InternalsAreVisible(currentModule, type.DeclaringModule);
     case FieldFlags.FamANDAssem:
       if (!Checker.InternalsAreVisible(currentModule, type.DeclaringModule)) return true;
       goto case FieldFlags.Family;
     case FieldFlags.Family:
       if (currentType == null || !TypeViewer.GetTypeView(typeViewer, currentType).IsAssignableTo(type)) {
         if (currentType != null && currentType.DeclaringType != null)
           return Checker.NotAccessible(member, ref qualifierType, currentModule, currentType.DeclaringType, typeViewer);
         return true;
       }
       while (qualifierType != null && qualifierType.Template != null)
         qualifierType = qualifierType.Template;
       if (qualifierType != null && !TypeViewer.GetTypeView(typeViewer, qualifierType).IsAssignableTo(currentType) && !TypeViewer.GetTypeView(typeViewer, qualifierType).IsAssignableToInstanceOf(currentType)) {
         qualifierType = null;
         return true;
       }
       return false;
     case FieldFlags.FamORAssem:
       if (Checker.InternalsAreVisible(currentModule, type.DeclaringModule)) return false;
       goto case FieldFlags.Family;
     case FieldFlags.Private:
       return true;
     case FieldFlags.Public:
       return false;
   }
   return false;
 }
Пример #33
0
 public virtual TypeNode GetMemberElementType(Member member, TypeViewer typeViewer) {
   if (member == null) return null;
   AttributeNode attr = MetadataHelper.GetCustomAttribute(member, SystemTypes.ElementTypeAttribute);
   if (attr != null){
     Literal litType = MetadataHelper.GetNamedAttributeValue(attr, StandardIds.ElementType);
     if (litType != null) return litType.Value as TypeNode;
   }        
   return this.GetStreamElementType(this.GetMemberType(member), typeViewer);
 }
Пример #34
0
        public override Expression ExplicitLiteralCoercion(Literal lit, TypeNode sourceType, TypeNode targetType, TypeViewer typeViewer)
        {
            if (sourceType == targetType && (sourceType == SystemTypes.Double || sourceType == SystemTypes.Single))
            {
                return(lit);
            }
            TypeNode originalTargetType = targetType;
            EnumNode sourceEnum         = sourceType as EnumNode;

            if (sourceEnum != null)
            {
                sourceType = sourceEnum.UnderlyingType;
            }
            bool needsRuntimeCoercion = this.suppressOverflowCheck;

            if (!sourceType.IsPrimitiveInteger || sourceType == SystemTypes.IntPtr || sourceType == SystemTypes.UIntPtr)
            {
                needsRuntimeCoercion = true;
            }
            else if (!targetType.IsPrimitiveInteger || targetType == SystemTypes.IntPtr || targetType == SystemTypes.UIntPtr)
            {
                needsRuntimeCoercion = true;
            }
            if (needsRuntimeCoercion)
            {
                if (lit != null && lit.Value != null)
                {
                    targetType = TypeNode.StripModifier(targetType, SystemTypes.NonNullType);
                }
                return(this.ExplicitCoercion(lit, targetType, typeViewer));
            }
            else
            {
                return(this.LiteralCoercion(lit, sourceType, targetType, true, originalTargetType, null, false));
            }
        }
Пример #35
0
 public virtual Cardinality GetCardinality(TypeNode collectionType, TypeViewer typeViewer) {
   if (collectionType == null) return Cardinality.None;
   TypeAlias ta = collectionType as TypeAlias;
   if (ta != null) collectionType = ta.AliasedType;
   if (collectionType is TupleType) {
     return Cardinality.One;
   }
   else if (collectionType.Template == SystemTypes.GenericBoxed) {
     return Cardinality.ZeroOrOne;
   }
   else if (collectionType.Template == SystemTypes.GenericNonNull) {
     return Cardinality.One;
   }
   else if (collectionType.Template == SystemTypes.GenericNonEmptyIEnumerable) {
     return Cardinality.OneOrMore;
   }
   else if (TypeViewer.GetTypeView(typeViewer, collectionType).IsAssignableTo(SystemTypes.INullable)) {
     return Cardinality.ZeroOrOne;
   }
   else {
     TypeUnion tu = collectionType as TypeUnion;
     if (tu != null && tu.Types.Count > 0) {
       Cardinality c = this.GetCardinality(tu.Types[0], typeViewer);
       for( int i = 1, n = tu.Types.Count; i < n; i++ ) {
         TypeNode tn = tu.Types[i];
         if (tn == null) continue;
         c = this.GetCardinalityOr(c, this.GetCardinality(tn, typeViewer));
       }
       return c;
     }
     TypeNode elementType = this.GetStreamElementType(collectionType, typeViewer);
     if (elementType != collectionType) {
       return Cardinality.ZeroOrMore;
     }
     else if (collectionType.IsValueType) {
       return Cardinality.One;
     }
     else {
       return Cardinality.None;
     }
   }
 }
Пример #36
0
 public virtual Expression CoerceTypeUnionToObject(Expression source, TypeViewer typeViewer){
   TypeUnion sourceType = (TypeUnion)source.Type;
   Method getValue = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(StandardIds.GetValue);
   Local temp = new Local(Identifier.Empty, sourceType);
   Expression tempAddr = new UnaryExpression(temp, NodeType.AddressOf);
   StatementList statements = new StatementList(2);
   statements.Add(new AssignmentStatement(temp, source));
   statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(tempAddr, getValue), null)));
   BlockExpression result = new BlockExpression(new Block(statements));
   result.Type = SystemTypes.Object;
   return result;
 }
Пример #37
0
 protected virtual Expression CoerceFromTypeUnion(Expression source, TypeUnion sourceType, TypeNode targetType, bool explicitCoercion, TypeNode originalTargetType, TypeViewer typeViewer){
   if (source == null || sourceType == null || targetType == null) return null;
   if (targetType == SystemTypes.Object) return this.CoerceTypeUnionToObject(source, typeViewer);
   int cErrors = (this.Errors != null) ? this.Errors.Count : 0;
   if (explicitCoercion){
     Method coercion = this.UserDefinedExplicitCoercionMethod(source, sourceType, targetType, false, originalTargetType, typeViewer);
     if (coercion != null && coercion.ReturnType == targetType && coercion.Parameters != null && coercion.Parameters[0] != null &&
       this.ImplicitCoercionFromTo(sourceType, coercion.Parameters[0].Type, typeViewer))
       return this.ImplicitCoercion(new MethodCall(new MemberBinding(null, coercion), new ExpressionList(source), NodeType.Call, coercion.ReturnType),
         targetType, typeViewer);
   }
   Method getTag = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(StandardIds.GetTag);
   if (getTag == null) return null;
   Method getValue = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(StandardIds.GetValue);
   if (getValue == null) return null;
   Local src = new Local(sourceType);
   Local srcOb = new Local(SystemTypes.Object, source.SourceContext);
   Local tgt = new Local(targetType);
   Expression callGetTag = new MethodCall(new MemberBinding(new UnaryExpression(src, NodeType.AddressOf), getTag), null);
   Expression callGetValue = new MethodCall(new MemberBinding(new UnaryExpression(src, NodeType.AddressOf), getValue), null);
   TypeNodeList types = sourceType.Types;
   int n = types == null ? 0 : types.Count;
   Block endOfSwitch = new Block();
   StatementList statements = new StatementList(5+n);
   statements.Add(new AssignmentStatement(src, source));
   statements.Add(new AssignmentStatement(srcOb, callGetValue));
   BlockList cases = new BlockList(n);
   statements.Add(new SwitchInstruction(callGetTag, cases));
   bool hadCoercion = false;
   Block eb = new Block(new StatementList(1));
   Construct c = new Construct(new MemberBinding(null, SystemTypes.InvalidCastException.GetConstructor()), null, SystemTypes.InvalidCastException);
   eb.Statements.Add(new Throw(c));
   for (int i = 0; i < n; i++){
     TypeNode t = types[i];
     if (t == null) continue;
     if (!explicitCoercion && !this.ImplicitCoercionFromTo(t, targetType, typeViewer)) return null;
     Expression expr = this.ExplicitCoercion(srcOb, t, typeViewer);
     if (expr == null) return null;
     expr = this.ExplicitCoercion(expr, targetType, typeViewer);
     if (expr == null) {
       cases.Add(eb);
       statements.Add(eb);
     }
     else {
       Block b = new Block(new StatementList(2));
       hadCoercion = true;
       expr.SourceContext = srcOb.SourceContext;
       b.Statements.Add(new AssignmentStatement(tgt, expr));
       b.Statements.Add(new Branch(null, endOfSwitch));
       cases.Add(b);
       statements.Add(b);
     }
   }
   if (this.Errors != null) {
     for (int ie = cErrors, ne = this.Errors.Count; ie < ne; ie++) {
       this.Errors[ie] = null;
     }
   }
   if (!hadCoercion) return null;
   statements.Add(endOfSwitch);
   statements.Add(new ExpressionStatement(tgt));
   return new BlockExpression(new Block(statements));
   //TODO: wrap this in a CoerceTypeUnion node so that source code can be reconstructed easily
 }
Пример #38
0
 public TypeViewerBehaviour()
 {
     _sut = new TypeViewer(typeof(MyServicesApiController));
 }
Пример #39
0
 public static bool NotAccessible(Member member, ref TypeNode qualifierType, int visibility, Module currentModule, TypeNode currentType, TypeViewer typeViewer) {
   TypeNode type = member.DeclaringType;
   return NotAccessible(member, type, ref qualifierType, visibility, currentModule, currentType, typeViewer);
 }
Пример #40
0
 public virtual bool ImplicitCoercionToUnion(TypeNode sourceType, TypeUnion union, TypeViewer typeViewer){
   if (union == null) return false;
   TypeNodeList types = union.Types;
   for (int i = 0, n = types == null ? 0 : types.Count; i < n; i++){
     TypeNode t = types[i];
     if (t == null) continue;
     if (this.ImplicitCoercionFromTo(sourceType, t, typeViewer)) return true;
   }
   return true;
 }
Пример #41
0
 public virtual Expression CoerceTypeIntersectionToObject(Expression source, TypeViewer typeViewer){
   TypeIntersection sourceType = (TypeIntersection)source.Type;
   Method coercion = TypeViewer.GetTypeView(typeViewer, sourceType).GetImplicitCoercionToMethod(SystemTypes.Object);
   ExpressionList args = new ExpressionList(1);
   args.Add(source);
   MethodCall result = new MethodCall(new MemberBinding(null, coercion), args);
   result.Type = SystemTypes.Object;
   return result;
 }
Пример #42
0
 public override Expression CoerceAnonymousNestedFunction(AnonymousNestedFunction func, TypeNode targetType, bool explicitCoercion, TypeViewer typeViewer)
 {
     if (func is AnonymousNestedDelegate && !(targetType is DelegateNode))
     {
         this.HandleError(func, Error.AnonMethToNonDel, this.GetTypeName(targetType));
         return(null);
     }
     return(base.CoerceAnonymousNestedFunction(func, targetType, explicitCoercion, typeViewer));
 }