/// <summary>
        /// Verification code invoked for entity sets
        /// </summary>
        /// <param name="item">The entity container being generated</param>
        internal void VerifyLanguageCaseSensitiveCompatibilityForEntitySet(System.Data.Metadata.Edm.EntityContainer item)
        {
            if (_isLanguageCaseSensitive)
            {
                return; // no validation necessary
            }

            Debug.Assert(item != null);

            HashSet <string> set = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (EntitySetBase entitySetBase in item.BaseEntitySets)
            {
                if (MetadataUtil.IsEntitySet(entitySetBase))
                {
                    EntitySet entitySet = (EntitySet)entitySetBase;
                    if (set.Contains(entitySet.Identity))
                    {
                        AddError(ModelBuilderErrorCode.IncompatibleSettingForCaseSensitiveOption,
                                 EdmSchemaErrorSeverity.Error, new InvalidOperationException(Strings.EntitySetExistsWithDifferentCase(entitySet.Identity)),
                                 item.Name);
                    }
                    else
                    {
                        set.Add(entitySet.Identity);
                    }
                }
            }
        }
示例#2
0
 private static bool IsModule(Type type)
 {
     return(type.IsClass &&
            type.IsSealed &&
            !type.IsNestedPublic &&
            MetadataUtil.IsAttributeDefined(type, Types.ModuleAttribute));
 }
示例#3
0
        /// <summary>
        /// emit all the documentation comments for an element's documentation child
        /// (if the element does not have a documentation child emit some standard "missing comments" comment
        /// </summary>
        /// <param name="element">the element whose documentation is to be displayed</param>
        /// <param name="commentCollection">the comment collection of the CodeDom object to be commented</param>
        public static void EmitSummaryComments(MetadataItem item, CodeCommentStatementCollection commentCollection)
        {
            Debug.Assert(item != null, "item parameter is null");
            Debug.Assert(commentCollection != null, "commentCollection parameter is null");

            Documentation documentation = GetDocumentation(item);

            string [] summaryComments = null;
            if (documentation != null && !MetadataUtil.IsNullOrEmptyOrWhiteSpace(documentation.Summary))
            {
                // we have documentation to emit
                summaryComments = GetFormattedLines(documentation.Summary, true);
            }
            else
            {
                string summaryComment;
                // no summary content, so use a default
                switch (item.BuiltInTypeKind)
                {
                case BuiltInTypeKind.EdmProperty:
                    summaryComment = Strings.MissingPropertyDocumentation(((EdmProperty)item).Name);
                    break;

                case BuiltInTypeKind.ComplexType:
                    summaryComment = Strings.MissingComplexTypeDocumentation(((ComplexType)item).FullName);
                    break;

                default:
                {
                    PropertyInfo pi = item.GetType().GetProperty("FullName");
                    if (pi == null)
                    {
                        pi = item.GetType().GetProperty("Name");
                    }

                    object value = null;
                    if (pi != null)
                    {
                        value = pi.GetValue(item, null);
                    }


                    if (value != null)
                    {
                        summaryComment = Strings.MissingDocumentation(value.ToString());
                    }
                    else
                    {
                        summaryComment = Strings.MissingDocumentationNoName;
                    }
                }
                break;
                }
                summaryComments = new string[] { summaryComment };
            }
            EmitSummaryComments(summaryComments, commentCollection);
            EmitOtherDocumentationComments(documentation, commentCollection);
        }
示例#4
0
        private static bool HasModuleMarkerAttribute(Type type)
        {
#if DNXCORE50
            return(MetadataUtil.IsAttributeDefined(type.GetTypeInfo(), Types.ModuleAttribute) ||
                   MetadataUtil.IsAttributeDefined(type.GetTypeInfo(), Types.ClrExtensionAttribute));
#else
            return(MetadataUtil.IsAttributeDefined(type, Types.ModuleAttribute) ||
                   MetadataUtil.IsAttributeDefined(type, Types.ClrExtensionAttribute));
#endif
        }
示例#5
0
        public bool IsDefined(IType attributeType)
        {
            ExternalType type = attributeType as ExternalType;

            if (null == type)
            {
                return(false);
            }
            return(MetadataUtil.IsAttributeDefined(_type, type.ActualType));
        }
示例#6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="element"></param>
        /// <param name="modelType"></param>
        /// <returns></returns>
        public static bool TryGetPrimitiveTypeKind(EdmType type, out PrimitiveTypeKind modelType)
        {
            if (!MetadataUtil.IsPrimitiveType(type))
            {
                // set it to something bogus because I have to
                modelType = PrimitiveTypeKind.Binary;
                return(false);
            }

            modelType = ((PrimitiveType)type).PrimitiveTypeKind;
            return(true);
        }
示例#7
0
        /// <summary>
        /// Emit the set statements for a property that is a scalar type
        /// </summary>
        /// <param name="statements">The statement collection to add the set statements to.</param>
        private void EmitScalarTypePropertySetStatements(CodeStatementCollection statements,
                                                         CollectionKind collectionKind)
        {
            Debug.Assert(statements != null, "statments can't be null");
            Debug.Assert(((MetadataUtil.IsPrimitiveType(Item.TypeUsage.EdmType)) || (MetadataUtil.IsCollectionType(Item.TypeUsage.EdmType)))
                         , "Must be a primitive type or collection type property");

            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)
            {
                PrimitiveType primitiveType = (PrimitiveType)Item.TypeUsage.EdmType;

                // basic pattern
                // this.fieldName = SetValidValue( value );
                //
                List <CodeExpression> parameters = new List <CodeExpression>();
                parameters.Add(valueRef);


                // pattern for non Nullable<T> types (string, byte[])
                //
                // this.fieldName = SetValidVaue( value, nullability );

                if (primitiveType.ClrEquivalentType.IsClass)
                {
                    // ref types have an extra boolean parameter to tell if the property is allowed to
                    // be null or not
                    parameters.Add(new CodePrimitiveExpression(Item.Nullable));
                }

                // now create and add the built statement
                statements.Add(
                    new CodeAssignStatement(
                        FieldRef,
                        new CodeMethodInvokeExpression(
                            CreateEdmStructuralObjectRef(TypeReference),
                            Utils.SetValidValueMethodName,
                            parameters.ToArray())));
            }
            else
            {
                // this.fieldName = value;
                statements.Add(
                    new CodeAssignStatement(
                        FieldRef, valueRef));
            }
        }
示例#8
0
        private CodeTypeReference GetType(EdmProperty property, bool getElementType)
        {
            PropertyTypeReferences types = default(PropertyTypeReferences);
            EdmType propertyType         = property.TypeUsage.EdmType;

            // Initialize types
            if (MetadataUtil.IsPrimitiveType(propertyType))
            {
                types = new PropertyTypeReferences(TypeReference, (PrimitiveType)propertyType);
            }
            else if (MetadataUtil.IsComplexType(propertyType))
            {
                types = new PropertyTypeReferences(TypeReference, (ComplexType)propertyType, Generator);
            }
            else if (Helper.IsCollectionType(propertyType))
            {
                TypeUsage typeUsage = ((CollectionType)propertyType).TypeUsage;
                if (MetadataUtil.IsPrimitiveType(typeUsage.EdmType))
                {
                    types = new PropertyTypeReferences(TypeReference, (PrimitiveType)typeUsage.EdmType, GetCollectionKind(property.TypeUsage));
                }
                else
                {
                    Debug.Assert(MetadataUtil.IsComplexType(typeUsage.EdmType));
                    types = new PropertyTypeReferences(TypeReference, (ComplexType)typeUsage.EdmType, GetCollectionKind(property.TypeUsage), Generator);
                }
            }
            else
            {
                // shouldn't be able to get here....
                Debug.Fail("Unexpected Property.Type type: " + propertyType.GetType());
            }

            // Set types, or retrieve existing types if they have been set in the interim
            // Don't cache Collection types since CollectionKind is really a facet and
            //it is not part of the key we are using for the dictionary used to cache.
            if (!Helper.IsCollectionType(propertyType))
            {
                Debug.Assert(types.NonNullable != null && types.Nullable != null, "did you forget to set the types variable?");
            }

            if (property.Nullable)
            {
                return(types.Nullable);
            }
            else
            {
                return(types.NonNullable);
            }
        }
示例#9
0
        private void EmitPropertyGetterBody(CodeStatementCollection statements)
        {
            // If the SchemaElement.Type isn't a ComplexType it better be PrimitiveType.
            if (MetadataUtil.IsComplexType(Item.TypeUsage.EdmType))
            {
                //Since Complex 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 (GetCollectionKind(Item.TypeUsage) == CollectionKind.None)
                {
                    // _field = GetValidValue( _field, FieldPropertyInfo, _fieldInitialized);
                    statements.Add(
                        new CodeAssignStatement(FieldRef,
                                                new CodeMethodInvokeExpression(
                                                    ThisRef,
                                                    Utils.GetValidValueMethodName,
                                                    new CodeDirectionExpression(FieldDirection.In, FieldRef),
                                                    new CodePrimitiveExpression(PropertyName),
                                                    new CodePrimitiveExpression(Item.Nullable),
                                                    ComplexPropertyInitializedFieldRef)));

                    // this._complexPropertyInitialized = true;
                    statements.Add(
                        new CodeAssignStatement(
                            ComplexPropertyInitializedFieldRef,
                            new CodePrimitiveExpression(true)));
                }
                // return _field;
                statements.Add(new CodeMethodReturnStatement(FieldRef));
            }
            else
            {
                PrimitiveType primitiveType = Item.TypeUsage.EdmType as PrimitiveType;
                if (primitiveType != null && primitiveType.ClrEquivalentType == typeof(byte[]))
                {
                    // return GetValidValue(_field);
                    statements.Add(
                        new CodeMethodReturnStatement(
                            new CodeMethodInvokeExpression(
                                CreateEdmStructuralObjectRef(TypeReference),
                                Utils.GetValidValueMethodName,
                                this.FieldRef)));
                }
                else
                {
                    // for everything else just return the field.
                    statements.Add(new CodeMethodReturnStatement(FieldRef));
                }
            }
        }
示例#10
0
 /// <summary>
 /// Verify that Entity Set and Type have compatible accessibilty.
 /// They are compatible if the generated code will compile.
 /// </summary>
 private void VerifyEntityTypeAndSetAccessibilityCompatability()
 {
     foreach (EntitySetBase entitySetBase in Item.BaseEntitySets)
     {
         if (MetadataUtil.IsEntitySet(entitySetBase))
         {
             EntitySet set = (EntitySet)entitySetBase;
             if (!AreTypeAndSetAccessCompatible(GetEntityTypeAccessibility(set.ElementType), GetEntitySetPropertyAccessibility(set)))
             {
                 Generator.AddError(
                     System.Data.Entity.Design.Strings.EntityTypeAndSetAccessibilityConflict(
                         set.ElementType.Name, GetAccessibilityCsdlStringFromMemberAttribute(GetEntityTypeAccessibility(set.ElementType)), set.Name, GetAccessibilityCsdlStringFromMemberAttribute(GetEntitySetPropertyAccessibility(set))),
                     ModelBuilderErrorCode.EntityTypeAndSetAccessibilityConflict,
                     EdmSchemaErrorSeverity.Error);
             }
         }
     }
 }
示例#11
0
        // requires: parameter type is constrained to be a scalar type
        // Determines CLR type for function parameter
        private static Type DetermineParameterType(FunctionParameter parameter)
        {
            Debug.Assert(null != parameter && MetadataUtil.IsPrimitiveType(parameter.TypeUsage.EdmType),
                         "validation must ensure only scalar type parameter are given");

            if (parameter.Mode != ParameterMode.In)
            {
                // non input parameter must be treated as ObjectParameter instances so that the
                // value can be set asynchronously (after the method has yielded and the reader
                // has been consumed)
                return(typeof(ObjectParameter));
            }

            PrimitiveType parameterType = (PrimitiveType)parameter.TypeUsage.EdmType;
            Type          clrType       = parameterType.ClrType;

            return(clrType);
        }
示例#12
0
        private void EmitField(CodeTypeDeclaration typeDecl, CodeTypeReference fieldType)
        {
            CodeMemberField memberField = new CodeMemberField(fieldType, FieldName);

            Generator.AttributeEmitter.EmitGeneratedCodeAttribute(memberField);

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

            typeDecl.Members.Add(memberField);

            if (MetadataUtil.IsComplexType(Item.TypeUsage.EdmType))
            {
                CodeMemberField complexInitField = new CodeMemberField(TypeReference.ForType(typeof(bool)), ComplexPropertyInitializedFieldName);
                Generator.AttributeEmitter.EmitGeneratedCodeAttribute(complexInitField);
                complexInitField.Attributes = MemberAttributes.Private;
                typeDecl.Members.Add(complexInitField);
            }
        }
 private static EntityConnection CreateStoreSchemaConnection(string providerInvariantName, string connectionString, out Version storeSchemaModelVersion)
 {
     // We are going to try loading all versions of the store schema model starting from the newest.
     // The first version of the model that was shipped with EntityFrameworkVersions.Version1 and EntityFrameworkVersions.Version2 is the last one
     // we try, if it fails to load let the exception to propagate up to the caller.
     foreach (var version in EntityFrameworkVersions.ValidVersions.Where(v => v > EntityFrameworkVersions.Version2).OrderByDescending(v => v))
     {
         try
         {
             storeSchemaModelVersion = version;
             return(EntityStoreSchemaGenerator.CreateStoreSchemaConnection(providerInvariantName, connectionString, storeSchemaModelVersion));
         }
         catch (Exception e)
         {
             // Ignore the exception with the current version and try the next one.
             if (!MetadataUtil.IsCatchableExceptionType(e))
             {
                 throw;
             }
         }
     }
     storeSchemaModelVersion = EntityFrameworkVersions.Version2;
     return(EntityStoreSchemaGenerator.CreateStoreSchemaConnection(providerInvariantName, connectionString, storeSchemaModelVersion));
 }
示例#14
0
        private void GenerateCodeCommon(MetadataArtifactLoader sourceLoader,
                                        List <MetadataArtifactLoader> loaders,
                                        LazyTextWriterCreator target,
                                        string sourceEdmSchemaFilePath,
                                        string targetFilePath,
                                        bool closeReaders,
                                        List <EdmSchemaError> errors)
        {
            MetadataArtifactLoaderComposite composite = new MetadataArtifactLoaderComposite(loaders);

            // create the schema manager from the xml readers
            Dictionary <MetadataArtifactLoader, XmlReader> readerSourceMap = new Dictionary <MetadataArtifactLoader, XmlReader>();
            IList <Schema>   schemas;
            List <XmlReader> readers = composite.GetReaders(readerSourceMap);

            try
            {
                IList <EdmSchemaError> schemaManagerErrors =
                    SchemaManager.ParseAndValidate(readers,
                                                   composite.GetPaths(),
                                                   SchemaDataModelOption.EntityDataModel,
                                                   EdmProviderManifest.Instance,
                                                   out schemas);
                errors.AddRange(schemaManagerErrors);
            }
            finally
            {
                if (closeReaders)
                {
                    MetadataUtil.DisposeXmlReaders(readers);
                }
            }
            ThrowOnAnyNonWarningErrors(errors);
            Debug.Assert(readerSourceMap.ContainsKey(sourceLoader), "the source loader didn't produce any of the xml readers...");
            XmlReader sourceReader = readerSourceMap[sourceLoader];


            // use the index of the "source" xml reader as the index of the "source" schema
            Debug.Assert(readers.Contains(sourceReader), "the source reader is not in the list of readers");
            int index = readers.IndexOf(sourceReader);

            Debug.Assert(index >= 0, "couldn't find the source reader in the list of readers");

            Debug.Assert(readers.Count == schemas.Count, "We have a different number of readers than schemas");
            Schema sourceSchema = schemas[index];

            Debug.Assert(sourceSchema != null, "sourceSchema is null");

            // create the EdmItemCollection from the schemas
            EdmItemCollection itemCollection = new EdmItemCollection(schemas);

            if (EntityFrameworkVersionsUtil.ConvertToVersion(itemCollection.EdmVersion) >= EntityFrameworkVersions.Version2)
            {
                throw EDesignUtil.InvalidOperation(Strings.TargetEntityFrameworkVersionToNewForEntityClassGenerator);
            }

            // generate code
            ClientApiGenerator generator = new ClientApiGenerator(sourceSchema, itemCollection, this, errors);

            generator.GenerateCode(target, targetFilePath);
        }
示例#15
0
        /// <summary>
        /// Creates the CodeTypeDeclarations necessary to generate the code for the EntityContainer schema element
        /// </summary>
        /// <returns></returns>
        public override CodeTypeDeclarationCollection EmitApiClass()
        {
            Validate(); // emitter-specific validation

            // declare the new class
            // public partial class LOBScenario : ObjectContext
            CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(Item.Name);

            typeDecl.IsPartial = true;

            // raise the TypeGenerated event
            CodeTypeReference      objectContextTypeRef = TypeReference.ObjectContext;
            TypeGeneratedEventArgs eventArgs            = new TypeGeneratedEventArgs(Item, objectContextTypeRef);

            Generator.RaiseTypeGeneratedEvent(eventArgs);

            if (eventArgs.BaseType != null && !eventArgs.BaseType.Equals(objectContextTypeRef))
            {
                typeDecl.BaseTypes.Add(eventArgs.BaseType);
            }
            else
            {
                typeDecl.BaseTypes.Add(TypeReference.ObjectContext);
            }
            AddInterfaces(Item.Name, typeDecl, eventArgs.AdditionalInterfaces);

            CommentEmitter.EmitSummaryComments(Item, typeDecl.Comments);
            EmitTypeAttributes(Item.Name, typeDecl, eventArgs.AdditionalAttributes);

            CreateConstructors(typeDecl);
            // adding partial OnContextCreated method
            CreateContextPartialMethods(typeDecl);

            foreach (EntitySetBase entitySetBase in Item.BaseEntitySets)
            {
                if (MetadataUtil.IsEntitySet(entitySetBase))
                {
                    EntitySet          set          = (EntitySet)entitySetBase;
                    CodeMemberProperty codeProperty = CreateEntitySetProperty(set);
                    typeDecl.Members.Add(codeProperty);

                    CodeMemberField codeField = CreateEntitySetField(set);
                    typeDecl.Members.Add(codeField);
                }
            }

            foreach (EntitySetBase entitySetBase in Item.BaseEntitySets)
            {
                if (MetadataUtil.IsEntitySet(entitySetBase))
                {
                    EntitySet        set          = (EntitySet)entitySetBase;
                    CodeMemberMethod codeProperty = CreateEntitySetAddObjectProperty(set);
                    typeDecl.Members.Add(codeProperty);
                }
            }

            foreach (EdmFunction functionImport in Item.FunctionImports)
            {
                if (ShouldEmitFunctionImport(functionImport))
                {
                    CodeMemberMethod functionMethod = CreateFunctionImportStructuralTypeReaderMethod(functionImport);
                    typeDecl.Members.Add(functionMethod);
                }
            }

            // additional members, if provided by the event subscriber
            AddMembers(Item.Name, typeDecl, eventArgs.AdditionalMembers);

            CodeTypeDeclarationCollection typeDecls = new CodeTypeDeclarationCollection();

            typeDecls.Add(typeDecl);
            return(typeDecls);
        }
示例#16
0
        /// <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();

            Generator.AttributeEmitter.EmitGeneratedCodeAttribute(method);

            CodeTypeReference       typeRef = TypeReference.FromString(Item.Name);
            UniqueIdentifierService uniqueIdentifierService = new UniqueIdentifierService(Generator.IsLanguageCaseSensitive, name => Utils.FixParameterName(name));
            string instanceName = uniqueIdentifierService.AdjustIdentifier(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, Item.FullName);
            }

            method.ReturnType = typeRef;

            // 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(propertyEmitter.PropertyName);
                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 (MetadataUtil.IsComplexType(propertyEmitter.Item.TypeUsage.EdmType))
                {
                    List <CodeExpression> complexVerifyParameters = new List <CodeExpression>();
                    complexVerifyParameters.Add(paramRef);
                    complexVerifyParameters.Add(new CodePrimitiveExpression(propertyEmitter.PropertyName));

                    newPropertyValue =
                        new CodeMethodInvokeExpression(
                            PropertyEmitter.CreateEdmStructuralObjectRef(TypeReference),
                            Utils.VerifyComplexObjectIsNotNullName,
                            complexVerifyParameters.ToArray());
                }
                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);
        }
示例#17
0
        private IList <EdmSchemaError> InternalGenerateCode(string sourceEdmSchemaFilePath, Version schemaVersion, LazyTextWriterCreator textWriter, IEnumerable <string> additionalEdmSchemaFilePaths, Version targetFrameworkVersion)
        {
            List <EdmSchemaError> errors = new List <EdmSchemaError>();

            try
            {
                if (targetFrameworkVersion == EntityFrameworkVersions.Version1)
                {
                    errors.Add(new EdmSchemaError(Strings.EntityCodeGenTargetTooLow, (int)ModelBuilderErrorCode.TargetVersionNotSupported, EdmSchemaErrorSeverity.Error));
                    return(errors);
                }

                if (!MetadataItemCollectionFactory.ValidateActualVersionAgainstTarget(targetFrameworkVersion, schemaVersion, errors))
                {
                    return(errors);
                }

                if (schemaVersion == EntityFrameworkVersions.EdmVersion1_1)
                {
                    return(GenerateCodeFor1_1Schema(sourceEdmSchemaFilePath, textWriter, additionalEdmSchemaFilePaths));
                }

                ReflectionAdapter codeGenerator = ReflectionAdapter.Create(_languageOption, targetFrameworkVersion);
                codeGenerator.SourceCsdlPath          = sourceEdmSchemaFilePath;
                codeGenerator.ReferenceCsdlPaths      = additionalEdmSchemaFilePaths;
                codeGenerator.EdmToObjectNamespaceMap = _edmToObjectNamespaceMap.AsDictionary();

                string code = codeGenerator.TransformText();

                if (codeGenerator.Errors.Count != 0)
                {
                    ModelBuilderErrorCode errorCode = ModelBuilderErrorCode.PreprocessTemplateTransformationError;
                    errors.AddRange(codeGenerator.Errors.OfType <CompilerError>().Select(c => ConvertToEdmSchemaError(c, errorCode)));

                    if (codeGenerator.Errors.HasErrors)
                    {
                        return(errors);
                    }
                }

                using (TextWriter writer = textWriter.GetOrCreateTextWriter())
                {
                    writer.Write(code);
                }
            }
            catch (System.UnauthorizedAccessException ex)
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.SecurityError, ex));
            }
            catch (System.IO.FileNotFoundException ex)
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.FileNotFound, ex));
            }
            catch (System.Security.SecurityException ex)
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.SecurityError, ex));
            }
            catch (System.IO.DirectoryNotFoundException ex)
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.DirectoryNotFound, ex));
            }
            catch (System.IO.IOException ex)
            {
                errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.IOException, ex));
            }
            catch (Exception e)
            {
                if (MetadataUtil.IsCatchableExceptionType(e))
                {
                    errors.Add(EntityClassGenerator.CreateErrorForException(ModelBuilderErrorCode.PreprocessTemplateTransformationError, e, sourceEdmSchemaFilePath));
                }
                else
                {
                    throw;
                }
            }

            return(errors);
        }
示例#18
0
 private bool IsAttributeDefined(System.Type attributeType)
 {
     return(MetadataUtil.IsAttributeDefined(_node, _provider.Map(attributeType)));
 }
示例#19
0
        /// <summary>
        /// The method to be called to create the property level attributes for the PropertyEmitter
        /// </summary>
        /// <param name="emitter">The strongly typed emitter</param>
        /// <param name="propertyDecl">The type declaration to add the attribues to.</param>
        /// <param name="additionalAttributes">Additional attributes to emit</param>
        public void EmitPropertyAttributes(PropertyEmitter emitter,
                                           CodeMemberProperty propertyDecl,
                                           List <CodeAttributeDeclaration> additionalAttributes)
        {
            if (MetadataUtil.IsPrimitiveType(emitter.Item.TypeUsage.EdmType) || MetadataUtil.IsEnumerationType(emitter.Item.TypeUsage.EdmType))
            {
                CodeAttributeDeclaration scalarPropertyAttribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmScalarPropertyAttribute"));

                if (emitter.IsKeyProperty)
                {
                    Debug.Assert(emitter.Item.Nullable == false, "An EntityKeyProperty cannot be nullable.");

                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "EntityKeyProperty", true);
                }

                if (!emitter.Item.Nullable)
                {
                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "IsNullable", false);
                }

                propertyDecl.CustomAttributes.Add(scalarPropertyAttribute);
            }
            else //Complex property
            {
                Debug.Assert(MetadataUtil.IsComplexType(emitter.Item.TypeUsage.EdmType) ||
                             (MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType)),
                             "not a complex type or a collection type");
                CodeAttributeDeclaration attribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmComplexPropertyAttribute"));
                propertyDecl.CustomAttributes.Add(attribute);

                // Have CodeDOM serialization set the properties on the ComplexObject, not the ComplexObject instance.
                attribute = EmitSimpleAttribute("System.ComponentModel.DesignerSerializationVisibility");
                AttributeEmitter.AddAttributeArguments(attribute,
                                                       new object[] { new CodePropertyReferenceExpression(
                                                                          new CodeTypeReferenceExpression(TypeReference.ForType(
                                                                                                              typeof(System.ComponentModel.DesignerSerializationVisibility))), "Content") });
                propertyDecl.CustomAttributes.Add(attribute);

                if (!MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType))
                {
                    // Non-collection complex properties also need additional serialization attributes to force them to be explicitly serialized if they are null
                    // If this is omitted, null complex properties do not get explicitly set to null during deserialization, which causes
                    // them to be lazily constructed once the property is accessed after the entity is deserialized. If the property is
                    // actually null during serialiation, that means the user has explicitly set it, so we need to maintain that during serialization.
                    // This doesn't apply to collection types because they aren't lazily constructed and don't need this extra information.
                    attribute = EmitSimpleAttribute("System.Xml.Serialization.XmlElement");
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true);
                    propertyDecl.CustomAttributes.Add(attribute);

                    attribute = EmitSimpleAttribute("System.Xml.Serialization.SoapElement");
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true);
                    propertyDecl.CustomAttributes.Add(attribute);
                }
            }

            // serialization attribute
            AddDataMemberAttribute(propertyDecl);

            if (additionalAttributes != null && additionalAttributes.Count > 0)
            {
                try
                {
                    propertyDecl.CustomAttributes.AddRange(additionalAttributes.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    emitter.Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(emitter.Item.Name),
                                               ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty,
                                               EdmSchemaErrorSeverity.Error,
                                               e);
                }
            }

            EmitGeneratedCodeAttribute(propertyDecl);
        }
示例#20
0
 public bool IsDefined(IType type)
 {
     return(MetadataUtil.IsAttributeDefined(_node, type));
 }
示例#21
0
        /// <summary>
        /// 'Format' a string of text into lines: separates in to lines on '\n', removes '\r', and removes common leading blanks.
        /// </summary>
        /// <param name="escapeForXml">if true characters troublesome for xml are converted to entities</param>
        /// <param name="text">the text to be formatted</param>
        /// <returns>the formatted lines</returns>
        public static string[] GetFormattedLines(string text, bool escapeForXml)
        {
#if false
            if (text.IndexOf("\n") >= 0)
            {
                Console.WriteLine("GetFormattedText(\"" + text.Replace("\n", "\\n").Replace("\r", "\\r") + "\"," + escapeForXml + ")");
            }
#endif
            Debug.Assert(!string.IsNullOrEmpty(text));

            // nothing in, almost nothing out.
            if (StringUtil.IsNullOrEmptyOrWhiteSpace(text))
            {
                return new string[] { "" }
            }
            ;

            // normalize CRLF and LFCRs to LFs (we just remove all the crs, assuming there are no extraneous ones) and remove trailing spaces
            text = text.Replace("\r", "");

            // remove leading and.or trailing line ends to get single line for:
            // <documentation>
            // text
            // <documentation>
            bool trim  = false;
            int  start = text.IndexOf('\n');
            if (start >= 0 && MetadataUtil.IsNullOrEmptyOrWhiteSpace(text, 0, start + 1))
            {
                ++start;

                trim = true;
            }
            else
            {
                start = 0;
            }
            int last = text.LastIndexOf('\n');
            if (last > start - 1 && MetadataUtil.IsNullOrEmptyOrWhiteSpace(text, last))
            {
                --last;
                trim = true;
            }
            else
            {
                last = text.Length - 1;
            }
            if (trim)
            {
                Debug.Assert(start <= last);
                text = text.Substring(start, last - start + 1);
            }

            // break into lines (preversing blank lines and preping text for being in xml comments)
            if (escapeForXml)
            {
                text = MetadataUtil.Entityize(text);
            }
            string[] lines = SplitIntoLines(text);

            if (lines.Length == 1)
            {
                lines[0] = lines[0].Trim();
                return(lines);
            }

            // find the maximum leading whitespace substring (ignoring blank lines)
            string leadingBlanks = null;
            foreach (string line in lines)
            {
                // is an empty line
                if (MetadataUtil.IsNullOrEmptyOrWhiteSpace(line))
                {
                    continue;
                }

                // find the leading whitespace substring
                Match match = LeadingBlanks.Match(line);
                if (!match.Success)
                {
                    //none, we're done
                    leadingBlanks = "";
                    break;
                }

                if (leadingBlanks == null)
                {
                    // this is first non-empty line
                    leadingBlanks = match.Groups["LeadingBlanks"].Value;
                    continue;
                }

                // use the leadingBlanks if it matched the new one or it is a leading substring of the new one
                string leadingBlanks2 = match.Groups["LeadingBlanks"].Value;
                if (leadingBlanks2 == leadingBlanks || leadingBlanks2.StartsWith(leadingBlanks, StringComparison.Ordinal))
                {
                    continue;
                }

                if (leadingBlanks.StartsWith(leadingBlanks2, StringComparison.OrdinalIgnoreCase))
                {
                    // the current leading whitespace string is a leading substring of leadingBlanks. use the new one
                    leadingBlanks = leadingBlanks2;
                    continue;
                }

                // find longest leading common substring and use that.
                int minLength = Math.Min(leadingBlanks.Length, leadingBlanks2.Length);
                for (int j = 0; j < minLength; ++j)
                {
                    if (leadingBlanks[j] != leadingBlanks2[j])
                    {
                        if (j == 0)
                        {
                            leadingBlanks = "";
                        }
                        else
                        {
                            leadingBlanks = leadingBlanks.Substring(0, j);
                        }
                        break;
                    }
                }

                // if we've reduced the leading substring to an empty string, we're done.
                if (string.IsNullOrEmpty(leadingBlanks))
                {
                    break;
                }
            }

            // remove the leading whitespace substring and remove any trailing blanks.
            int numLeadingCharsToRemove = leadingBlanks.Length;
            for (int i = 0; i < lines.Length; ++i)
            {
                if (lines[i].Length >= numLeadingCharsToRemove)
                {
                    lines[i] = lines[i].Substring(numLeadingCharsToRemove);
                }
                lines[i] = lines[i].TrimEnd();
            }
            return(lines);
        }
示例#22
0
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] //For GenerateCodeCommon method call. Since we use null as the path, we have not changed the scope of the resource.
        public IList <EdmSchemaError> GenerateCode(XmlReader sourceEdmSchema, TextWriter target, IEnumerable <XmlReader> additionalEdmSchemas)
        {
            EDesignUtil.CheckArgumentNull(sourceEdmSchema, "sourceEdmSchema");
            EDesignUtil.CheckArgumentNull(additionalEdmSchemas, "additionalEdmSchemas");
            EDesignUtil.CheckArgumentNull(target, "target");

            List <EdmSchemaError> errors = new List <EdmSchemaError>();

            try
            {
                MetadataArtifactLoader        sourceLoader = new MetadataArtifactLoaderXmlReaderWrapper(sourceEdmSchema);
                List <MetadataArtifactLoader> loaders      = new List <MetadataArtifactLoader>();
                loaders.Add(sourceLoader);

                int index = 0;
                foreach (XmlReader additionalEdmSchema in additionalEdmSchemas)
                {
                    if (additionalEdmSchema == null)
                    {
                        throw EDesignUtil.Argument(Strings.NullAdditionalSchema("additionalEdmSchema", index));
                    }

                    try
                    {
                        MetadataArtifactLoader loader = new MetadataArtifactLoaderXmlReaderWrapper(additionalEdmSchema);
                        Debug.Assert(loader != null, "when is the loader ever null?");
                        loaders.Add(loader);
                    }
                    catch (Exception e)
                    {
                        if (MetadataUtil.IsCatchableExceptionType(e))
                        {
                            errors.Add(new EdmSchemaError(e.Message,
                                                          (int)ModelBuilderErrorCode.CodeGenAdditionalEdmSchemaIsInvalid,
                                                          EdmSchemaErrorSeverity.Error));
                        }
                        else
                        {
                            throw;
                        }
                    }
                    index++;
                }
                ThrowOnAnyNonWarningErrors(errors);

                GenerateCodeCommon(sourceLoader,
                                   loaders,
                                   new LazyTextWriterCreator(target),
                                   null,  // source path
                                   null,  // target file path
                                   false, // dispose readers?
                                   errors);
            }
            catch (TerminalErrorException)
            {
                // do nothing
                // just a place to jump when errors are detected
            }

            return(errors);
        }
示例#23
0
 private static bool HasModuleMarkerAttribute(Type type)
 {
     return(MetadataUtil.IsAttributeDefined(type, Types.ModuleAttribute) ||
            MetadataUtil.IsAttributeDefined(type, Types.ClrExtensionAttribute));
 }
示例#24
0
        [ResourceConsumption(ResourceScope.Machine)] //For MetadataArtifactLoader.Create method call. But the path is not created in this method.
        public IList <EdmSchemaError> GenerateCode(string sourceEdmSchemaFilePath, string targetPath, IEnumerable <string> additionalEdmSchemaFilePaths)
        {
            EDesignUtil.CheckStringArgument(sourceEdmSchemaFilePath, "sourceEdmSchemaFilePath");
            EDesignUtil.CheckArgumentNull(additionalEdmSchemaFilePaths, "additionalEdmSchemaFilePaths");
            EDesignUtil.CheckStringArgument(targetPath, "targetPath");

            List <EdmSchemaError> errors = new List <EdmSchemaError>();

            try
            {
                // create a loader for the source
                HashSet <string>       uriRegistry = new HashSet <string>();
                MetadataArtifactLoader sourceLoader;
                try
                {
                    sourceLoader = MetadataArtifactLoader.Create(sourceEdmSchemaFilePath, MetadataArtifactLoader.ExtensionCheck.Specific,
                                                                 XmlConstants.CSpaceSchemaExtension, uriRegistry);
                }
                catch (MetadataException e)
                {
                    errors.Add(CreateErrorForException(ModelBuilderErrorCode.CodeGenSourceFilePathIsInvalid, e, sourceEdmSchemaFilePath));
                    return(errors);
                }

                if (sourceLoader.IsComposite)
                {
                    throw new ArgumentException(Strings.CodeGenSourceFilePathIsNotAFile, "sourceEdmSchemaPath");
                }

                // create loaders for all the additional schemas
                List <MetadataArtifactLoader> loaders = new List <MetadataArtifactLoader>();
                loaders.Add(sourceLoader);
                int index = 0;
                foreach (string additionalSchemaFilePath in additionalEdmSchemaFilePaths)
                {
                    if (additionalSchemaFilePath == null)
                    {
                        throw EDesignUtil.Argument(Strings.NullAdditionalSchema("additionalEdmSchemaFilePaths", index));
                    }

                    try
                    {
                        MetadataArtifactLoader loader = MetadataArtifactLoader.Create(additionalSchemaFilePath,
                                                                                      MetadataArtifactLoader.ExtensionCheck.Specific,
                                                                                      XmlConstants.CSpaceSchemaExtension, uriRegistry);
                        Debug.Assert(loader != null, "when is the loader ever null?");
                        loaders.Add(loader);
                    }
                    catch (Exception e)
                    {
                        if (MetadataUtil.IsCatchableExceptionType(e))
                        {
                            errors.Add(CreateErrorForException(ModelBuilderErrorCode.CodeGenAdditionalEdmSchemaIsInvalid, e, additionalSchemaFilePath));
                        }
                        else
                        {
                            throw;
                        }
                    }
                    index++;
                }

                ThrowOnAnyNonWarningErrors(errors);
                try
                {
                    using (LazyTextWriterCreator target = new LazyTextWriterCreator(targetPath))
                    {
                        GenerateCodeCommon(sourceLoader, loaders, target, sourceEdmSchemaFilePath, targetPath,
                                           true, // dispose readers
                                           errors);
                    }
                }
                catch (System.IO.IOException ex)
                {
                    errors.Add(CreateErrorForException(System.Data.EntityModel.SchemaObjectModel.ErrorCode.IOException, ex, targetPath));
                    return(errors);
                }
            }
            catch (TerminalErrorException)
            {
                // do nothing
                // just a place to jump when errors are detected
            }
            return(errors);
        }
示例#25
0
        /// <summary>
        /// This is a control function to delegate the creation of the
        /// setter statments to the correct code path
        /// </summary>
        /// <param name="statements">The collection that the setter statements should be added to.</param>
        /// <param name="additionalSetStatements">Additional statements to emit</param>
        private void EmitPropertySetterBody(CodeStatementCollection statements, List <CodeStatement> additionalSetStatements)
        {
            // Invoke the partial method "On[PropertyName]Changing();
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    OnChangingPartialMethodName(PropertyName), new CodePropertySetValueReferenceExpression()));

            // ReportPropertyChanging( _piFieldName );
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    Utils.ReportPropertyChangingMethodName,
                    new CodePrimitiveExpression(PropertyName)));

            // insert additional statements following the PropertyChanging event
            if (additionalSetStatements != null && additionalSetStatements.Count > 0)
            {
                try
                {
                    statements.AddRange(additionalSetStatements.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       e);
                }
            }

            if (MetadataUtil.IsPrimitiveType(Item.TypeUsage.EdmType))
            {
                EmitScalarTypePropertySetStatements(statements, CollectionKind.None);
            }
            else if (MetadataUtil.IsComplexType(Item.TypeUsage.EdmType))
            {
                // ComplexTypes have a completely different set pattern:
                EmitComplexTypePropertySetStatements(statements, CollectionKind.None);
            }
            else if (MetadataUtil.IsCollectionType(Item.TypeUsage.EdmType))
            {
                if (MetadataUtil.IsComplexType(((CollectionType)Item.TypeUsage.EdmType).TypeUsage.EdmType))
                {
                    EmitComplexTypePropertySetStatements(statements, GetCollectionKind(Item.TypeUsage));
                }
                else
                {
                    Debug.Assert(MetadataUtil.IsPrimitiveType(((CollectionType)Item.TypeUsage.EdmType).TypeUsage.EdmType),
                                 "Collections should be of primitive types or complex types");
                    EmitScalarTypePropertySetStatements(statements, GetCollectionKind(Item.TypeUsage));
                }
            }
            else if (MetadataUtil.IsEnumerationType(Item.TypeUsage.EdmType))
            {
                // this.fieldName = value;
                statements.Add(
                    new CodeAssignStatement(
                        FieldRef,
                        new CodePropertySetValueReferenceExpression()));
            }

            // ReportPropertyChanged( _piFieldName );
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    Utils.ReportPropertyChangedMethodName,
                    new CodePrimitiveExpression(PropertyName)));

            // Invoke the partial method "On[PropertyName]Changed();
            statements.Add(
                new CodeMethodInvokeExpression(
                    ThisRef,
                    OnChangedPartialMethodName(PropertyName)));
        }