protected void HandleTypeAttribute(XmlReader reader)
        {
            DebugCheck.NotNull(reader);

            string type;
            if (!Utils.GetString(Schema, reader, out type))
            {
                return;
            }

            TypeModifier typeModifier;
            Function.RemoveTypeModifier(ref type, out typeModifier, out _isRefType);

            switch (typeModifier)
            {
                case TypeModifier.Array:
                    _collectionKind = CollectionKind.Bag;
                    break;
                default:
                    Debug.Assert(
                        typeModifier == TypeModifier.None,
                        string.Format(
                            CultureInfo.CurrentCulture,
                            "Type is not valid for property {0}: {1}. The modifier for the type cannot be used in this context.", FQName,
                            reader.Value));
                    break;
            }

            if (!Utils.ValidateDottedName(Schema, reader, type))
            {
                return;
            }

            _unresolvedType = type;
        }
		public CollectionTraits( CollectionKind type, MethodInfo addMethod, MethodInfo getEnumeratorMethod, PropertyInfo countProperty, Type elementType )
		{
			this.CollectionType = type;
			this.GetEnumeratorMethod = getEnumeratorMethod; 
			this.AddMethod = addMethod;
			this.CountProperty = countProperty;
			this.ElementType = elementType;
		}
 internal static string GetTypeNameForErrorMessage(SchemaType type, CollectionKind colKind, bool isRef)
 {
     string typeName = type.FQName;
     if (isRef)
     {
         typeName = "Ref(" + typeName + ")";
     }
     switch (colKind)
     {
         case CollectionKind.Bag:
             typeName = "Collection(" + typeName + ")";
             break;
         default:
             Debug.Assert(colKind == CollectionKind.None, "Unexpected CollectionKind");
             break;
     }
     return typeName;
 }
 /**
  * @param kind The kind to set.
  */
 public void setKind(CollectionKind kind)
 {
     this.kind = kind;
 }
Exemple #5
0
 public CollectionTypeReference(CollectionKind kind, TypeReference elementType)
 {
     Kind        = kind;
     ElementType = elementType ?? throw new ArgumentNullException(nameof(elementType));
 }
        void WriteCollection(CollectionDataContract collectionContract)
        {
            XmlDictionaryString itemNamespace = dataContract.Namespace;

            XmlDictionaryString itemName = collectionDataContract.CollectionItemName;

            if (collectionContract.ChildElementNamespace != null)
            {
                writer.WriteNamespaceDecl(collectionDataContract.ChildElementNamespace);
            }

            if (collectionContract.Kind == CollectionKind.Array)
            {
                Type itemType = collectionContract.ItemType;
                int  i;

                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (objLocal.GetType().GetElementType() != itemType)
                {
                    throw new InvalidCastException(string.Format("Cannot cast array of {0} to array of {1}", objLocal.GetType().GetElementType(), itemType));
                }

                ctx.IncrementArrayCount(writer, (Array)objLocal);

                if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, () => objLocal, itemName, itemNamespace))
                {
                    var arr = (Array)objLocal;
                    var idx = new int [1];
                    for (i = 0; i < arr.Length; i++)
                    {
                        if (!TryWritePrimitive(itemType, null, null, i, itemNamespace, itemName, 0))
                        {
                            WriteStartElement(itemType, collectionContract.Namespace, itemNamespace, itemName, 0);
                            idx [0] = i;
                            var mbrVal = arr.GetValue(idx);
                            WriteValue(itemType, mbrVal, false);
                            WriteEndElement();
                        }
                    }
                }
            }
            else
            {
                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (!collectionContract.UnderlyingType.IsAssignableFrom(objLocal.GetType()))
                {
                    throw new InvalidCastException(string.Format("Cannot cast {0} to {1}", objLocal.GetType(), collectionContract.UnderlyingType));
                }

                MethodInfo incrementCollectionCountMethod = null;
                switch (collectionContract.Kind)
                {
                case CollectionKind.Collection:
                case CollectionKind.List:
                case CollectionKind.Dictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                    break;

                case CollectionKind.GenericCollection:
                case CollectionKind.GenericList:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                    break;

                case CollectionKind.GenericDictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                    break;
                }
                if (incrementCollectionCountMethod != null)
                {
                    incrementCollectionCountMethod.Invoke(ctx, new object [] { writer, objLocal });
                }

                bool    isDictionary = false, isGenericDictionary = false;
                Type    enumeratorType = null;
                Type [] keyValueTypes  = null;
                if (collectionContract.Kind == CollectionKind.GenericDictionary)
                {
                    isGenericDictionary = true;
                    keyValueTypes       = collectionContract.ItemType.GetGenericArguments();
                    enumeratorType      = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                }
                else if (collectionContract.Kind == CollectionKind.Dictionary)
                {
                    isDictionary   = true;
                    keyValueTypes  = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                    enumeratorType = Globals.TypeOfDictionaryEnumerator;
                }
                else
                {
                    enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                }
                MethodInfo moveNextMethod   = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                if (moveNextMethod == null || getCurrentMethod == null)
                {
                    if (enumeratorType.IsInterface)
                    {
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod;
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod;
                        }
                    }
                    else
                    {
                        Type           ienumeratorInterface = Globals.TypeOfIEnumerator;
                        CollectionKind kind = collectionContract.Kind;
                        if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                        {
                            Type[] interfaceTypes = enumeratorType.GetInterfaces();
                            foreach (Type interfaceType in interfaceTypes)
                            {
                                if (interfaceType.IsGenericType &&
                                    interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric &&
                                    interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                {
                                    ienumeratorInterface = interfaceType;
                                    break;
                                }
                            }
                        }
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                        }
                    }
                }
                Type   elementType  = getCurrentMethod.ReturnType;
                object currentValue = null;                 // of elementType

                var enumerator = (IEnumerator)collectionContract.GetEnumeratorMethod.Invoke(objLocal, new object [0]);
                if (isDictionary)
                {
                    enumerator = new CollectionDataContract.DictionaryEnumerator((IDictionaryEnumerator)enumerator);
                }
                else if (isGenericDictionary)
                {
                    Type            ctorParam    = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                    ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
                    enumerator = (IEnumerator)Activator.CreateInstance(enumeratorType, new object [] { enumerator });
                }

                var emptyArray = new object [0];
                while (enumerator != null && enumerator.MoveNext())
                {
                    currentValue = getCurrentMethod.Invoke(enumerator, emptyArray);

                    if (incrementCollectionCountMethod == null)
                    {
                        XmlFormatGeneratorStatics.IncrementItemCountMethod.Invoke(ctx, new object [] { 1 });
                    }

                    if (!TryWritePrimitive(elementType, () => currentValue, null, null, itemNamespace, itemName, 0))
                    {
                        WriteStartElement(elementType, collectionContract.Namespace, itemNamespace, itemName, 0);
                        if (isGenericDictionary || isDictionary)
                        {
                            collectionDataContract.ItemContract.WriteXmlValue(writer, currentValue, ctx);
                        }
                        else
                        {
                            WriteValue(elementType, currentValue, false);
                        }
                        WriteEndElement();
                    }
                }
            }
        }
        private bool ReturnTypeMeetsFunctionImportBasicRequirements(SchemaType type, CollectionKind returnTypeCollectionKind)
        {
            if (type is ScalarType && returnTypeCollectionKind == CollectionKind.Bag) 
                return true;
            if (type is SchemaEntityType && returnTypeCollectionKind == CollectionKind.Bag) return true;

            if (Schema.SchemaVersion == XmlConstants.EdmVersionForV1_1)
            {
                if (type is ScalarType && returnTypeCollectionKind == CollectionKind.None) return true;
                if (type is SchemaEntityType && returnTypeCollectionKind == CollectionKind.None) return true;
                if (type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.None) return true;
                if (type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.Bag) return true;
            }
            if (Schema.SchemaVersion >= XmlConstants.EdmVersionForV2)
            {
                if (type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.Bag) return true;
            }
            if (Schema.SchemaVersion >= XmlConstants.EdmVersionForV3)
            {
                if (type is SchemaEnumType && returnTypeCollectionKind == CollectionKind.Bag) return true;
            }

            return false;
        }
 /// <summary>
 /// Initializes a new instance of the CollectionKindAnnotation class.
 /// </summary>
 /// <param name="kind">The collection kind.</param>
 public CollectionKindAnnotation(CollectionKind kind)
 {
     this.CollectionKind = kind;
 }
Exemple #9
0
        /// <summary>
        /// Emit the property set statments to properly set a ComplexType.
        /// </summary>
        /// <param name="statements">The collection of statements that the set statements should be added to.</param>
        private void EmitComplexTypePropertySetStatements(CodeStatementCollection statements, CollectionKind collectionKind)
        {
            CodePropertySetValueReferenceExpression valueRef = new CodePropertySetValueReferenceExpression();

            //Since collections are not supported by
            //the stack, we don't need to do anything special
            //like doing an Attach or Detatch like the way we do for complex types.
            if (collectionKind == CollectionKind.None)
            {
                // this.fieldName = SetValidValue( this.fieldName, value, _pifieldName);
                statements.Add(
                    new CodeAssignStatement(
                        FieldRef,
                        new CodeMethodInvokeExpression(
                            ThisRef,
                            Utils.SetValidValueMethodName,
                            FieldRef,
                            valueRef,
                            new CodePrimitiveExpression(PropertyName))));

                // this._complexPropertyInitialized = true;
                statements.Add(
                    new CodeAssignStatement(
                        ComplexPropertyInitializedFieldRef,
                        new CodePrimitiveExpression(true)));
            }
            else
            {
                // this.fieldName = value;
                statements.Add(
                    new CodeAssignStatement(
                        FieldRef, valueRef));
            }
        }
        private static TypeUsage GetFunctionTypeUsage(
            bool isModelFunction,
            System.Data.Entity.Core.SchemaObjectModel.Function somFunction,
            FacetEnabledSchemaElement somParameter,
            DbProviderManifest providerManifest,
            bool areConvertingForProviderManifest,
            System.Data.Entity.Core.SchemaObjectModel.SchemaType type,
            CollectionKind collectionKind,
            bool isRefType,
            Converter.ConversionCache convertedItemCache,
            Dictionary <SchemaElement, GlobalItem> newGlobalItems)
        {
            if (somParameter != null && areConvertingForProviderManifest && somParameter.HasUserDefinedFacets)
            {
                return(somParameter.TypeUsage);
            }
            if (type == null)
            {
                if (isModelFunction && somParameter != null && somParameter is Parameter)
                {
                    ((Parameter)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return(somParameter.TypeUsage);
                }
                if (somParameter == null || !(somParameter is ReturnType))
                {
                    return((TypeUsage)null);
                }
                ((ReturnType)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                return(somParameter.TypeUsage);
            }
            EdmType edmType;

            if (!areConvertingForProviderManifest)
            {
                ScalarType scalarType = type as ScalarType;
                if (scalarType != null)
                {
                    if (isModelFunction && somParameter != null)
                    {
                        if (somParameter.TypeUsage == null)
                        {
                            somParameter.ValidateAndSetTypeUsage(scalarType);
                        }
                        return(somParameter.TypeUsage);
                    }
                    if (isModelFunction)
                    {
                        ModelFunction modelFunction = somFunction as ModelFunction;
                        if (modelFunction.TypeUsage == null)
                        {
                            modelFunction.ValidateAndSetTypeUsage(scalarType);
                        }
                        return(modelFunction.TypeUsage);
                    }
                    if (somParameter != null && somParameter.HasUserDefinedFacets && somFunction.Schema.DataModel == SchemaDataModelOption.ProviderDataModel)
                    {
                        somParameter.ValidateAndSetTypeUsage(scalarType);
                        return(somParameter.TypeUsage);
                    }
                    edmType = (EdmType)Converter.GetPrimitiveType(scalarType, providerManifest);
                }
                else
                {
                    edmType = (EdmType)Converter.LoadSchemaElement(type, providerManifest, convertedItemCache, newGlobalItems);
                    if (isModelFunction && type is SchemaEnumType)
                    {
                        if (somParameter != null)
                        {
                            somParameter.ValidateAndSetTypeUsage(edmType);
                            return(somParameter.TypeUsage);
                        }
                        if (somFunction != null)
                        {
                            ModelFunction modelFunction = (ModelFunction)somFunction;
                            modelFunction.ValidateAndSetTypeUsage(edmType);
                            return(modelFunction.TypeUsage);
                        }
                    }
                }
            }
            else
            {
                edmType = !(type is TypeElement) ? (EdmType)(type as ScalarType).Type : (EdmType)(type as TypeElement).PrimitiveType;
            }
            TypeUsage typeUsage;

            if (collectionKind != CollectionKind.None)
            {
                typeUsage = convertedItemCache.GetCollectionTypeUsageWithNullFacets(edmType);
            }
            else
            {
                EntityType entityType = edmType as EntityType;
                typeUsage = entityType == null || !isRefType?convertedItemCache.GetTypeUsageWithNullFacets(edmType) : TypeUsage.Create((EdmType) new RefType(entityType));
            }
            return(typeUsage);
        }
 private void ValidateFunctionImportReturnType(SchemaElement owner, SchemaType returnType, CollectionKind returnTypeCollectionKind, EntityContainerEntitySet entitySet, bool entitySetPathDefined)
 {
     if (returnType != null && !ReturnTypeMeetsFunctionImportBasicRequirements(returnType, returnTypeCollectionKind))
     {
         owner.AddError(ErrorCode.FunctionImportUnsupportedReturnType,
                        EdmSchemaErrorSeverity.Error,
                        owner,
                        GetReturnTypeErrorMessage(Schema.SchemaVersion, this.Name)
                        );
     }
     ValidateFunctionImportReturnType(owner, returnType, entitySet, entitySetPathDefined);
 }
Exemple #12
0
        public CollectionType CreateCollection(CollectionKind kind, Classifier elementType,
                                               bool deferFullInitialization = false, List <CollectionType> deferredCollectionList = null)
        {
            CollectionType newType;
            var            tupleCacheKey = new Tuple <Classifier, CollectionKind>(elementType, kind);

            if (collectionTypeCache.ContainsKey(tupleCacheKey))
            {
                return(collectionTypeCache[tupleCacheKey]);
            }

            if (kind == CollectionKind.Collection)
            {
                newType = new CollectionType(TypeTable, elementType, Any);
            }
            else
            {
                CollectionType inheritFrom;                // = CreateCollection(CollectionKind.Collection, elementType, deferFullInitialization, deferredCollectionList);
                switch (kind)
                {
                case CollectionKind.Bag:
                    inheritFrom = CreateCollection(CollectionKind.Collection, elementType, deferFullInitialization, deferredCollectionList);
                    newType     = new BagType(TypeTable, elementType, inheritFrom);
                    break;

                case CollectionKind.Collection:
                    newType = null;
                    System.Diagnostics.Debug.Fail("Hups.");
                    break;

                case CollectionKind.OrderedSet:
                    inheritFrom = CreateCollection(CollectionKind.Collection, elementType, deferFullInitialization, deferredCollectionList);
                    newType     = new OrderedSetType(TypeTable, elementType, inheritFrom);
                    break;

                case CollectionKind.Sequence:
                    inheritFrom = CreateCollection(CollectionKind.Collection, elementType, deferFullInitialization, deferredCollectionList);
                    newType     = new SequenceType(TypeTable, elementType, inheritFrom);
                    break;

                case CollectionKind.Set:
                    inheritFrom = CreateCollection(CollectionKind.Collection, elementType, deferFullInitialization, deferredCollectionList);
                    newType     = new SetType(TypeTable, elementType, inheritFrom);
                    break;

                default:
                    newType = null;
                    System.Diagnostics.Debug.Fail("CreateCollectionType( ... ): missing case for CollectionKind.");
                    break;
                }
            }

            newType.DeferredFullInitialization = deferFullInitialization;

            if (!deferFullInitialization)
            {
                PerformDeferredInitialization(newType);
            }
            else
            {
                deferredCollectionList.Add(newType);
            }

            TypeTable.RegisterType(newType);
            collectionTypeCache[tupleCacheKey] = newType;
            return(newType);
        }
            void WriteCollection(CollectionDataContract collectionContract)
            {
                LocalBuilder itemNamespace = ilg.DeclareLocal(typeof(XmlDictionaryString), "itemNamespace");

                ilg.Load(dataContractArg);
                ilg.LoadMember(XmlFormatGeneratorStatics.NamespaceProperty);
                ilg.Store(itemNamespace);

                LocalBuilder itemName = ilg.DeclareLocal(typeof(XmlDictionaryString), "itemName");

                ilg.Load(dataContractArg);
                ilg.LoadMember(XmlFormatGeneratorStatics.CollectionItemNameProperty);
                ilg.Store(itemName);

                if (collectionContract.ChildElementNamespace != null)
                {
                    ilg.Load(xmlWriterArg);
                    ilg.Load(dataContractArg);
                    ilg.LoadMember(XmlFormatGeneratorStatics.ChildElementNamespaceProperty);
                    ilg.Call(XmlFormatGeneratorStatics.WriteNamespaceDeclMethod);
                }

                if (collectionContract.Kind == CollectionKind.Array)
                {
                    Type         itemType = collectionContract.ItemType;
                    LocalBuilder i        = ilg.DeclareLocal(Globals.TypeOfInt, "i");

                    ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementArrayCountMethod, xmlWriterArg, objectLocal);

                    if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, objectLocal, itemName, itemNamespace))
                    {
                        ilg.For(i, 0, objectLocal);
                        if (!TryWritePrimitive(itemType, null /*value*/, null /*memberInfo*/, i /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/))
                        {
                            WriteStartElement(itemType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/);
                            ilg.LoadArrayElement(objectLocal, i);
                            LocalBuilder memberValue = ilg.DeclareLocal(itemType, "memberValue");
                            ilg.Stloc(memberValue);
                            WriteValue(memberValue, false /*writeXsiType*/);
                            WriteEndElement();
                        }
                        ilg.EndFor();
                    }
                }
                else
                {
                    MethodInfo incrementCollectionCountMethod = null;
                    switch (collectionContract.Kind)
                    {
                    case CollectionKind.Collection:
                    case CollectionKind.List:
                    case CollectionKind.Dictionary:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                        break;

                    case CollectionKind.GenericCollection:
                    case CollectionKind.GenericList:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                        break;

                    case CollectionKind.GenericDictionary:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                        break;
                    }
                    if (incrementCollectionCountMethod != null)
                    {
                        ilg.Call(contextArg, incrementCollectionCountMethod, xmlWriterArg, objectLocal);
                    }

                    bool   isDictionary = false, isGenericDictionary = false;
                    Type   enumeratorType = null;
                    Type[] keyValueTypes  = null;
                    if (collectionContract.Kind == CollectionKind.GenericDictionary)
                    {
                        isGenericDictionary = true;
                        keyValueTypes       = collectionContract.ItemType.GetGenericArguments();
                        enumeratorType      = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                    }
                    else if (collectionContract.Kind == CollectionKind.Dictionary)
                    {
                        isDictionary   = true;
                        keyValueTypes  = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                        enumeratorType = Globals.TypeOfDictionaryEnumerator;
                    }
                    else
                    {
                        enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                    }
                    MethodInfo moveNextMethod   = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                    MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                    if (moveNextMethod == null || getCurrentMethod == null)
                    {
                        if (enumeratorType.IsInterface)
                        {
                            if (moveNextMethod == null)
                            {
                                moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod;
                            }
                            if (getCurrentMethod == null)
                            {
                                getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod;
                            }
                        }
                        else
                        {
                            Type           ienumeratorInterface = Globals.TypeOfIEnumerator;
                            CollectionKind kind = collectionContract.Kind;
                            if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                            {
                                Type[] interfaceTypes = enumeratorType.GetInterfaces();
                                foreach (Type interfaceType in interfaceTypes)
                                {
                                    if (interfaceType.IsGenericType &&
                                        interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric &&
                                        interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                    {
                                        ienumeratorInterface = interfaceType;
                                        break;
                                    }
                                }
                            }
                            if (moveNextMethod == null)
                            {
                                moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                            }
                            if (getCurrentMethod == null)
                            {
                                getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                            }
                        }
                    }
                    Type         elementType  = getCurrentMethod.ReturnType;
                    LocalBuilder currentValue = ilg.DeclareLocal(elementType, "currentValue");

                    LocalBuilder enumerator = ilg.DeclareLocal(enumeratorType, "enumerator");
                    ilg.Call(objectLocal, collectionContract.GetEnumeratorMethod);
                    if (isDictionary)
                    {
                        ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, Globals.TypeOfIDictionaryEnumerator);
                        ilg.New(XmlFormatGeneratorStatics.DictionaryEnumeratorCtor);
                    }
                    else if (isGenericDictionary)
                    {
                        Type            ctorParam    = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                        ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
                        ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, ctorParam);
                        ilg.New(dictEnumCtor);
                    }
                    ilg.Stloc(enumerator);

                    ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod);
                    if (incrementCollectionCountMethod == null)
                    {
                        ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                    }
                    if (!TryWritePrimitive(elementType, currentValue, null /*memberInfo*/, null /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/))
                    {
                        WriteStartElement(elementType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/);

                        if (isGenericDictionary || isDictionary)
                        {
                            ilg.Call(dataContractArg, XmlFormatGeneratorStatics.GetItemContractMethod);
                            ilg.Load(xmlWriterArg);
                            ilg.Load(currentValue);
                            ilg.ConvertValue(currentValue.LocalType, Globals.TypeOfObject);
                            ilg.Load(contextArg);
                            ilg.Call(XmlFormatGeneratorStatics.WriteXmlValueMethod);
                        }
                        else
                        {
                            WriteValue(currentValue, false /*writeXsiType*/);
                        }
                        WriteEndElement();
                    }
                    ilg.EndForEach(moveNextMethod);
                }
            }
        void WriteCollection(CollectionDataContract collectionContract)
        {
            XmlDictionaryString itemName = context.CollectionItemName;

            if (collectionContract.Kind == CollectionKind.Array)
            {
                Type itemType = collectionContract.ItemType;
                int  i;

                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (objLocal.GetType().GetElementType() != itemType)
                {
                    throw new InvalidCastException(string.Format("Cannot cast array of {0} to array of {1}", objLocal.GetType().GetElementType(), itemType));
                }

                context.IncrementArrayCount(writer, (Array)objLocal);

                if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, () => objLocal, itemName))
                {
                    WriteArrayAttribute();
                    var arr = (Array)objLocal;
                    var idx = new int [1];
                    for (i = 0; i < arr.Length; i++)
                    {
                        if (!TryWritePrimitive(itemType, null, null, i, itemName, 0))
                        {
                            WriteStartElement(itemName, 0);
                            idx [0] = i;
                            var mbrVal = arr.GetValue(idx);
                            WriteValue(itemType, mbrVal);
                            WriteEndElement();
                        }
                    }
                }
            }
            else
            {
                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (!collectionContract.UnderlyingType.IsAssignableFrom(objLocal.GetType()))
                {
                    throw new InvalidCastException(string.Format("Cannot cast {0} to {1}", objLocal.GetType(), collectionContract.UnderlyingType));
                }

                MethodInfo incrementCollectionCountMethod = null;
                switch (collectionContract.Kind)
                {
                case CollectionKind.Collection:
                case CollectionKind.List:
                case CollectionKind.Dictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                    break;

                case CollectionKind.GenericCollection:
                case CollectionKind.GenericList:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                    break;

                case CollectionKind.GenericDictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                    break;
                }
                if (incrementCollectionCountMethod != null)
                {
                    incrementCollectionCountMethod.Invoke(context, new object [] { writer, objLocal });
                }

                bool    isDictionary = false, isGenericDictionary = false;
                Type    enumeratorType = null;
                Type [] keyValueTypes  = null;
                if (collectionContract.Kind == CollectionKind.GenericDictionary)
                {
                    isGenericDictionary = true;
                    keyValueTypes       = collectionContract.ItemType.GetGenericArguments();
                    enumeratorType      = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                }
                else if (collectionContract.Kind == CollectionKind.Dictionary)
                {
                    isDictionary   = true;
                    keyValueTypes  = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                    enumeratorType = Globals.TypeOfDictionaryEnumerator;
                }
                else
                {
                    enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                }
                MethodInfo moveNextMethod   = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                if (moveNextMethod == null || getCurrentMethod == null)
                {
                    if (enumeratorType.IsInterface)
                    {
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = JsonFormatGeneratorStatics.MoveNextMethod;
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = JsonFormatGeneratorStatics.GetCurrentMethod;
                        }
                    }
                    else
                    {
                        Type           ienumeratorInterface = Globals.TypeOfIEnumerator;
                        CollectionKind kind = collectionContract.Kind;
                        if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                        {
                            Type[] interfaceTypes = enumeratorType.GetInterfaces();
                            foreach (Type interfaceType in interfaceTypes)
                            {
                                if (interfaceType.IsGenericType &&
                                    interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric &&
                                    interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                {
                                    ienumeratorInterface = interfaceType;
                                    break;
                                }
                            }
                        }
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                        }
                    }
                }
                Type   elementType  = getCurrentMethod.ReturnType;
                object currentValue = null;                 // of elementType

                var enumerator = (IEnumerator)collectionContract.GetEnumeratorMethod.Invoke(objLocal, new object [0]);
                if (isDictionary)
                {
                    ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { Globals.TypeOfIDictionaryEnumerator }, null);
                    enumerator = (IEnumerator)dictEnumCtor.Invoke(new object [] { enumerator });
                }
                else if (isGenericDictionary)
                {
                    Type            ctorParam    = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                    ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
                    enumerator = (IEnumerator)Activator.CreateInstance(enumeratorType, new object [] { enumerator });
                }

                bool canWriteSimpleDictionary = isDictionary || isGenericDictionary;

                bool         writeSimpleDictionary = canWriteSimpleDictionary && context.UseSimpleDictionaryFormat;
                PropertyInfo genericDictionaryKeyProperty = null, genericDictionaryValueProperty = null;

                if (canWriteSimpleDictionary)
                {
                    Type genericDictionaryKeyValueType = Globals.TypeOfKeyValue.MakeGenericType(keyValueTypes);
                    genericDictionaryKeyProperty   = genericDictionaryKeyValueType.GetProperty(JsonGlobals.KeyString);
                    genericDictionaryValueProperty = genericDictionaryKeyValueType.GetProperty(JsonGlobals.ValueString);
                }

                if (writeSimpleDictionary)
                {
                    WriteObjectAttribute();
                    object key, value;
                    var    empty_args = new object [0];
                    while ((bool)moveNextMethod.Invoke(enumerator, empty_args))
                    {
                        currentValue = getCurrentMethod.Invoke(enumerator, empty_args);
                        key          = CodeInterpreter.GetMember(genericDictionaryKeyProperty, currentValue);
                        value        = CodeInterpreter.GetMember(genericDictionaryValueProperty, currentValue);

                        WriteStartElement(key, 0 /*nameIndex*/);
                        WriteValue(genericDictionaryValueProperty.PropertyType, value);
                        WriteEndElement();
                    }
                }
                else
                {
                    WriteArrayAttribute();

                    var emptyArray = new object [0];
                    while (enumerator != null && enumerator.MoveNext())
                    {
                        currentValue = getCurrentMethod.Invoke(enumerator, emptyArray);

                        if (incrementCollectionCountMethod == null)
                        {
                            XmlFormatGeneratorStatics.IncrementItemCountMethod.Invoke(context, new object [] { 1 });
                        }

                        if (!TryWritePrimitive(elementType, () => currentValue, null, null, itemName, 0))
                        {
                            WriteStartElement(itemName, 0);
                            if (isGenericDictionary || isDictionary)
                            {
                                var jc = JsonDataContract.GetJsonDataContract(XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(
                                                                                  collectionDataContract.ItemContract));
                                // FIXME: this TypeHandle might be wrong; there is no easy way to get Type for currentValue though.
                                DataContractJsonSerializer.WriteJsonValue(jc, writer, currentValue, context, currentValue.GetType().TypeHandle);
                            }
                            else
                            {
                                WriteValue(elementType, currentValue);
                            }
                            WriteEndElement();
                        }
                    }
                }
            }
        }
Exemple #15
0
 private bool ReturnTypeMeetsFunctionImportBasicRequirements(
     SchemaType type,
     CollectionKind returnTypeCollectionKind)
 {
     return(type is ScalarType && returnTypeCollectionKind == CollectionKind.Bag || type is SchemaEntityType && returnTypeCollectionKind == CollectionKind.Bag || this.Schema.SchemaVersion == 1.1 && (type is ScalarType && returnTypeCollectionKind == CollectionKind.None || type is SchemaEntityType && returnTypeCollectionKind == CollectionKind.None || (type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.None || type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.Bag)) || (this.Schema.SchemaVersion >= 2.0 && type is SchemaComplexType && returnTypeCollectionKind == CollectionKind.Bag || this.Schema.SchemaVersion >= 3.0 && type is SchemaEnumType && returnTypeCollectionKind == CollectionKind.Bag));
 }
Exemple #16
0
        CollectionType CreateCollectionType(CollectionKind kind, Classifier type)
        {
            CollectionType collectionType = Library.CreateCollection(kind, type);

            return(collectionType);
        }
            private void WriteCollection(CollectionDataContract collectionContract)
            {
                LocalBuilder itemName = _ilg.DeclareLocal(typeof(XmlDictionaryString), "itemName");

                _ilg.Load(_contextArg);
                _ilg.LoadMember(JsonFormatGeneratorStatics.CollectionItemNameProperty);
                _ilg.Store(itemName);

                if (collectionContract.Kind == CollectionKind.Array)
                {
                    Type         itemType = collectionContract.ItemType;
                    LocalBuilder i        = _ilg.DeclareLocal(Globals.TypeOfInt, "i");

                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.IncrementArrayCountMethod, _xmlWriterArg, _objectLocal);

                    if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, _objectLocal, itemName))
                    {
                        WriteArrayAttribute();
                        _ilg.For(i, 0, _objectLocal);
                        if (!TryWritePrimitive(itemType, null /*value*/, null /*memberInfo*/, i /*arrayItemIndex*/, itemName, 0 /*nameIndex*/))
                        {
                            WriteStartElement(itemName, 0 /*nameIndex*/);
                            _ilg.LoadArrayElement(_objectLocal, i);
                            LocalBuilder memberValue = _ilg.DeclareLocal(itemType, "memberValue");
                            _ilg.Stloc(memberValue);
                            WriteValue(memberValue);
                            WriteEndElement();
                        }
                        _ilg.EndFor();
                    }
                }
                else
                {
                    MethodInfo incrementCollectionCountMethod = null;
                    switch (collectionContract.Kind)
                    {
                    case CollectionKind.Collection:
                    case CollectionKind.List:
                    case CollectionKind.Dictionary:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                        break;

                    case CollectionKind.GenericCollection:
                    case CollectionKind.GenericList:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                        break;

                    case CollectionKind.GenericDictionary:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                        break;
                    }
                    if (incrementCollectionCountMethod != null)
                    {
                        _ilg.Call(_contextArg, incrementCollectionCountMethod, _xmlWriterArg, _objectLocal);
                    }

                    bool   isDictionary = false, isGenericDictionary = false;
                    Type   enumeratorType = null;
                    Type[] keyValueTypes  = null;
                    if (collectionContract.Kind == CollectionKind.GenericDictionary)
                    {
                        isGenericDictionary = true;
                        keyValueTypes       = collectionContract.ItemType.GetGenericArguments();
                        enumeratorType      = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                    }
                    else if (collectionContract.Kind == CollectionKind.Dictionary)
                    {
                        isDictionary   = true;
                        keyValueTypes  = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                        enumeratorType = Globals.TypeOfDictionaryEnumerator;
                    }
                    else
                    {
                        enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                    }
                    MethodInfo moveNextMethod   = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, Array.Empty <Type>());
                    MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, Array.Empty <Type>());
                    if (moveNextMethod == null || getCurrentMethod == null)
                    {
                        if (enumeratorType.IsInterface)
                        {
                            if (moveNextMethod == null)
                            {
                                moveNextMethod = JsonFormatGeneratorStatics.MoveNextMethod;
                            }
                            if (getCurrentMethod == null)
                            {
                                getCurrentMethod = JsonFormatGeneratorStatics.GetCurrentMethod;
                            }
                        }
                        else
                        {
                            Type           ienumeratorInterface = Globals.TypeOfIEnumerator;
                            CollectionKind kind = collectionContract.Kind;
                            if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                            {
                                Type[] interfaceTypes = enumeratorType.GetInterfaces();
                                foreach (Type interfaceType in interfaceTypes)
                                {
                                    if (interfaceType.IsGenericType &&
                                        interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric &&
                                        interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                    {
                                        ienumeratorInterface = interfaceType;
                                        break;
                                    }
                                }
                            }
                            if (moveNextMethod == null)
                            {
                                moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                            }
                            if (getCurrentMethod == null)
                            {
                                getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                            }
                        }
                    }
                    Type         elementType  = getCurrentMethod.ReturnType;
                    LocalBuilder currentValue = _ilg.DeclareLocal(elementType, "currentValue");

                    LocalBuilder enumerator = _ilg.DeclareLocal(enumeratorType, "enumerator");
                    _ilg.Call(_objectLocal, collectionContract.GetEnumeratorMethod);
                    if (isDictionary)
                    {
                        ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, new Type[] { Globals.TypeOfIDictionaryEnumerator });
                        _ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, Globals.TypeOfIDictionaryEnumerator);
                        _ilg.New(dictEnumCtor);
                    }
                    else if (isGenericDictionary)
                    {
                        Type            ctorParam    = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                        ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, new Type[] { ctorParam });
                        _ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, ctorParam);
                        _ilg.New(dictEnumCtor);
                    }
                    _ilg.Stloc(enumerator);

                    bool canWriteSimpleDictionary = isDictionary || isGenericDictionary;
                    if (canWriteSimpleDictionary)
                    {
                        Type         genericDictionaryKeyValueType  = Globals.TypeOfKeyValue.MakeGenericType(keyValueTypes);
                        PropertyInfo genericDictionaryKeyProperty   = genericDictionaryKeyValueType.GetProperty(JsonGlobals.KeyString);
                        PropertyInfo genericDictionaryValueProperty = genericDictionaryKeyValueType.GetProperty(JsonGlobals.ValueString);

                        _ilg.Load(_contextArg);
                        _ilg.LoadMember(JsonFormatGeneratorStatics.UseSimpleDictionaryFormatWriteProperty);
                        _ilg.If();
                        WriteObjectAttribute();
                        LocalBuilder pairKey   = _ilg.DeclareLocal(Globals.TypeOfString, "key");
                        LocalBuilder pairValue = _ilg.DeclareLocal(keyValueTypes[1], "value");
                        _ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod);

                        _ilg.LoadAddress(currentValue);
                        _ilg.LoadMember(genericDictionaryKeyProperty);
                        _ilg.ToString(keyValueTypes[0]);
                        _ilg.Stloc(pairKey);

                        _ilg.LoadAddress(currentValue);
                        _ilg.LoadMember(genericDictionaryValueProperty);
                        _ilg.Stloc(pairValue);

                        WriteStartElement(pairKey, 0 /*nameIndex*/);
                        WriteValue(pairValue);
                        WriteEndElement();

                        _ilg.EndForEach(moveNextMethod);
                        _ilg.Else();
                    }

                    WriteArrayAttribute();

                    _ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod);
                    if (incrementCollectionCountMethod == null)
                    {
                        _ilg.Call(_contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                    }
                    if (!TryWritePrimitive(elementType, currentValue, null /*memberInfo*/, null /*arrayItemIndex*/, itemName, 0 /*nameIndex*/))
                    {
                        WriteStartElement(itemName, 0 /*nameIndex*/);

                        if (isGenericDictionary || isDictionary)
                        {
                            _ilg.Call(_dataContractArg, JsonFormatGeneratorStatics.GetItemContractMethod);
                            _ilg.Call(JsonFormatGeneratorStatics.GetRevisedItemContractMethod);
                            _ilg.Call(JsonFormatGeneratorStatics.GetJsonDataContractMethod);
                            _ilg.Load(_xmlWriterArg);
                            _ilg.Load(currentValue);
                            _ilg.ConvertValue(currentValue.LocalType, Globals.TypeOfObject);
                            _ilg.Load(_contextArg);
                            _ilg.Load(currentValue.LocalType);
                            _ilg.LoadMember(JsonFormatGeneratorStatics.TypeHandleProperty);
                            _ilg.Call(JsonFormatGeneratorStatics.WriteJsonValueMethod);
                        }
                        else
                        {
                            WriteValue(currentValue);
                        }
                        WriteEndElement();
                    }
                    _ilg.EndForEach(moveNextMethod);

                    if (canWriteSimpleDictionary)
                    {
                        _ilg.EndIf();
                    }
                }
            }
Exemple #18
0
            public PropertyTypeReferences(TypeReference typeReference, PrimitiveType primitiveType, CollectionKind collectionKind)
            {
                Type type = primitiveType.ClrEquivalentType;

                if (collectionKind == CollectionKind.None)
                {
                    _nonNullable = typeReference.ForType(type);
                    if (type.IsValueType)
                    {
                        _nullable = typeReference.NullableForType(type);
                    }
                    else
                    {
                        _nullable = typeReference.ForType(type);
                    }
                }
                else
                {
                    CodeTypeReference primitiveTypeRef = typeReference.ForType(type);
                    CodeTypeReference collectionType   = GetCollectionTypeReference(typeReference, primitiveTypeRef, collectionKind);
                    _nonNullable = collectionType;
                    _nullable    = collectionType;
                }
            }
 private void ValidateFunctionImportReturnType(SchemaElement owner, SchemaType returnType, CollectionKind returnTypeCollectionKind, EntityContainerEntitySet entitySet, bool entitySetPathDefined)
 {
     if (returnType != null && !ReturnTypeMeetsFunctionImportBasicRequirements(returnType, returnTypeCollectionKind))
     {
         owner.AddError(ErrorCode.FunctionImportUnsupportedReturnType,
             EdmSchemaErrorSeverity.Error,
             owner,
             GetReturnTypeErrorMessage(Schema.SchemaVersion, this.Name)
             );
     }
     ValidateFunctionImportReturnType(owner, returnType, entitySet, entitySetPathDefined);
 }
Exemple #20
0
            public PropertyTypeReferences(TypeReference typeReference, ComplexType complexType, CollectionKind collectionKind, ClientApiGenerator generator)
            {
                CodeTypeReference baseType = generator.GetLeastPossibleQualifiedTypeReference(complexType);

                baseType     = GetCollectionTypeReference(typeReference, baseType, collectionKind);
                _nonNullable = baseType;
                _nullable    = baseType;
            }
        private static TypeUsage GetFunctionTypeUsage(
            bool isModelFunction,
            Som.Function somFunction,
            Som.FacetEnabledSchemaElement somParameter,
            DbProviderManifest providerManifest,
            bool areConvertingForProviderManifest,
            Som.SchemaType type,
            CollectionKind collectionKind,
            bool isRefType,
            ConversionCache convertedItemCache,
            Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems)
        {
            if (null != somParameter && areConvertingForProviderManifest
                && somParameter.HasUserDefinedFacets)
            {
                return somParameter.TypeUsage;
            }

            if (null == type)
            {
                if (isModelFunction && somParameter != null
                    && somParameter is Som.Parameter)
                {
                    ((Som.Parameter)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return somParameter.TypeUsage;
                }
                else if (somParameter != null
                         && somParameter is Som.ReturnType)
                {
                    ((Som.ReturnType)somParameter).ResolveNestedTypeNames(convertedItemCache, newGlobalItems);
                    return somParameter.TypeUsage;
                }
                else
                {
                    return null;
                }
            }

            EdmType edmType;
            if (!areConvertingForProviderManifest)
            {
                // SOM verifies the type is either scalar, row, or entity
                var scalarType = type as Som.ScalarType;
                if (null != scalarType)
                {
                    if (isModelFunction && somParameter != null)
                    {
                        if (somParameter.TypeUsage == null)
                        {
                            somParameter.ValidateAndSetTypeUsage(scalarType);
                        }
                        return somParameter.TypeUsage;
                    }
                    else if (isModelFunction)
                    {
                        var modelFunction = somFunction as Som.ModelFunction;
                        if (modelFunction.TypeUsage == null)
                        {
                            modelFunction.ValidateAndSetTypeUsage(scalarType);
                        }
                        return modelFunction.TypeUsage;
                    }
                    else if (somParameter != null && somParameter.HasUserDefinedFacets
                             && somFunction.Schema.DataModel == Som.SchemaDataModelOption.ProviderDataModel)
                    {
                        somParameter.ValidateAndSetTypeUsage(scalarType);
                        return somParameter.TypeUsage;
                    }
                    else
                    {
                        edmType = GetPrimitiveType(scalarType, providerManifest);
                    }
                }
                else
                {
                    edmType = (EdmType)LoadSchemaElement(
                        type,
                        providerManifest,
                        convertedItemCache,
                        newGlobalItems);

                    // Neither FunctionImport nor its Parameters can have facets when defined in CSDL so for enums, 
                    // since they are only a CSpace concept, we need to process facets only on model functions 
                    if (isModelFunction && type is Som.SchemaEnumType)
                    {
                        Debug.Assert(somFunction.Schema.DataModel == Som.SchemaDataModelOption.EntityDataModel, "Enums live only in CSpace");

                        if (somParameter != null)
                        {
                            somParameter.ValidateAndSetTypeUsage(edmType);
                            return somParameter.TypeUsage;
                        }
                        else if (somFunction != null)
                        {
                            var modelFunction = ((Som.ModelFunction)somFunction);
                            modelFunction.ValidateAndSetTypeUsage(edmType);
                            return modelFunction.TypeUsage;
                        }
                        else
                        {
                            Debug.Fail("Should never get here.");
                        }
                    }
                }
            }
            else if (type is Som.TypeElement)
            {
                var typeElement = type as Som.TypeElement;
                edmType = typeElement.PrimitiveType;
            }
            else
            {
                var typeElement = type as Som.ScalarType;
                edmType = typeElement.Type;
            }

            //Construct type usage
            TypeUsage usage;
            if (collectionKind != CollectionKind.None)
            {
                usage = convertedItemCache.GetCollectionTypeUsageWithNullFacets(edmType);
            }
            else
            {
                var entityType = edmType as EntityType;
                if (entityType != null && isRefType)
                {
                    usage = TypeUsage.Create(new RefType(entityType));
                }
                else
                {
                    usage = convertedItemCache.GetTypeUsageWithNullFacets(edmType);
                }
            }

            return usage;
        }
Exemple #22
0
 private static CodeTypeReference GetCollectionTypeReference(TypeReference typeReference, CodeTypeReference baseType, CollectionKind collectionKind)
 {
     if (collectionKind == CollectionKind.Bag)
     {
         baseType = GetCollectionTypeReferenceForBagSemantics(typeReference, baseType);
     }
     else if (collectionKind == CollectionKind.List)
     {
         baseType = GetCollectionTypeReferenceForListSemantics(typeReference, baseType);
     }
     else
     {
         Debug.Assert(collectionKind == CollectionKind.None, "Was another CollectionKind value added");
         // nothing more to do for .None
     }
     return(baseType);
 }
Exemple #23
0
            public void ShouldSerialize(CollectionKind kind, string expected)
            {
                string actual = JsonConvert.SerializeObject(kind);

                Assert.Equal(expected, actual, ignoreLineEndingDifferences: true);
            }
Exemple #24
0
            public void ShouldDeserialize(string kind, CollectionKind expected)
            {
                CollectionKind actual = JsonConvert.DeserializeObject <CollectionKind>(kind);

                Assert.Equal(expected, actual);
            }
 /// <summary>
 /// Handles the Multiplicity attribute on the property.
 /// </summary>
 /// <param name="reader"></param>
 private void HandleCollectionKindAttribute(XmlReader reader)
 {
     string value = reader.Value;
     if (value == XmlConstants.CollectionKind_None)
     {
         _collectionKind = CollectionKind.None;
     }
     else
     {
         if (value == XmlConstants.CollectionKind_List)
         {
             _collectionKind = CollectionKind.List;
         }
         else if (value == XmlConstants.CollectionKind_Bag)
         {
             _collectionKind = CollectionKind.Bag;
         }
         else
         {
             Debug.Fail("Xsd should have changed", "XSD validation should have ensured that" +
                 " Multiplicity attribute has only 'None' or 'Bag' or 'List' as the values");
             return;
         }
     }
 }
 /// <summary>
 /// Initializes a new instance of the CollectionKindAnnotation class.
 /// </summary>
 /// <param name="kind">The collection kind.</param>
 public CollectionKindAnnotation(CollectionKind kind)
 {
     this.CollectionKind = kind;
 }