示例#1
0
        private void AddRootNamespaceField(CodeTypeDeclaration typeDecl)
        {
            // Add this field (VB declaration), where known client type name is ClientNS.BikesEntities
            // ROOTNAMESPACE = GetType(ClientNS.BikesEntities).Namespace.Remove(GetType(ClientNS.BikesEntities).Namespace.LastIndexOf("ClientNS"))

            EntityContainer container          = (EntityContainer)this.Item;
            string          containerNamespace = Generator.GetClientTypeNamespace(this.Generator.GetContainerNamespace(container));
            // VB-ism: if namespace and type names are the same (Blah.Blah), GetType(Blah.Blah) fails...
            string vbScopedcontainerName = (string.IsNullOrEmpty(containerNamespace) || container.Name.Equals(containerNamespace, StringComparison.OrdinalIgnoreCase))
                                           ? container.Name : (containerNamespace + "." + container.Name);


            CodeExpression namespaceAccess = new CodePropertyReferenceExpression(
                new CodeTypeOfExpression(vbScopedcontainerName),
                "Namespace");

            CodeMemberField rootNamespaceField = new CodeMemberField(
                TypeReference.ForType(typeof(string)),
                "ROOTNAMESPACE");

            rootNamespaceField.Attributes     = MemberAttributes.Static | MemberAttributes.Private;
            rootNamespaceField.InitExpression = new CodeMethodInvokeExpression(
                namespaceAccess,
                "Remove",
                new CodeMethodInvokeExpression(
                    namespaceAccess,
                    "LastIndexOf",
                    new CodePrimitiveExpression(containerNamespace)));
            AttributeEmitter.AddGeneratedCodeAttribute(rootNamespaceField);
            typeDecl.Members.Add(rootNamespaceField);
        }
示例#2
0
        /// <summary>
        /// Creates the necessary constructors for the entity container.
        /// </summary>
        private void CreateConstructors(CodeTypeDeclaration typeDecl, bool setupTypeMapper, bool hasInheritance)
        {
            // Constructor that takes a uri
            //
            // public ctor(System.Uri serviceRoot)
            //    : base(serviceRoot)
            // {
            //      this.OnContextCreated();
            // }
            CodeConstructor connectionWorkspaceCtor = new CodeConstructor();

            connectionWorkspaceCtor.Attributes = MemberAttributes.Public;
            CodeParameterDeclarationExpression connectionParam = new CodeParameterDeclarationExpression(TypeReference.FromString("System.Uri", true), "serviceRoot");

            connectionWorkspaceCtor.Parameters.Add(connectionParam);
            connectionWorkspaceCtor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression(connectionParam.Name));

            AttributeEmitter.AddGeneratedCodeAttribute(connectionWorkspaceCtor);

            CommentEmitter.EmitSummaryComments(Strings.CtorSummaryComment(Item.Name), connectionWorkspaceCtor.Comments);

            // If we have an externally provided namespage (e.g. from Visual Studio), we need to
            // inject a type-mapper because type names won't match between client and server
            if (setupTypeMapper || hasInheritance)
            {
                connectionWorkspaceCtor.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(ThisRef, "ResolveName"),
                        new CodeDelegateCreateExpression(
                            TypeReference.ForType(typeof(Func <,>), TypeReference.ForType(typeof(Type)), TypeReference.ForType(typeof(String))),
                            ThisRef,
                            "ResolveNameFromType"
                            )
                        )
                    );
            }

            if (setupTypeMapper)
            {
                connectionWorkspaceCtor.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(ThisRef, "ResolveType"),
                        new CodeDelegateCreateExpression(
                            TypeReference.ForType(typeof(Func <,>), TypeReference.ForType(typeof(String)), TypeReference.ForType(typeof(Type))),
                            ThisRef,
                            "ResolveTypeFromName"
                            )
                        )
                    );
            }

            connectionWorkspaceCtor.Statements.Add(OnContextCreatedCodeMethodInvokeExpression());

            typeDecl.Members.Add(connectionWorkspaceCtor);
        }
示例#3
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;
                }
            }
示例#4
0
 private CodeExpression LanguageSpecificNamespace(string ns)
 {
     if (this.Generator.Language == LanguageOption.GenerateVBCode)
     {
         return(new CodeMethodInvokeExpression(
                    new CodeTypeReferenceExpression(TypeReference.ForType(typeof(string))),
                    "Concat",
                    new CodeVariableReferenceExpression("ROOTNAMESPACE"),
                    new CodePrimitiveExpression(ns)));
     }
     else
     {
         return(new CodePrimitiveExpression(ns));
     }
 }
示例#5
0
        private void EmitField(CodeTypeDeclaration typeDecl, CodeTypeReference fieldType)
        {
            CodeMemberField memberField = new CodeMemberField(fieldType, FieldName);

            memberField.Attributes = MemberAttributes.Private;
            if (HasDefault(Item))
            {
                memberField.InitExpression = GetDefaultValueExpression(Item);
            }

            AttributeEmitter.AddGeneratedCodeAttribute(memberField);

            typeDecl.Members.Add(memberField);

            if (TypeSemantics.IsComplexType(Item.TypeUsage))
            {
                CodeMemberField complexInitField = new CodeMemberField(TypeReference.ForType(typeof(bool)), ComplexPropertyInitializedFieldName);
                complexInitField.Attributes = MemberAttributes.Private;
                AttributeEmitter.AddGeneratedCodeAttribute(complexInitField);
                typeDecl.Members.Add(complexInitField);
            }
        }
示例#6
0
        private void CreateFunctionArgument(CodeMemberMethod method, UniqueIdentifierService uniqueIdentifierService, FunctionParameter parameter)
        {
            // get type of parameter
            Type clrType = DetermineParameterType(parameter);

            // parameters to stored procedures must be nullable
            CodeTypeReference argumentType  = clrType.IsValueType ? TypeReference.NullableForType(clrType) : TypeReference.ForType(clrType);
            string            parameterName = uniqueIdentifierService.AdjustIdentifier(parameter.Name, parameter);
            CodeParameterDeclarationExpression codeParameter = new CodeParameterDeclarationExpression(argumentType, parameterName);

            method.Parameters.Add(codeParameter);
        }
示例#7
0
        private CodeExpression CreateFunctionParameter(CodeMemberMethod method, UniqueIdentifierService uniqueIdentifierService, FunctionParameter parameter)
        {
            // get (adjusted) name of parameter
            string adjustedParameterName;

            if (!uniqueIdentifierService.TryGetAdjustedName(parameter, out adjustedParameterName))
            {
                Debug.Fail("parameter must be registered in identifier service");
            }
            Type parameterType = DetermineParameterType(parameter);

            // make sure the variable name does not collide with any parameters to the method, or any
            // existing variables (all registered in the service)
            string variableName = uniqueIdentifierService.AdjustIdentifier(parameter.Name + "Parameter");

            // ObjectParameter variableName;
            // if (null != parameterName)
            // {
            //     variableName = new ObjectParameter("parameterName", adjustedParameterName);
            // }
            // else
            // {
            //     variableName = new ObjectParameter("parameterName", typeof(parameterType));
            // }
            method.Statements.Add(
                new CodeVariableDeclarationStatement(TypeReference.ForType(typeof(ObjectParameter)), variableName));
            CodeExpression variableReference  = new CodeVariableReferenceExpression(variableName);
            CodeExpression parameterReference = new CodeVariableReferenceExpression(adjustedParameterName);
            CodeStatement  nullConstructor    = new CodeAssignStatement(variableReference,
                                                                        new CodeObjectCreateExpression(TypeReference.ForType(typeof(ObjectParameter)),
                                                                                                       new CodePrimitiveExpression(parameter.Name),
                                                                                                       new CodeTypeOfExpression(TypeReference.ForType(parameterType))));
            CodeStatement valueConstructor = new CodeAssignStatement(variableReference,
                                                                     new CodeObjectCreateExpression(TypeReference.ForType(typeof(ObjectParameter)),
                                                                                                    new CodePrimitiveExpression(parameter.Name),
                                                                                                    parameterReference));
            CodeExpression notNullCondition;

            if (parameterType.IsValueType)
            {
                // Value type parameters generate Nullable<ValueType> arguments (see CreateFunctionArgument).
                // We call Nullable<ValueType>.HasValue to determine whether the argument passed in is null
                // (since null != nullableTypeInstance does not work in VB)
                //
                // parameterReference.HasValue
                notNullCondition = new CodePropertyReferenceExpression(
                    parameterReference,
                    "HasValue");
            }
            else
            {
                // use parameterReference != null
                notNullCondition = new CodeBinaryOperatorExpression(
                    parameterReference,
                    CodeBinaryOperatorType.IdentityInequality,
                    NullExpression);
            }
            method.Statements.Add(
                new CodeConditionStatement(
                    notNullCondition,
                    new CodeStatement[] { valueConstructor, },
                    new CodeStatement[] { nullConstructor, }
                    )
                );
            return(variableReference);
        }
        /// <summary>
        /// Emit static factory method which creates an instance of the class and initializes
        /// non-nullable properties (taken as arguments)
        /// </summary>
        /// <param name="typeDecl"></param>
        protected virtual void EmitFactoryMethod(CodeTypeDeclaration typeDecl)
        {
            // build list of non-nullable properties
            ReadOnlyMetadataCollection <EdmProperty> properties = GetProperties();
            List <EdmProperty> parameters = new List <EdmProperty>(properties.Count);

            foreach (EdmProperty property in properties)
            {
                bool include = IncludeFieldInFactoryMethod(property);
                if (include)
                {
                    parameters.Add(property);
                }
            }

            // if there are no parameters, we don't emit anything (1 is for the null element)
            // nor do we emit everything if this is the Ref propertied ctor and the parameter list is the same as the many parametered ctor
            if (parameters.Count < 1)
            {
                return;
            }

            CodeMemberMethod        method  = new CodeMemberMethod();
            CodeTypeReference       typeRef = TypeReference.FromString(Item.Name);
            UniqueIdentifierService uniqueIdentifierService = new UniqueIdentifierService(Generator.IsLanguageCaseSensitive);
            string instanceName = uniqueIdentifierService.AdjustIdentifier(Utils.CamelCase(Item.Name));

            // public static Class CreateClass(...)
            method.Attributes = MemberAttributes.Static | MemberAttributes.Public;
            method.Name       = "Create" + Item.Name;
            if (NavigationPropertyEmitter.IsNameAlreadyAMemberName(Item, method.Name, Generator.LanguageAppropriateStringComparer))
            {
                Generator.AddError(Strings.GeneratedFactoryMethodNameConflict(method.Name, Item.Name),
                                   ModelBuilderErrorCode.GeneratedFactoryMethodNameConflict,
                                   EdmSchemaErrorSeverity.Error);
            }

            method.ReturnType = typeRef;
            AttributeEmitter.AddGeneratedCodeAttribute(method);

            // output method summary comments
            CommentEmitter.EmitSummaryComments(Strings.FactoryMethodSummaryComment(Item.Name), method.Comments);


            // Class class = new Class();
            CodeVariableDeclarationStatement createNewInstance = new CodeVariableDeclarationStatement(
                typeRef, instanceName, new CodeObjectCreateExpression(typeRef));

            method.Statements.Add(createNewInstance);
            CodeVariableReferenceExpression instanceRef = new CodeVariableReferenceExpression(instanceName);

            // iterate over the properties figuring out which need included in the factory method
            foreach (EdmProperty property in parameters)
            {
                // CreateClass( ... , propType propName ...)
                PropertyEmitter   propertyEmitter       = new PropertyEmitter(Generator, property, UsingStandardBaseClass);
                CodeTypeReference propertyTypeReference = propertyEmitter.PropertyType;
                String            parameterName         = uniqueIdentifierService.AdjustIdentifier(Utils.FixParameterName(propertyEmitter.PropertyName, "argument"));
                parameterName = Utils.SetSpecialCaseForFxCopOnPropertyName(parameterName);
                CodeParameterDeclarationExpression paramDecl = new CodeParameterDeclarationExpression(
                    propertyTypeReference, parameterName);
                CodeArgumentReferenceExpression paramRef = new CodeArgumentReferenceExpression(paramDecl.Name);
                method.Parameters.Add(paramDecl);

                // add comment describing the parameter
                CommentEmitter.EmitParamComments(paramDecl, Strings.FactoryParamCommentGeneral(propertyEmitter.PropertyName), method.Comments);

                CodeExpression newPropertyValue;
                if (TypeSemantics.IsComplexType(propertyEmitter.Item.TypeUsage))
                {
                    List <CodeExpression> complexVerifyParameters = new List <CodeExpression>();
                    complexVerifyParameters.Add(paramRef);
                    complexVerifyParameters.Add(new CodePrimitiveExpression(propertyEmitter.PropertyName));

                    // if (null == param) { throw new ArgumentNullException("PropertyName"); }
                    method.Statements.Add(
                        new CodeConditionStatement(
                            EmitExpressionEqualsNull(paramRef),
                            new CodeThrowExceptionStatement(
                                new CodeObjectCreateExpression(
                                    TypeReference.ForType(typeof(ArgumentNullException)),
                                    new CodePrimitiveExpression(parameterName)
                                    )
                                )
                            )
                        );

                    newPropertyValue = paramRef;
                }
                else
                {
                    newPropertyValue = paramRef;
                }

                // Scalar property:
                //     Property = param;
                // Complex property:
                //     Property = StructuralObject.VerifyComplexObjectIsNotNull(param, propertyName);

                method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(instanceRef, propertyEmitter.PropertyName), newPropertyValue));
            }

            // return class;
            method.Statements.Add(new CodeMethodReturnStatement(instanceRef));

            // actually add the method to the class
            typeDecl.Members.Add(method);
        }
示例#9
0
            private static CodeTypeReference GetCollectionTypeReferenceForListSemantics(TypeReference typeReference, CodeTypeReference baseType)
            {
                CodeTypeReference typeRef = typeReference.ForType(typeof(System.Collections.Generic.IList <>), baseType);

                return(typeRef);
            }
示例#10
0
        private CodeExpression GetEnumValue <T>(T value)
        {
            Type type = typeof(T);

            return(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(TypeReference.ForType(type)), Enum.GetName(type, value)));
        }
示例#11
0
 /// <summary>
 /// Get a reference to the base class DataObject
 /// </summary>
 public static CodeTypeReferenceExpression CreateEdmStructuralObjectRef(TypeReference typeReference)
 {
     return(new CodeTypeReferenceExpression(typeReference.ForType(typeof(System.Data.Objects.DataClasses.StructuralObject))));
 }
示例#12
0
        private void CreateTypeMappingMethods(CodeTypeDeclaration typeDecl, bool needTypeMapper, bool hasInheritance)
        {
            // Special case to compensate for VB's "root namespace" feature.
            if (this.Generator.Language == LanguageOption.GenerateVBCode)
            {
                AddRootNamespaceField(typeDecl);
            }

            CodeExpression comparisonExpression = new CodePropertyReferenceExpression(
                new CodeTypeReferenceExpression(TypeReference.ForType(typeof(StringComparison))),
                Enum.GetName(typeof(StringComparison), this.Generator.LanguageAppropriateStringComparer));

            if (needTypeMapper)
            {
                CodeMemberMethod resolveTypeFromName = new CodeMemberMethod();
                resolveTypeFromName.Name       = "ResolveTypeFromName";
                resolveTypeFromName.Attributes = MemberAttributes.Final | MemberAttributes.Family;
                resolveTypeFromName.Parameters.Add(new CodeParameterDeclarationExpression(TypeReference.ForType(typeof(string)), "typeName"));
                resolveTypeFromName.ReturnType = TypeReference.ForType(typeof(Type));
                AttributeEmitter.AddGeneratedCodeAttribute(resolveTypeFromName);
                CommentEmitter.EmitSummaryComments(Strings.TypeMapperDescription, resolveTypeFromName.Comments);

                // NOTE: since multiple namespaces can have the same prefix and match the namespace
                // prefix condition, it's important that the prefix check is done is prefix-length
                // order, starting with the longest prefix.
                var pairs = this.Generator.NamespaceMap.OrderByDescending(p => p.Key.Length).ThenBy(p => p.Key);

                foreach (var pair in pairs)
                {
                    // Assuming pair.Key is "abc" and pair.Value is "def" and len(def)=3, generate:
                    // if (typeName.StartsWith("abc", StringComparison.Ordinal))
                    //     return this.GetType().Assembly.GetType(string.Concat("def", typeName.Substring(3)), false)
                    // DEVNOTE(Microsoft): we should use GetType(xxx, FALSE) here so it will not throw and fall back to null
                    // GetType(type, bool throw, bool ignoreCase) does not exist in SL, do not use!
                    resolveTypeFromName.Statements.Add(
                        new CodeConditionStatement(
                            new CodeMethodInvokeExpression(
                                new CodeVariableReferenceExpression("typeName"),
                                "StartsWith",
                                new CodePrimitiveExpression(pair.Key),
                                comparisonExpression
                                ),
                            new CodeMethodReturnStatement(
                                new CodeMethodInvokeExpression(
                                    new CodePropertyReferenceExpression(
                                        new CodeMethodInvokeExpression(
                                            ThisRef,
                                            "GetType"
                                            ),
                                        "Assembly"
                                        ),
                                    "GetType",
                                    new CodeMethodInvokeExpression(
                                        new CodeTypeReferenceExpression(TypeReference.ForType(typeof(string))),
                                        "Concat",
                                        this.LanguageSpecificNamespace(pair.Value),
                                        new CodeMethodInvokeExpression(
                                            new CodeVariableReferenceExpression("typeName"),
                                            "Substring",
                                            new CodePrimitiveExpression(pair.Key.Length)
                                            )
                                        ),
                                    new CodePrimitiveExpression(false)
                                    )
                                )
                            )
                        );
                }

                resolveTypeFromName.Statements.Add(
                    new CodeMethodReturnStatement(
                        new CodePrimitiveExpression(null)));

                typeDecl.Members.Add(resolveTypeFromName);
            }

            CodeMemberMethod resolveNameFromType = new CodeMemberMethod();

            resolveNameFromType.Name       = "ResolveNameFromType";
            resolveNameFromType.Attributes = MemberAttributes.Final | MemberAttributes.Family;
            resolveNameFromType.Parameters.Add(new CodeParameterDeclarationExpression(TypeReference.ForType(typeof(Type)), "clientType"));
            resolveNameFromType.ReturnType = TypeReference.ForType(typeof(String));
            AttributeEmitter.AddGeneratedCodeAttribute(resolveNameFromType);
            CommentEmitter.EmitSummaryComments(Strings.TypeMapperDescription, resolveNameFromType.Comments);

            // NOTE: in this case order also matters, but the length of the CLR
            // namespace is what needs to be considered.
            var reversePairs = Generator.NamespaceMap.OrderByDescending(p => p.Value.Length).ThenBy(p => p.Key);

            foreach (var pair in reversePairs)
            {
                // Assuming pair.Key is "abc" and pair.Value is "def", generate:
                // if (t.Namespace.Equals("def", StringComparison.Ordinal)) return string.Concat("abc.", t.Name);

                resolveNameFromType.Statements.Add(
                    new CodeConditionStatement(
                        new CodeMethodInvokeExpression(
                            new CodePropertyReferenceExpression(
                                new CodeVariableReferenceExpression("clientType"),
                                "Namespace"
                                ),
                            "Equals",
                            this.LanguageSpecificNamespace(pair.Value),
                            comparisonExpression
                            ),
                        new CodeMethodReturnStatement(
                            new CodeMethodInvokeExpression(
                                new CodeTypeReferenceExpression(TypeReference.ForType(typeof(string))),
                                "Concat",
                                new CodePrimitiveExpression(pair.Key + "."),
                                new CodePropertyReferenceExpression(
                                    new CodeVariableReferenceExpression("clientType"),
                                    "Name"
                                    )
                                )
                            )
                        )
                    );
            }

            if (hasInheritance)
            {
                CodeExpression clientTypeFullName = new CodePropertyReferenceExpression(
                    new CodeVariableReferenceExpression("clientType"),
                    "FullName");

                if (this.Generator.Language == LanguageOption.GenerateVBCode)
                {
                    // return clientType.FullName.Substring(ROOTNAMESPACE.Length);
                    resolveNameFromType.Statements.Add(
                        new CodeMethodReturnStatement(
                            new CodeMethodInvokeExpression(
                                clientTypeFullName,
                                "Substring",
                                new CodePropertyReferenceExpression(
                                    new CodeVariableReferenceExpression("ROOTNAMESPACE"),
                                    "Length"
                                    )
                                )
                            )
                        );
                }
                else
                {
                    // return clientType.FullName;
                    resolveNameFromType.Statements.Add(new CodeMethodReturnStatement(clientTypeFullName));
                }
            }
            else
            {
                resolveNameFromType.Statements.Add(
                    new CodeMethodReturnStatement(
                        NullExpression
                        )
                    );
            }

            typeDecl.Members.Add(resolveNameFromType);
        }