/// <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); } } } }
private static bool IsModule(Type type) { return(type.IsClass && type.IsSealed && !type.IsNestedPublic && MetadataUtil.IsAttributeDefined(type, Types.ModuleAttribute)); }
/// <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); }
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 }
public bool IsDefined(IType attributeType) { ExternalType type = attributeType as ExternalType; if (null == type) { return(false); } return(MetadataUtil.IsAttributeDefined(_type, type.ActualType)); }
/// <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); }
/// <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)); } }
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); } }
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)); } } }
/// <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); } } } }
// 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); }
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)); }
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); }
/// <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); }
/// <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); }
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); }
private bool IsAttributeDefined(System.Type attributeType) { return(MetadataUtil.IsAttributeDefined(_node, _provider.Map(attributeType))); }
/// <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); }
public bool IsDefined(IType type) { return(MetadataUtil.IsAttributeDefined(_node, type)); }
/// <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); }
[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); }
private static bool HasModuleMarkerAttribute(Type type) { return(MetadataUtil.IsAttributeDefined(type, Types.ModuleAttribute) || MetadataUtil.IsAttributeDefined(type, Types.ClrExtensionAttribute)); }
[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); }
/// <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))); }