/// <summary> /// Copy members from <paramref name="typeReference"/> into the class <paramref name="p"/> in the context of the /// <paramref name="context"/> /// </summary> private void CopyMembers(TypeReference typeReference, Class p, ClassContent context) { if (typeReference.Class == null) { throw new InvalidOperationException("Impossible condition to proceed"); } foreach (ClassContent cc in typeReference.Class.Content) { // Can't use AddContent as that sorts the content and would mess up the outer loops ClassContent newCc = cc.Clone() as ClassContent; newCc.Container = p; newCc.MemberOf = p.MemberOf; newCc.Annotations.Add(new CodeCollapseAnnotation() { Name = context.Name, Order = 0, Property = context }); newCc.Annotations.Add(new CodeCollapseAnnotation() { Name = newCc.Name, Order = 1, Property = newCc }); // Assign code collapse attributes p.Content.Add(newCc); } }
/// <summary> /// Create a cardinality change /// </summary> private void CreateCardinalityChange(Feature feature, Constraint constraint) { #region Cardinality Change // 1. Validate constraint & target CardinalityConstraintValue ccv = constraint.Value as CardinalityConstraintValue; ClassContent ccFeature = feature as ClassContent; if (ccFeature == null) { Trace.WriteLine(String.Format("Delta: Cannot apply cardinality constraint against a feature of type '{0}', skipping...", feature.GetType().Name), "error"); return; } // 2. Validate existing data if ((ccv.OriginalMaxValue.HasValue ? ccv.OriginalMaxValue.ToString() != ccFeature.MaxOccurs : ccFeature.MaxOccurs != "*") || (ccv.OriginalMinValue.HasValue ? ccv.OriginalMinValue.ToString() != ccFeature.MinOccurs : ccFeature.MaxOccurs != null)) { Trace.WriteLine(String.Format("Delta: Applying cardinality constraint on '{0}' even though original Min/Max occurs do not match!", feature.Name), "warn"); } // 3. Validate that the cardinality doesn't already exist if (ccFeature.Annotations.Exists(o => o is CardinalityConstraintAnnotation && (o as CardinalityConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Cardinality constraint has already been applied to '{0}'", feature.Name), "error"); return; } // 4. Append the annotation ccFeature.Annotations.Add(new CardinalityConstraintAnnotation() { ChangeType = ChangeType.Edit, RealmCode = this.m_deltaSet.Realm.Code, MaxOccurs = ccv.NewMaxValue.HasValue ? ccv.NewMaxValue.Value.ToString() : "*", MinOccurs = ccv.NewMinValue.HasValue ? ccv.NewMinValue.Value.ToString() : null, RealmName = this.m_deltaSet.MetaData.Description }); #endregion }
public List <String> GetTypes(Schema Schema) { var Primitives = GetPrimitives(Schema); var NamespaceToClasses = new Dictionary <String, List <List <String> > >(); void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent) { if (!NamespaceToClasses.ContainsKey(ClassNamespaceName)) { NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >()); } NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList()); } foreach (var c in Schema.Types) { if (c.OnPrimitive) { continue; } else if (c.OnAlias) { AddClass(c.NamespaceName(), Alias(c.Alias)); } else if (c.OnRecord) { AddClass(c.NamespaceName(), Record(c.Record)); } else if (c.OnTaggedUnion) { AddClass(c.NamespaceName(), TaggedUnion(c.TaggedUnion)); } else if (c.OnEnum) { AddClass(c.NamespaceName(), Enum(c.Enum)); } else if (c.OnClientCommand) { } else if (c.OnServerCommand) { } else { throw new InvalidOperationException(); } } if (NamespaceToClasses.Count > 1) { throw new NotSupportedException("PythonMultipleNamespace"); //Python不支持nested class import } var Classes = NamespaceToClasses.Select(p => p.Value.Join(new String[] { "" })); return((new List <List <String> > { Primitives }).Concat(Classes).Join(new String[] { "" }).ToList()); }
/// <summary> /// Determine if the class content is a candidate for collapsing /// </summary> private bool IsCandidateForTypeCollapse(ClassContent cc) { // Candidates must be a property with 0..1 and must be // traversable in nature. if (cc.MaxOccurs != "1" || !(cc is Property) || (cc as Property).PropertyType != Property.PropertyTypes.TraversableAssociation || cc.MinOccurs != "0") { return(false); } // Determine the conformance meets criteria if ((cc.Conformance == ClassContent.ConformanceKind.Optional || cc.Conformance == ClassContent.ConformanceKind.Required) && !QueryConformance((cc as Property).Type, ClassContent.ConformanceKind.Optional | ClassContent.ConformanceKind.Required)) { return(false); } else if (cc.Conformance == ClassContent.ConformanceKind.Populated) { return(false); } // Make sure none of the child member names appear in the parent class they are to be merged with bool isCandidate = CountReferences((cc as Property).Type) == 1; foreach (ClassContent content in (cc.Container as Class).Content) { isCandidate &= HasMember((cc as Property).Type, content.Name); } // Now we must determine if there are no other references to the class to be collapsed return(isCandidate); }
/// <summary> /// Replace references in the class content <paramref name="cc"/> from <paramref name="s"/> /// to <paramref name="f"/> /// </summary> private void ReplaceReferences(Class s, Class f, ClassContent cc) { string fqnF = String.Format("{0}.{1}", f.ContainerName, f.Name), fqnS = String.Format("{0}.{1}", s.ContainerName, s.Name); if (cc is Property && (cc as Property).Type.Name == fqnS) { UpdateReference((cc as Property).Type, fqnS, fqnF); } else if (cc is Choice) { foreach (var c in (cc as Choice).Content) { ReplaceReferences(s, f, c); } } // Alternate traversals if (cc is Property) { foreach (var alt in (cc as Property).AlternateTraversalNames ?? new List <Property.AlternateTraversalData>()) { if (alt.CaseWhen.Name.Equals(fqnS)) { alt.CaseWhen.Name = fqnF; alt.CaseWhen.MemberOf = s.MemberOf; } } } }
public List <String> GetTypes(Schema Schema) { var NamespaceName = Schema.Types.Concat(Schema.TypeRefs).Where(t => !t.OnPrimitive).FirstOrDefault()?.NamespaceName() ?? ""; var Primitives = GetPrimitives(Schema); var NamespaceToClasses = new Dictionary <String, List <List <String> > >(); void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent) { if (!NamespaceToClasses.ContainsKey(ClassNamespaceName)) { NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >()); } NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList()); } AddClass(NamespaceName, Streams()); AddClass(NamespaceName, BinaryTranslator(Schema, NamespaceName)); if (NamespaceToClasses.Count > 1) { throw new NotSupportedException("PythonMultipleNamespace"); //Python不支持nested class import } var Classes = NamespaceToClasses.Select(p => p.Value.Join(new String[] { "" })); return((new List <List <String> > { Primitives }).Concat(Classes).Join(new String[] { "" }).ToList()); }
/// <summary> /// Apply delta against a property /// </summary> private void ApplyDelta(ClassContent property, RelationshipDeltaData delta) { Trace.WriteLine(string.Format("Delta: Applying deltas for '{0}.{1}'...", property.Container.Name, property.Name), "debug"); // Apply constraints foreach (var constraint in delta.Constraint) { ApplyConstraint(property, constraint); } }
/// <summary> /// Create a remove change delta /// </summary> private void CreateRemoveChange(Feature feature, Constraint constraint) { #region Remove Change // 1. Find the feature that is to be removed Feature removeFeature = null; ClassContent pFeature = feature as ClassContent; RemoveConstraintValue rcv = constraint.Value as RemoveConstraintValue; if (rcv.RelationshipName == feature.Name) { removeFeature = feature; } else if (!String.IsNullOrEmpty(rcv.OwnedEntryPoint) && !String.IsNullOrEmpty(rcv.ClassName)) { if (feature is Property) { var ssContainer = ((feature as Property).Container as Class).ContainerPackage; if (ssContainer != null && ssContainer.Name.Equals(rcv.OwnedEntryPoint)) { removeFeature = ssContainer.OwnedClasses.Find(o => o.Name.Equals(rcv.ClassName)); } } } // 2. Validate the feature if (removeFeature == null) { Trace.WriteLine(String.Format("Delta: Cannot apply remove constraint on '{0}.{1}{2}' as the path was not found...", rcv.OwnedEntryPoint, rcv.ClassName, rcv.RelationshipName == null ? "" : "." + rcv.RelationshipName), "error"); return; } // 3. Apply the remove constraint if (removeFeature.Annotations.Exists(o => o is RemoveConstraintAnnotation && (o as RemoveConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Conformance constraint has already been applied to '{0}'", feature.Name), "error"); return; } removeFeature.Annotations.Add( new RemoveConstraintAnnotation() { ChangeType = ChangeType.Remove, RealmCode = this.m_deltaSet.Realm.Code, RealmName = this.m_deltaSet.MetaData.Description } ); // 4. Remove the supported constraint removeFeature.Annotations.RemoveAll(o => o is SupportedConstraintAnnotation && (o as SupportedConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code); #endregion }
public List <String> GetTypes(Schema Schema, String NamespaceName) { var Primitives = GetPrimitives(Schema); var NamespaceToClasses = new List <KeyValuePair <String, List <List <String> > > >(); void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent) { if ((NamespaceToClasses.Count > 0) && (NamespaceToClasses[NamespaceToClasses.Count - 1].Key == ClassNamespaceName)) { NamespaceToClasses[NamespaceToClasses.Count - 1].Value.Add(ClassContent.ToList()); } else { NamespaceToClasses.Add(new KeyValuePair <String, List <List <String> > >(ClassNamespaceName, new List <List <String> > { ClassContent.ToList() })); } } AddClass(NamespaceName, Streams()); AddClass(NamespaceName, BinaryTranslator(Schema, NamespaceName)); var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).ToList(); if (Commands.Count > 0) { var SchemaClosureGenerator = Schema.GetSchemaClosureGenerator(); var Hash = SchemaClosureGenerator.GetSubSchema(Schema.Types.Where(t => (t.OnClientCommand || t.OnServerCommand) && t.Version() == ""), new List <TypeSpec> { }).GetNonattributed().Hash(); if (WithServer) { AddClass(NamespaceName, BinarySerializationServer(Hash, Commands, SchemaClosureGenerator, NamespaceName)); } if (WithClient) { AddClass(NamespaceName, IBinarySender()); AddClass(NamespaceName, BinarySerializationClient(Hash, Commands, SchemaClosureGenerator, NamespaceName)); } } var Classes = NamespaceToClasses.Select(p => WrapNamespace(p.Key, p.Value.Join(new String[] { "" }))); return((new List <List <String> > { Primitives }).Concat(Classes).Join(new String[] { "" }).ToList()); }
/// <summary> /// Count references of the type in the specified class content /// </summary> private int CountReferences(ClassContent cc, TypeReference tr) { int retVal = 0; FeatureComparer fc = new FeatureComparer(); if (cc is Property && fc.CompareTypeReference((cc as Property).Type, tr) == 0) { retVal++; } else if (cc is Choice) { foreach (ClassContent scc in (cc as Choice).Content) { retVal += CountReferences(scc, tr); } } return(retVal); }
/// <summary> /// Create a conformance change annotation /// </summary> private void CreateConformanceChange(Feature feature, Constraint constraint) { #region Conformance Change // 1. Validate the constraint is against a property ClassContent pFeature = feature as ClassContent; if (pFeature == null) { Trace.WriteLine(String.Format("Delta: Conformance constraint cannot be applied against a '{1}' named '{0}'", feature.Name, feature.GetType().Name), "error"); return; } // 2. Validate the conformance old value is in fact a match ConstraintValue <String> stConstraint = constraint.Value as ConstraintValue <string>; if (stConstraint == null || stConstraint.Original.ToLower() != pFeature.Conformance.ToString().ToLower()) { Trace.WriteLine(String.Format("Delta: Conformance constraint cannot be applied because the original value of '{0}' does not match the actual original property conformance of '{1}'", stConstraint.Original.ToLower(), pFeature.Conformance.ToString().ToLower()), "error"); return; } // Map the SCREAMING CAPS to ScreamingCaps string friendlyValue = String.Format("{0}{1}", stConstraint.New[0], stConstraint.New.Substring(1).ToLower()); if (friendlyValue == "Not_allowed") { friendlyValue = "NotAllowed"; } // 3. Verify a constraint for the same jurisdication has not already been added if (feature.Annotations.Exists(o => o is ConformanceConstraintAnnotation && (o as ConformanceConstraintAnnotation).RealmCode == this.m_deltaSet.Realm.Code)) { Trace.WriteLine(String.Format("Delta: Conformance constraint has already been applied to '{0}'", feature.Name), "error"); return; } feature.Annotations.Add( new ConformanceConstraintAnnotation() { NewValue = (Property.ConformanceKind)Enum.Parse(typeof(Property.ConformanceKind), friendlyValue), ChangeType = ChangeType.Edit, RealmCode = this.m_deltaSet.Realm.Code, RealmName = this.m_deltaSet.MetaData.Description } ); #endregion }
/// <summary> /// Class content comparer /// </summary> private int CompareContent(ClassContent x, ClassContent y) { // Name must match if (!x.Name.Equals(y.Name)) { return(x.Name.CompareTo(y.Name)); } else if (!x.GetType().Equals(y.GetType())) // must be the same type of content { return(-1); } else if (x is Property) // We have already asserted that x and y must be the same type { return(CompareProperty(x as Property, y as Property)); } else if (x is Choice) // Compare choice { return(CompareChoice(x as Choice, y as Choice)); } return(0); }
/// <summary> /// Is this a candidate for collapsing meaningless complexity /// </summary> private bool IsCandidateForMeaninglessComplexityCollapse(ClassContent cc) { if (!(cc is Property) || (cc as Property).Type.Class == null) { return(false); // Not a candidate } // The condition for this type of collection is that the referenced type: // 1. Provides only ONE property (after --collapse-ignore are removed) // 2. The ONE property is mandatory (must be provided) List <ClassContent> content = (cc as Property).Type.Class.GetFullContent(); content.RemoveAll(a => CorCollapserPipelineTrigger.collapseIgnore.Contains(a.Name)); // Remove the ignore if (CorCollapserPipelineTrigger.collapseIgnoreFixed) { content.RemoveAll(o => o is Property && !String.IsNullOrEmpty((o as Property).FixedValue) && (o as Property).PropertyType == Property.PropertyTypes.Structural); } if (content.Count != 1) { return(false); // can't collapse this relation as there is more than sub-property } ClassContent candidate = content[0]; // Is this a generic parameter if ((candidate.Container as Class).TypeParameters != null && (cc.Container as Class).TypeParameters.Find(o => o.ParameterName == (candidate as Property).Type.Name) != null) { return(false); } // Now determine if we can collapse return((candidate.Conformance == ClassContent.ConformanceKind.Mandatory || candidate.Conformance >= cc.Conformance || (cc.Conformance <= ClassContent.ConformanceKind.Required && candidate.Conformance == ClassContent.ConformanceKind.Populated)) && // Experiment: && candidate.Conformance != ClassContent.ConformanceKind.Populated) candidate.MaxOccurs == "1" && candidate is Property); }
public List <String> GetTypes(Schema Schema, String NamespaceName) { var Primitives = GetPrimitives(Schema); var NamespaceToClasses = new Dictionary <String, List <List <String> > >(); void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent) { if (!NamespaceToClasses.ContainsKey(ClassNamespaceName)) { NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >()); } NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList()); } var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).ToList(); if (Commands.Count > 0) { var SchemaClosureGenerator = Schema.GetSchemaClosureGenerator(); var Hash = SchemaClosureGenerator.GetSubSchema(Schema.Types.Where(t => (t.OnClientCommand || t.OnServerCommand) && t.Version() == ""), new List <TypeSpec> { }).GetNonattributed().Hash(); AddClass(NamespaceName, JsonSerializationServer(Hash, Commands, SchemaClosureGenerator, NamespaceName)); AddClass(NamespaceName, IJsonSender()); AddClass(NamespaceName, JsonSerializationClient(Hash, Commands, SchemaClosureGenerator, NamespaceName)); AddClass(NamespaceName, JsonLogAspectWrapper(Commands, NamespaceName)); } AddClass(NamespaceName, JsonTranslator(Schema, NamespaceName)); var Classes = NamespaceToClasses.Select(p => Inner.WrapNamespace(p.Key, p.Value.Join(new String[] { "" }))); return((new List <List <String> > { Primitives }).Concat(Classes).Join(new String[] { "" }).ToList()); }
/// <summary> /// Query conformance /// </summary> private bool QueryConformance(TypeReference typeReference, ClassContent.ConformanceKind p) { if(typeReference.Class == null) return false; bool retVal = true; // Class content foreach (ClassContent cc in typeReference.Class.GetFullContent()) if (cc is Property) retVal &= ((cc.Conformance & p) == cc.Conformance); else if (cc is Choice) retVal &= QueryConformance(cc as Choice, typeReference, p); return retVal; }
/// <summary> /// Count references of the type in the specified class content /// </summary> private int CountReferences(ClassContent cc, TypeReference tr) { int retVal = 0; FeatureComparer fc = new FeatureComparer(); if (cc is Property && fc.CompareTypeReference((cc as Property).Type, tr) == 0) retVal++; else if (cc is Choice) foreach (ClassContent scc in (cc as Choice).Content) retVal += CountReferences(scc, tr); return retVal; }
/// <summary> /// Query the conformance for a choice /// </summary> private bool QueryConformance(Choice chc, TypeReference typeReference, ClassContent.ConformanceKind p) { bool retVal = true; foreach (ClassContent cc in chc.Content) if (cc is Property) retVal &= ((cc.Conformance & p) == cc.Conformance); else if (cc is Choice) retVal &= QueryConformance(cc as Choice, typeReference, p); return retVal; }
/// <summary> /// Render property attribute /// </summary> private String RenderPropertyAttribute(ClassContent cc, string ownerPackage, int propertySort) { StringWriter retBuilder = new StringWriter(); // Represent as an option Choice options = cc as Choice; if(options == null) options = new Choice() { Content = new List<ClassContent>() { cc as Property } }; // Traversal names already rendered List<string> alreadyRendered = new List<string>(); // Iterate through choices foreach (Property property in options.Content) { // Enumerator for alt-traversals List<Property.AlternateTraversalData> altTraversal = new List<Property.AlternateTraversalData>(); altTraversal.Add(new Property.AlternateTraversalData() { CaseWhen = property.Type, TraversalName = property.Name }); // Alternatives if (property.AlternateTraversalNames != null) foreach (Property.AlternateTraversalData kv in property.AlternateTraversalNames) altTraversal.Add(kv); // Write properties foreach (Property.AlternateTraversalData kv in altTraversal) { // Datatype TypeReference tr = Datatypes.MapDatatype(kv.CaseWhen); string key = string.Format("{0}.{1}.{2}.{3}", ownerPackage, tr.Name, kv.TraversalName, kv.InteractionOwner != null ? kv.InteractionOwner.Name : ""); // Already rendered if (!alreadyRendered.Contains(key)) { retBuilder.Write("\t@Property(name = \"{0}\", conformance = ConformanceType.{1}, propertyType = PropertyType.{2}, sortKey = {3}", kv.TraversalName, cc.Conformance.ToString().ToUpper(), (options.Content[0] as Property).PropertyType.ToString().ToUpper(), propertySort); // Now a type hint if (tr.Class != null && (property.Container is Choice || property.AlternateTraversalNames != null)) retBuilder.Write(", type = {0}.class", CreateDatatypeRef(tr, property, ownerPackage)); // Now for an interaction hint if (tr.Class != null && (property.Container is Choice || property.AlternateTraversalNames != null) && kv.InteractionOwner != null) retBuilder.Write(", interactionOwner = {0}.interaction.{1}.class", ownerPackage, kv.InteractionOwner.Name); // Impose a flavor? if (tr.Flavor != null) retBuilder.Write(", imposeFlavorId = \"{0}\"", tr.Flavor); // Is this a set? if (property.MaxOccurs != "1") retBuilder.Write(", minOccurs = {0}, maxOccurs = {1}", property.MinOccurs, property.MaxOccurs == "*" ? "-1" : property.MaxOccurs); if (property.MinLength != null) retBuilder.Write(", minLength = {0}", property.MinLength); if (property.MaxLength != null) retBuilder.Write(", maxLength = {0}", property.MaxLength); // Is there an update mode //if (property.UpdateMode != null) // retBuilder.Write(", defaultUpdateMode = UpdateMode.{0}", property.UpdateMode); // Is there a supplier domain? if (property.SupplierDomain != null && property.SupplierStrength == MohawkCollege.EHR.gpmr.COR.Property.CodingStrengthKind.CodedNoExtensions) retBuilder.Write(", supplierDomain = \"{0}\"", (property.SupplierDomain.ContentOid)); // Fixed value if (!String.IsNullOrEmpty(property.FixedValue)) retBuilder.Write(", fixedValue = \"{0}\"", property.FixedValue); // generic supplier if (property.Type != null && property.Type.GenericSupplier != null && property.Type.GenericSupplier.Count > 0) { retBuilder.Write(", genericSupplier = {"); foreach (var genSupp in property.Type.GenericSupplier) if((property.Container as Class).TypeParameters == null || !(property.Container as Class).TypeParameters.Exists(o=>o.Name == genSupp.Name)) retBuilder.Write("{0}.class{1}", CreateDatatypeRef(genSupp, property, ownerPackage, false), genSupp == property.Type.GenericSupplier.Last() ? "" : ","); retBuilder.Write("}"); } else if (property.MaxOccurs != "1" && !Datatypes.IsCollectionType(property.Type)) // Array list so we still need to put this in { retBuilder.Write(", genericSupplier = {"); CreateDatatypeRef(property.Type, property, ownerPackage); retBuilder.Write("}"); } retBuilder.WriteLine("),"); alreadyRendered.Add(key); } } } string retVal = retBuilder.ToString(); retVal = retVal.Substring(0, retVal.LastIndexOf(",")); retVal += "\r\n"; if (alreadyRendered.Count > 1) { if (!s_imports.Contains("org.marc.everest.annotations.Properties")) s_imports.Add("org.marc.everest.annotations.Properties"); return String.Format("\t@Properties( value = {{\r\n{0}\t }})\r\n", retVal); } else return retVal; }
/// <summary> /// Collapse the data type of <paramref name="cc"/> so that it is the only meaningful data type provided by its /// natural type /// </summary> private void CollapseMemberType(ClassContent cc, Class context) { if (!(cc is Property)) { throw new InvalidOperationException("Can't collapse this member type"); // Not a candidate } // The condition for this type of collection is that the referenced type: // 1. Provides only ONE property (after --collapse-ignore are removed) // 2. The ONE property is mandatory (must be provided) List <ClassContent> content = (cc as Property).Type.Class.GetFullContent(); content.RemoveAll(a => CorCollapserPipelineTrigger.collapseIgnore.Contains(a.Name)); // Remove the ignore if (CorCollapserPipelineTrigger.collapseIgnoreFixed) { content.RemoveAll(o => o is Property && !String.IsNullOrEmpty((o as Property).FixedValue) && (o as Property).PropertyType == Property.PropertyTypes.Structural); } if (content.Count != 1) { throw new InvalidOperationException("Can't collapse type with more than one meaningful content"); // can't collapse this relation as there is more than sub-property } ClassContent candidate = content[0]; cc.Annotations.Add(new CodeCollapseAnnotation() { Name = cc.Name, Order = 0, Property = cc as Property }); // Has this collapsed member had any collapsing if (candidate.Annotations.Count > 0) { // Get all code collapse annotations from the candidate List <Annotation> collapseAnnotations = candidate.Annotations.FindAll(o => o is CodeCollapseAnnotation); // Find one that links it to the candidate //collapseAnnotations.RemoveAll(o => candidate.Annotations.Count(ca => (ca as CodeCollapseAnnotation).Property == (o as CodeCollapseAnnotation).Property) != 1); CodeCollapseAnnotation oldCca = null; foreach (CodeCollapseAnnotation cca in collapseAnnotations) { cca.Order = cc.Annotations.Count; if (cc.Annotations.Count(ca => ca is CodeCollapseAnnotation && (ca as CodeCollapseAnnotation).Property == cca.Property) == 0) { cc.Annotations.Add(cca); } oldCca = cca; } } else { cc.Annotations.Add(new CodeCollapseAnnotation() { Name = candidate.Name, Order = 1, Property = candidate as Property }); } // Determine a better name if (CorCollapserPipelineTrigger.collapseSpecialNaming) { // We collapse the collapsee's name into the parent by default. string preferredName = candidate.Name; // If the container for the property already has an element by the name we prefer, we must // or the collapsee's name is in the useless words list we must keep the current name, or if the // parent's name is in the structurally important collection if ((cc.Container as Class).GetFullContent().Find(o => o.Name == preferredName) != null || CorCollapserPipelineTrigger.uselessWords.Contains(preferredName) || CorCollapserPipelineTrigger.importantWords.Contains(cc.Name)) { preferredName = cc.Name; } cc.Name = preferredName; } // Now determine if we can collapse (cc as Property).Type = (candidate as Property).Type.Clone() as TypeReference; (cc as Property).SupplierDomain = (candidate as Property).SupplierDomain; (cc as Property).SupplierStrength = (candidate as Property).SupplierStrength; (cc as Property).Type.Container = cc; (cc as Property).Type.MemberOf = cc.MemberOf; // Update documentation if ((cc as Property).Documentation == null && candidate.Documentation != null) { (cc as Property).Documentation = candidate.Documentation; } }
/// <summary> /// Copy members from <paramref name="typeReference"/> into the class <paramref name="p"/> in the context of the /// <paramref name="context"/> /// </summary> private void CopyMembers(TypeReference typeReference, Class p, ClassContent context) { if(typeReference.Class == null) throw new InvalidOperationException("Impossible condition to proceed"); foreach (ClassContent cc in typeReference.Class.Content) { // Can't use AddContent as that sorts the content and would mess up the outer loops ClassContent newCc = cc.Clone() as ClassContent; newCc.Container = p; newCc.MemberOf = p.MemberOf; newCc.Annotations.Add(new CodeCollapseAnnotation() { Name = context.Name, Order = 0, Property = context }); newCc.Annotations.Add(new CodeCollapseAnnotation() { Name = newCc.Name, Order = 1, Property = newCc}); // Assign code collapse attributes p.Content.Add(newCc); } }
void CreateBook() { autor = new ClassAutor(); content = new ClassContent(); title = new ClassTitle(); }
/// <summary> /// Replace references in the class content <paramref name="cc"/> from <paramref name="s"/> /// to <paramref name="f"/> /// </summary> private void ReplaceReferences(Class s, Class f, ClassContent cc) { string fqnF = String.Format("{0}.{1}", f.ContainerName, f.Name), fqnS = String.Format("{0}.{1}", s.ContainerName, s.Name); if (cc is Property && (cc as Property).Type.Name == fqnS) UpdateReference((cc as Property).Type, fqnS, fqnF); else if (cc is Choice) foreach (var c in (cc as Choice).Content) ReplaceReferences(s, f, c); // Alternate traversals if(cc is Property) foreach (var alt in (cc as Property).AlternateTraversalNames ?? new List<Property.AlternateTraversalData>()) if (alt.CaseWhen.Name.Equals(fqnS)) { alt.CaseWhen.Name = fqnF; alt.CaseWhen.MemberOf = s.MemberOf; } }
/// <summary> /// Is this a candidate for collapsing meaningless complexity /// </summary> private bool IsCandidateForMeaninglessComplexityCollapse(ClassContent cc) { if(!(cc is Property) || (cc as Property).Type.Class == null) return false; // Not a candidate // The condition for this type of collection is that the referenced type: // 1. Provides only ONE property (after --collapse-ignore are removed) // 2. The ONE property is mandatory (must be provided) List<ClassContent> content = (cc as Property).Type.Class.GetFullContent(); content.RemoveAll(a => CorCollapserPipelineTrigger.collapseIgnore.Contains(a.Name)); // Remove the ignore if (CorCollapserPipelineTrigger.collapseIgnoreFixed) content.RemoveAll(o => o is Property && !String.IsNullOrEmpty((o as Property).FixedValue) && (o as Property).PropertyType == Property.PropertyTypes.Structural); if (content.Count != 1) return false; // can't collapse this relation as there is more than sub-property ClassContent candidate = content[0]; // Is this a generic parameter if ((candidate.Container as Class).TypeParameters != null && (cc.Container as Class).TypeParameters.Find(o => o.ParameterName == (candidate as Property).Type.Name) != null) return false; // Now determine if we can collapse return (candidate.Conformance == ClassContent.ConformanceKind.Mandatory || candidate.Conformance >= cc.Conformance || (cc.Conformance <= ClassContent.ConformanceKind.Required && candidate.Conformance == ClassContent.ConformanceKind.Populated)) // Experiment: && candidate.Conformance != ClassContent.ConformanceKind.Populated) && candidate.MaxOccurs == "1" && candidate is Property; }
///----------------------------------------------------------------- #region Rule internal protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst) { variants.Clear(); var slots = new int[contentSrc.NameCount / 2]; GatherVariants(0, slots, variants, scriptContent, contentSrc, contentDst); }
///----------------------------------------------------------------- #region Rule internal protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst) { var slots = new int[contentDst.VarCount]; for (var s = 0; s < slots.Length; s++) { slots[s] = 0; } variants.Clear(); GatherVariantsSlots(0, slots, variants, scriptContent, contentSrc, contentDst); }
protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst) { variants.Clear(); for (int r = 0; r < repeatCount; r++) { var variant = new FunctionVariant(scriptContent.functionContents.Count); for (var fc = 0; fc < scriptContent.functionContents.Count; fc++) { var functionContent = scriptContent.functionContents[fc]; for (var v = 0; v < contentSrc.names.Count; v++) { var functionBody = functionContent.body; if (Defaults[0].CanSwap(functionBody)) { var swap = Defaults[0] + scriptContent.classDefaultType; functionBody = swap.Apply(functionBody); } if (Defaults[1].CanSwap(functionBody)) { var swap = Defaults[1] + (r + 1).ToString(); functionBody = swap.Apply(functionBody); } if (Names.DefaultSymbol.CanSwap(functionBody)) { var swap = Names.DefaultSymbol + contentSrc.names[v] + r.ToString(); functionBody = swap.Apply(functionBody); } if (Variables.DefaultSymbol.CanSwap(functionBody)) { var swap = Variables.DefaultSymbol + r.ToString(); functionBody = swap.Apply(functionBody); } variant[fc] = functionBody; } } variants.Add(variant); } }
private TypeReference CreateTypeReference(AssociationEnd ae, ClassContent cc) { // Resolve CMET ClassElement cel = staticModel.OwnedClass.Find(o => (o.Choice is CommonModelElementRef) && (o.Choice as CommonModelElementRef).Name == ae.ParticipantClassName); if (cel != null) // It is a CMET - Note: This is where late binding may occur.. ae.ParticipantClassName = (cel.Choice as CommonModelElementRef).CmetName ?? (cel.Choice as CommonModelElementRef).Name; // Resolve to CMET // The type of this end is the type of the association TypeReference tr = new TypeReference(); tr.Container = cc; tr.MemberOf = ClassRepository; #region Type Reference // IS the traversable association referencing a CMET type? // if it is, then we require some extra processing to de-reference the CMET if (ClassRepository.ContainsKey(ae.ParticipantClassName) && ClassRepository[ae.ParticipantClassName] is CommonTypeReference) { // Get the CMET references (which is a CTR in COR) CommonTypeReference ctr = (ClassRepository[ae.ParticipantClassName] as CommonTypeReference); tr = ctr.Class; // Assign the class type reference tr.MemberOf = ClassRepository; // Process this class? if (!ClassRepository.ContainsKey(tr.Name)) PackageParser.ParseClassFromPackage(tr.Name, repository, ClassRepository); if (cc is Property) { (cc as Property).FixedValue = ctr.ClassifierCode; // Assign a fixed classifier code (cc as Property).Documentation = ctr.Documentation; // Assign the documentation } } else if (cel != null) // Bad CMET ref { // JF - Bug processing payload models //// the --ignore-cmet flag if (MifCompiler.hostContext.Mode == Pipeline.OperationModeType.Quirks) { System.Diagnostics.Trace.WriteLine(string.Format("can't make type reference to CMET '{0}' as it wasn't found in the classes. The user has specified the --quirks flag so this error won't be classified as fatal...", (cel.Choice as CommonModelElementRef).CmetName), "quirks"); tr.Name = null; } else throw new InvalidOperationException(string.Format("can't make type reference to CMET '{0}' as it wasn't found anywhere in the repository ({1}).", (cel.Choice as CommonModelElementRef).CmetName, staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT))); } else { if (templateParameters.ContainsKey(ae.ParticipantClassName)) tr.Name = ae.ParticipantClassName; else tr.Name = string.Format("{0}.{1}", staticModel.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : staticModel.PackageLocation.ToString(MifCompiler.NAME_FORMAT), ae.ParticipantClassName); } #endregion return tr; }
/// <summary> /// Apply delta against a property /// </summary> private void ApplyDelta(ClassContent property, RelationshipDeltaData delta) { Trace.WriteLine(string.Format("Delta: Applying deltas for '{0}.{1}'...", property.Container.Name, property.Name), "debug"); // Apply constraints foreach (var constraint in delta.Constraint) ApplyConstraint(property, constraint); }
/// <summary> /// Determine if the class content is a candidate for collapsing /// </summary> private bool IsCandidateForTypeCollapse(ClassContent cc) { // Candidates must be a property with 0..1 and must be // traversable in nature. if (cc.MaxOccurs != "1" || !(cc is Property) || (cc as Property).PropertyType != Property.PropertyTypes.TraversableAssociation || cc.MinOccurs != "0") return false; // Determine the conformance meets criteria if((cc.Conformance == ClassContent.ConformanceKind.Optional || cc.Conformance == ClassContent.ConformanceKind.Required) && !QueryConformance((cc as Property).Type, ClassContent.ConformanceKind.Optional | ClassContent.ConformanceKind.Required)) return false; else if (cc.Conformance == ClassContent.ConformanceKind.Populated) return false; // Make sure none of the child member names appear in the parent class they are to be merged with bool isCandidate = CountReferences((cc as Property).Type) == 1; foreach(ClassContent content in (cc.Container as Class).Content) isCandidate &= HasMember((cc as Property).Type, content.Name); // Now we must determine if there are no other references to the class to be collapsed return isCandidate; }
///----------------------------------------------------------------- #region CodeRule abstract protected abstract void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst);
/// <summary> /// Optimize the <paramref name="feature"/> /// </summary> public MohawkCollege.EHR.gpmr.COR.Feature Optimize(MohawkCollege.EHR.gpmr.COR.Feature f, CombineLog workingLog) { string qualifiedName = String.Format("{0}.{1}", (f as Class).ContainerName, f.Name); // Garbage bin List <String> classGarbageBin = new List <string>(); List <ClassContent> contentGarbageBin = new List <ClassContent>(); // Still valid to process this feature if (!Repository.ContainsKey(qualifiedName)) { return(null); // Can't process non-existant class } // First determine if a class that is identical to this already exists FeatureComparer comparer = new FeatureComparer(); var matchingFeatures = from kv in Repository where comparer.Compare(kv.Value, f) == 0 select kv.Value; CombineInfo currentCombinationLog = new CombineInfo(); // Find matching features in each of the sub-systems if (matchingFeatures.Count() > 1 && CorCollapserPipelineTrigger.combine == true) { System.Diagnostics.Trace.WriteLine(String.Format("{0} other classes can be represented by this class", matchingFeatures.Count()), "debug"); currentCombinationLog.Destination = qualifiedName; foreach (var s in matchingFeatures) { string qName = String.Format("{0}.{1}", (s as Class).ContainerName, s.Name); if (qName != qualifiedName) { System.Diagnostics.Trace.WriteLine(String.Format("\tReplaces '{0}'", qName), "debug"); currentCombinationLog.Class.Add(qName); // Copy alternate traversal data foreach (ClassContent cc in (s as Class).Content) { if (cc is Property && (cc as Property).AlternateTraversalNames != null) { if (((f as Class).Content.Find(o => o.Name == cc.Name) as Property).AlternateTraversalNames == null) { ((f as Class).Content.Find(o => o.Name == cc.Name) as Property).AlternateTraversalNames = new List <Property.AlternateTraversalData>(); } ((f as Class).Content.Find(o => o.Name == cc.Name) as Property).AlternateTraversalNames.AddRange((cc as Property).AlternateTraversalNames); } } // Replace referneces ReplaceReferences(s as Class, f as Class); // Add an annotation f.Annotations.Add(new CodeCombineAnnotation((s as Class).CreateTypeReference())); // Remove this class (Add it to the garbage bin) classGarbageBin.Add(qName); } } workingLog.CombineOps.Add(currentCombinationLog); } // Now collapse members if (CorCollapserPipelineTrigger.collapse) { for (int i = 0; i < (f as Class).Content.Count; i++) { ClassContent cc = (f as Class).Content[i]; // Determine if it is a candidate for collapsing needless complexity if (IsCandidateForMeaninglessComplexityCollapse(cc)) { while (IsCandidateForMeaninglessComplexityCollapse(cc)) { System.Diagnostics.Trace.WriteLine(string.Format("\tCollapsing '{0}'", cc.Name), "debug"); CollapseMemberType(cc, f as Class); } } // Determine if it is a candidate for collapsing the entire type else if (IsCandidateForTypeCollapse(cc)) { System.Diagnostics.Trace.WriteLine(string.Format("\tCollapsing '{0}'", cc.Name), "debug"); CopyMembers((cc as Property).Type, f as Class, cc); contentGarbageBin.Add(cc); } } // Clean up garbage bin (f as Class).Content.RemoveAll(a => contentGarbageBin.Contains(a)); (f as Class).Content.Sort(new ClassContent.Comparator()); } // Clean the garbage bin foreach (string s in classGarbageBin) { Repository.Remove(s); } return(null); }
///----------------------------------------------------------------- #region CodeRule overridable public virtual BuildResult Generate(ScriptContent data) { var variants = new List <FunctionVariant>(); //If needed, Add the default value as a possible class var maxSrc = data.classInfos.Count + (GenerateDefault ? 1 : 0); //Only loop through the dst classes if required var maxDst = GenerationMode == GenerationRule.ForeachSrcCrossDest ? data.classInfos.Count : 1; var infoSrc = new ClassContent(); var infoDst = new ClassContent(); var infoDef = new ClassContent(); if (GenerateDefault) { infoDef.className = data.classDefaultType; } //Loop throught the source classes for (var iSrc = 0; iSrc < maxSrc; iSrc++) { //Add the default value as a possible class infoSrc = GenerateDefault && iSrc == 0 ? infoDef : data.classInfos[iSrc + (GenerateDefault ? -1 : 0)]; if (UseOneClassPerSource) { data.codeGenerated.Add(new ScriptContent.GeneratedCode { className = infoSrc.className, code = string.Empty }); } else if (data.codeGenerated.Count == 0) { data.codeGenerated.Add(new ScriptContent.GeneratedCode { className = string.Empty, code = string.Empty }); } //one pass or as many as the dst classes for (var iSDst = 0; iSDst < maxDst; iSDst++) { if (GenerationMode == GenerationRule.ForeachSrcCrossDest) { infoDst = data.classInfos[iSDst]; } //Gather code variants GatherVariants(variants, data, infoSrc, infoDst); var swapSrc = ClassSrc + infoSrc.className; var swapDst = ClassDst; //Add the Header from the code file if (GenerationMode == GenerationRule.ForeachSrcCrossDest) { swapDst = swapDst + infoDst.className; AddCodeTo(data, data.codeHeader, swapSrc, swapDst); } else { AddCodeTo(data, data.codeHeader, swapSrc); } //Go through all variants and apply them to the code for (var v = 0; v < variants.Count; v++) { var variant = variants[v]; var codeBody = data.codeBody; //Error out if the requested funcs result are not available if (!SwapCodeContent(ref codeBody, Functions, variant.Count, variant.Variants)) { return((BuildResult)BuildResult.ValueType.PrateekScriptInsufficientNames + GetType().Name + infoSrc.className); } //Error out if the requested Names are not available if (!SwapCodeContent(ref codeBody, Names, infoSrc.NameCount, infoSrc.names)) { return((BuildResult)BuildResult.ValueType.PrateekScriptInsufficientNames + infoSrc.className); } if (GenerationMode == GenerationRule.ForeachSrcCrossDest) { AddCodeTo(data, codeBody, swapSrc, swapDst); } else { AddCodeTo(data, codeBody, swapSrc); } } //Add the Footer from the code file if (GenerationMode == GenerationRule.ForeachSrcCrossDest) { AddCodeTo(data, data.codeFooter, swapSrc, swapDst); } else { AddCodeTo(data, data.codeFooter, swapSrc); } } } for (var c = 0; c < data.codeGenerated.Count; c++) { var codeGenerated = data.codeGenerated[c]; codeGenerated.code = codeGenerated.code.Replace(string.Empty.NewLine(), string.Empty.NewLine() + Glossary.Macros.codeDataTabsTag); data.codeGenerated[c] = codeGenerated; } return(BuildResult.ValueType.Success); }
internal static Property Parse(ClassAttribute clsa, String vocabBindingRealm, ClassRepository cr, Dictionary <string, Package> derivationSuppliers) { // TODO: Support EnumerationValue stuff Property retVal = new Property(); // Name (and busines names) retVal.Name = clsa.Name; foreach (BusinessName bn in clsa.BusinessName) { if (bn.Language == MifCompiler.Language || bn.Language == null) { retVal.BusinessName = bn.Name; } } // Documentation if (clsa.Annotations != null) { retVal.Documentation = DocumentationParser.Parse(clsa.Annotations.Documentation); } // Conformance retVal.Conformance = clsa.IsMandatory ? ClassContent.ConformanceKind.Mandatory : clsa.Conformance == ConformanceKind.Required ? ClassContent.ConformanceKind.Required : ClassContent.ConformanceKind.Optional; if (retVal.Conformance != Property.ConformanceKind.Mandatory && clsa.MinimumMultiplicity == "1") { retVal.Conformance = Property.ConformanceKind.Populated; } // Min / Max occurs if (retVal.Conformance == MohawkCollege.EHR.gpmr.COR.Property.ConformanceKind.Mandatory) { retVal.MinOccurs = "1"; } else { retVal.MinOccurs = clsa.MinimumMultiplicity; } retVal.MaxOccurs = clsa.MaximumMultiplicity == "-1" ? "*" : clsa.MaximumMultiplicity; retVal.MaxLength = clsa.MaximumLength; retVal.MinLength = clsa.MinimumLength; // Structural or non? retVal.PropertyType = clsa.IsImmutable ? Property.PropertyTypes.Structural : Property.PropertyTypes.NonStructural; // Default value retVal.DefaultValue = clsa.DefaultValue; retVal.Initializor = clsa.DefaultFrom == DefaultDeterminerKind.ITS ? Property.InitializorTypes.ITS : clsa.DefaultFrom == DefaultDeterminerKind.Realm ? Property.InitializorTypes.Realm : clsa.DefaultFrom == DefaultDeterminerKind.ReferencingAttribute ? Property.InitializorTypes.ReferencedAttributes : Property.InitializorTypes.DefaultValue; if (clsa.DerivedFrom != null) { retVal.Realization = new List <ClassContent>(); foreach (var dei in clsa.DerivedFrom) { MohawkCollege.EHR.gpmr.COR.Feature ss = null; Package derivationPkg = null; if (!derivationSuppliers.TryGetValue(dei.StaticModelDerivationId, out derivationPkg) || derivationPkg == null) { continue; } // Has the package been compiled? if (!cr.TryGetValue(string.Format("{0}", derivationPkg.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss)) { // Attempt to parse PackageParser.Parse(derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT), derivationPkg.MemberOfRepository, cr); // Ditch if still can't find if (!cr.TryGetValue(string.Format("{0}", derivationPkg.PackageLocation.Artifact == ArtifactKind.RIM ? "RIM" : derivationPkg.PackageLocation.ToString(MifCompiler.NAME_FORMAT)), out ss)) { System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}' (derivation supplier {2})", dei.ClassName, dei.AttributeName, dei.StaticModelDerivationId), "warn"); } } // Feature was found var f = (ss as MohawkCollege.EHR.gpmr.COR.SubSystem).FindClass(dei.ClassName); if (f != null) { ClassContent cc = f.GetFullContent().Find(o => o.Name == dei.AttributeName); retVal.Realization.Add(cc); } else { System.Diagnostics.Trace.WriteLine(String.Format("Can't find derivation class '{0}' for association '{1}' (derivation supplier {2})", dei.ClassName, dei.AttributeName, dei.StaticModelDerivationId), "warn"); } } } // Derived from retVal.DerivedFrom = clsa; // Fixed Value retVal.FixedValue = clsa.FixedValue; // Sort key retVal.SortKey = clsa.SortKey; // Datatype retVal.Type = TypeReferenceParser.Parse(clsa.Type); // Update Modes retVal.UpdateMode = clsa.UpdateModeDefault.ToString(); if (clsa.UpdateModesAllowed != null) { retVal.AllowedUpdateModes = new List <string>(); foreach (string s in clsa.UpdateModesAllowed.Split(',')) { retVal.AllowedUpdateModes.Add(s); } } // Supplier domains if (clsa.Vocabulary != null) { if (clsa.Vocabulary.Code != null && !String.IsNullOrEmpty(clsa.Vocabulary.Code.Code)) // Fixed code { retVal.FixedValue = string.Format("{0}", clsa.Vocabulary.Code.Code); } // JF: If the code system is identified, then bind if (clsa.Vocabulary.Code != null && !String.IsNullOrEmpty(clsa.Vocabulary.Code.CodeSystemName)) // Very odd thing that is present in UV mifs { Trace.WriteLine(String.Format("'{0}' is specified as fixed code's code system, however no fixed code is present. Assuming this is a bound code system instead", "assumption")); retVal.SupplierDomain = cr.Find(o => o is CodeSystem && (o as CodeSystem).Name.Equals(clsa.Vocabulary.Code.CodeSystemName)) as Enumeration; if (retVal.SupplierDomain == null) { Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the code system was not found", clsa.Name, clsa.Vocabulary.Code.CodeSystemName), "warn"); } } if (clsa.Vocabulary.ConceptDomain != null) { retVal.SupplierDomain = cr.Find(o => o is ConceptDomain && (o as ConceptDomain).Name.Equals(clsa.Vocabulary.ConceptDomain.Name)) as Enumeration; if (retVal.SupplierDomain == null && MifCompiler.hostContext.Mode == Pipeline.OperationModeType.Quirks) { retVal.SupplierDomain = cr.Find(o => o is Enumeration && o.Name.Equals(clsa.Vocabulary.ConceptDomain.Name)) as Enumeration; if (retVal.SupplierDomain != null) { Trace.WriteLine(String.Format("'{0}' couldn't be bound to concept domain '{1}', '{2}' with name '{1}' was located, so the binding was changed", clsa.Name, clsa.Vocabulary.ConceptDomain.Name, retVal.SupplierDomain.EnumerationType), "quirks"); } } if (retVal.SupplierDomain == null) { Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the concept domain was not found", clsa.Name, clsa.Vocabulary.ConceptDomain.Name), "warn"); } } if (clsa.Vocabulary.ValueSet != null) { retVal.SupplierDomain = cr.Find(o => o is ValueSet && (o as ValueSet).Name.Equals(clsa.Vocabulary.ValueSet.Name)) as Enumeration; if (retVal.SupplierDomain == null) { Trace.WriteLine(String.Format("'{0}' could not be bound to '{1}' as the value set was not found", clsa.Name, clsa.Vocabulary.ValueSet.Name), "warn"); } if (!String.IsNullOrEmpty(clsa.Vocabulary.ValueSet.RootCode)) { bool shouldFix = false; if (retVal.SupplierDomain != null) { var enumLiteral = retVal.SupplierDomain.Literals.Find(o => o.Name == clsa.Vocabulary.ValueSet.RootCode); shouldFix = enumLiteral != null && enumLiteral.RelatedCodes != null && enumLiteral.RelatedCodes.Count == 0; } if (shouldFix) { retVal.FixedValue = String.Format("{0}", clsa.Vocabulary.ValueSet.RootCode); } } } // Supplier strength(s) if (clsa.Vocabulary.ValueSet != null) { retVal.SupplierStrength = clsa.Vocabulary.ValueSet.CodingStrength == CodingStrengthKind.CNE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions: clsa.Vocabulary.ValueSet.CodingStrength == CodingStrengthKind.CWE ? (Property.CodingStrengthKind?)Property.CodingStrengthKind.CodedNoExtensions : null; } // Supplier domain strength if (retVal.SupplierDomain != null) { if (defaultCodingStrengths.ContainsKey(retVal.SupplierDomain.Name ?? "") && !retVal.SupplierStrength.HasValue) { retVal.SupplierStrength = defaultCodingStrengths[retVal.SupplierDomain.Name]; } else { retVal.SupplierStrength = Property.CodingStrengthKind.CodedNoExtensions; System.Diagnostics.Trace.WriteLine(string.Format("No vocabulary value set on property {0}! Defaulting to CNE for supplier strength", retVal.Name), "assumption"); } } } return(retVal); }
public Dictionary <String, IEnumerable <String> > GetPackageFiles(Schema Schema, String NamespaceName) { var NamespaceToClasses = new Dictionary <String, List <KeyValuePair <String, List <String> > > >(); void AddClass(String ClassNamespaceName, String ClassName, IEnumerable <String> ClassContent) { if (!NamespaceToClasses.ContainsKey(ClassNamespaceName)) { NamespaceToClasses.Add(ClassNamespaceName, new List <KeyValuePair <String, List <String> > >()); } NamespaceToClasses[ClassNamespaceName].Add(new KeyValuePair <String, List <String> >(ClassName, ClassContent.ToList())); } var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).Where(t => t.Version() == "").ToList(); if (Commands.Count > 0) { var SchemaClosureGenerator = Schema.GetSchemaClosureGenerator(); var Hash = SchemaClosureGenerator.GetSubSchema(Schema.Types.Where(t => (t.OnClientCommand || t.OnServerCommand) && t.Version() == ""), new List <TypeSpec> { }).GetNonattributed().Hash(); AddClass(NamespaceName, "IJsonSender", IJsonSender()); AddClass(NamespaceName, "JsonSerializationClient", JsonSerializationClient(Hash, Commands, SchemaClosureGenerator, NamespaceName)); } AddClass(NamespaceName, "JsonTranslator", JsonTranslator(Schema, NamespaceName)); return(NamespaceToClasses.SelectMany(p => p.Value.Select(v => new KeyValuePair <String, IEnumerable <String> >(String.Join("/", p.Key.Split('.').Where(NamespacePart => NamespacePart != "").Select(NamespacePart => LowercaseCamelize(NamespacePart)).Concat(new String[] { v.Key })), WrapModule(p.Key, Schema.Imports, v.Value)))).ToDictionary(p => p.Key, p => p.Value)); }
public List <String> GetTypes(Schema Schema, String NamespaceName) { var Primitives = GetPrimitives(Schema); var NamespaceToClasses = new Dictionary <String, List <List <String> > >(); void AddClass(String ClassNamespaceName, IEnumerable <String> ClassContent) { if (!NamespaceToClasses.ContainsKey(ClassNamespaceName)) { NamespaceToClasses.Add(ClassNamespaceName, new List <List <String> >()); } NamespaceToClasses[ClassNamespaceName].Add(ClassContent.ToList()); } foreach (var c in Schema.Types) { if (c.OnPrimitive) { if (c.VersionedName() == "Unit") { AddClass(c.NamespaceName(), Primitive_Unit()); } else if (c.VersionedName() == "Optional") { AddClass(c.NamespaceName(), Primitive_Optional()); } else { continue; } } else if (c.OnAlias) { AddClass(c.NamespaceName(), Alias(c.Alias)); } else if (c.OnRecord) { AddClass(c.NamespaceName(), Record(c.Record)); } else if (c.OnTaggedUnion) { AddClass(c.NamespaceName(), TaggedUnion(c.TaggedUnion)); } else if (c.OnEnum) { AddClass(c.NamespaceName(), Enum(c.Enum)); } else if (c.OnClientCommand) { AddClass(c.NamespaceName(), ClientCommand(c.ClientCommand)); } else if (c.OnServerCommand) { AddClass(c.NamespaceName(), ServerCommand(c.ServerCommand)); } else { throw new InvalidOperationException(); } } var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).ToList(); if (Commands.Count > 0) { AddClass(NamespaceName, IApplicationServer(Commands, NamespaceName)); AddClass(NamespaceName, IApplicationClient(Commands, NamespaceName)); AddClass(NamespaceName, IEventPump(Commands, NamespaceName)); } var Classes = NamespaceToClasses.Select(p => WrapNamespace(p.Key, p.Value.Join(new String[] { "" }))); return((new List <List <String> > { Primitives }).Concat(Classes).Join(new String[] { "" }).ToList()); }
/// <summary> /// Render class content to class file /// </summary> private string RenderClassContent(ClassContent cc, string ownerPackage, int propertySort) { StringWriter sw = new StringWriter(); // Render the backing field TypeReference backingFieldType = null; if (cc is Property) { // HACK: Java can't hide members, so what we need to do // is detect if the model changes data types between overridden // classes. backingFieldType = GetBackingFieldTypeThroughChildren((cc as Property), cc.Container as Class); // backingFieldType = (cc as Property).Type; } else { backingFieldType = ((cc as Choice).Content[0] as Property).Type; if (backingFieldType != null && backingFieldType.Class != null) backingFieldType = backingFieldType.Class.BaseClass; else backingFieldType = new TypeReference() { Name = null }; foreach (var chc in (cc as Choice).Content) { if (backingFieldType.Name == null) break; // Just going to use System.Object Anyways Property chcProperty = chc as Property; // Cast a property // This line ensures that a common root class can be used across all the choices if (chcProperty.Type == null || chcProperty.Type.Class == null || chcProperty.Type.Class.BaseClass.Name != backingFieldType.Name) backingFieldType = new TypeReference() { Name = null }; } } // Backing field write sw.WriteLine("\t// Backing field for {0}", cc.Name); sw.Write("\tprivate "); // Fixed value? //if (cc is Property && !String.IsNullOrEmpty((cc as Property).FixedValue)) // sw.Write("final "); // Datatype reference string dtr = CreateDatatypeRef(backingFieldType, cc as Property, ownerPackage); bool initialize = false, isNativeCollection = false; if (cc.MaxOccurs != "1" && !Datatypes.IsCollectionType(backingFieldType)) { dtr = string.Format("ArrayList<{0}>", dtr); initialize = true; isNativeCollection = true; } sw.Write("{0} m_{1}", dtr, Util.Util.MakeFriendly(cc.Name)); if (initialize) sw.Write(" = new {0}()", dtr); string setterName = "set"; // TODO: Fixed Values here var property = cc as Property; // Only render fixed values when: // 1. The property is a property // 2. The property has a fixed value // 3. The property is mandatory or populated // 4. The property is not a traversable association. if (property != null && !String.IsNullOrEmpty(property.FixedValue) && (property.Conformance == ClassContent.ConformanceKind.Populated || property.Conformance == ClassContent.ConformanceKind.Mandatory) && property.PropertyType != Property.PropertyTypes.TraversableAssociation) { // Get the real supplier (value set, or code system if concept domain) var splrCd = property.SupplierDomain as ConceptDomain; var bindingDomain = property.SupplierDomain; Enumeration.EnumerationValue ev = null; if (splrCd != null && splrCd.ContextBinding != null && splrCd.ContextBinding.Count == 1) bindingDomain = splrCd.ContextBinding[0]; if(bindingDomain != null) ev = bindingDomain.GetEnumeratedLiterals().Find(o => o.Name == (property.FixedValue ?? property.DefaultValue)); bool wontRenderBd = bindingDomain != null ? String.IsNullOrEmpty(EnumerationRenderer.WillRender(bindingDomain)) : true; if (bindingDomain == null) sw.Write(" = ({2})org.marc.everest.formatters.FormatterUtil.fromWireFormat(\"{1}\", {0}.class);", backingFieldType.Name, property.FixedValue, dtr); else if (ev == null || wontRenderBd) // Enumeration value is not known in the enumeration, fixed value fails { System.Diagnostics.Trace.WriteLine(String.Format("Can't find literal '{0}' in supplier domain for property '{1}'", property.FixedValue, property.Name), "error"); if (wontRenderBd) // wont be rendering binding domain, so best to just emit it { if(Datatypes.GetOverrideSetters(backingFieldType, property, ownerPackage).FirstOrDefault(o=>o.Parameters.Count == 2) != null) sw.Write(" = new {0}(\"{1}\", {2})", dtr, property.FixedValue, ev == null ? "null" : String.Format("\"{0}\"", ev.CodeSystem)); else sw.Write(" = new {0}(\"{1}\")", dtr, property.FixedValue, ev == null ? "null" : String.Format("\"{0}\"", ev.CodeSystem)); } else sw.Write(" = new {0}(new {2}(\"{3}\"))", dtr, ownerPackage, Util.Util.MakeFriendly(EnumerationRenderer.WillRender(property.SupplierDomain)), property.FixedValue); } else // Fixed value is known sw.Write(" = new {2}({0}.{1})", Util.Util.MakeFriendly(EnumerationRenderer.WillRender(bindingDomain)), Util.Util.PascalCase(ev.BusinessName ?? ev.Name), dtr, ownerPackage); // Update setter name so the output method has the right naming convention setterName = "override"; } sw.WriteLine(";"); // Render the documentation sw.Write(DocumentationRenderer.Render(cc.Documentation, 1)); // Render the property attribute sw.Write(RenderPropertyAttribute(cc, ownerPackage, propertySort)); // JF: Are there any members in the parent that we're overriding? String modifier = ""; if (cc.Container != null && cc.Container is Class) { var containerClassRef = (cc.Container as Class).BaseClass; while (containerClassRef != null && containerClassRef.Class != null) { foreach (var content in containerClassRef.Class.Content) { if (content.ToString() == property.ToString()) modifier = "@Override"; //else if (content is Property && CreatePascalCasedName(content as Property) == pName || // content is Choice && CreatePascalCasedName(content as Choice) == pName) // modifier = "new virtual"; } containerClassRef = containerClassRef.Class.BaseClass; } } // Render the getter sw.Write(modifier); sw.WriteLine("\tpublic {0} get{1}() {{ return this.m_{2}; }}", dtr, Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(cc.Name)); // Render setters // Default setter sw.Write(DocumentationRenderer.Render(cc.Documentation, 1)); sw.Write(modifier); sw.WriteLine("\tpublic void {3}{1}({0} value) {{ this.m_{2} = value; }}", dtr, Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(cc.Name), setterName); // Now to render the helper methods that can set the backing property, these are convenience methods if (cc is Choice && !isNativeCollection) { // Now, return getAsMethods StringBuilder getTraversalFor = new StringBuilder(); foreach (Property p in (cc as Choice).Content) { if (p.Type.Class != null && p.Type.Class.IsAbstract) continue; // don't output abstract classes getTraversalFor.AppendFormat("\t\tif(this.m_{0} instanceof {1}) return \"{2}\";\r\n", Util.Util.MakeFriendly(cc.Name), CreateDatatypeRef(p.Type, p, ownerPackage, false), p.Name); sw.WriteLine("\t/** Gets the {0} property cast to {1} or null if {0} is not an instance of {1}. This happens when the traversal name is {2}. This convenience method saves the developer from casting */", Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(p.Type.Name), p.Name); sw.WriteLine("\tpublic {0} get{1}If{4}() {{ if(this.m_{3} instanceof {0}) return ({0})this.m_{3}; else return null; }}", CreateDatatypeRef(p.Type, p, ownerPackage), Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(p.Type.Name), Util.Util.MakeFriendly(cc.Name), Util.Util.PascalCase(p.Name)); sw.WriteLine("\t/** Sets the {0} property given the specified instance of {1}. */", Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(p.Type.Name)); sw.WriteLine("\tpublic void {3}{1}({0} value) {{ this.m_{2} = value; }}", CreateDatatypeRef(p.Type, p, ownerPackage), Util.Util.PascalCase(cc.Name), Util.Util.MakeFriendly(cc.Name), setterName); } sw.WriteLine("\t/** Gets the actual traversal name used for the choice element {0}, null if traversal was not provided **/", Util.Util.PascalCase(cc.Name)); sw.WriteLine("\tpublic String get{0}TraversalName() {{", Util.Util.PascalCase(cc.Name)); sw.WriteLine(getTraversalFor); sw.WriteLine("\t\treturn null;"); sw.WriteLine("\t}"); ; // TODO: Factory methods and etc } else if (!isNativeCollection) { foreach (var sod in MohawkCollege.EHR.gpmr.Pipeline.Renderer.Java.HeuristicEngine.Datatypes.GetOverrideSetters(backingFieldType, cc as Property, ownerPackage)) { sw.Write(DocumentationRenderer.Render(cc.Documentation, 1)); sw.Write("\tpublic void {1}{0}(", Util.Util.PascalCase(cc.Name), setterName); foreach (var parm in sod.Parameters) { sw.Write("{0} {1}", parm.DataType, parm.Name); if (sod.Parameters.Last() != parm) sw.Write(", "); } sw.Write(")"); if (sod.Throws != null && sod.Throws.Count > 0) { sw.Write(" throws "); foreach (var thrw in sod.Throws) sw.Write("{0} {1}", thrw.Type, thrw == sod.Throws.Last() ? "" : ","); } sw.WriteLine("{"); sw.WriteLine("\t\t{0}", sod.SetterText); sw.WriteLine("\t\tthis.m_{0} = {1};", Util.Util.MakeFriendly(cc.Name), sod.ValueInstance.Name); sw.WriteLine("\t}"); } } return sw.ToString(); }
///----------------------------------------------------------------- #region Rule internal protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst) { infos.Clear(); Glossary.Macros.GetTags(this); variants.Clear(); if (scriptContent.functionContents.Count == 0) { return; } var result = string.Empty; var variant = new FunctionVariant(result); for (var k = 0; k < infos.Count; k++) { result += scriptContent.functionContents[0].body; result = (Variables[0] + infos[k].name).Apply(result); } variant[0] = result; variants.Add(variant); }
private string CreateProperty(ClassContent cc, String ownerNs, int propertySort) { // JF: Supporting CeRX // There are some things where there is a choice that has no choices .. ? if (cc is Choice && (cc as Choice).Content.Count == 0) { Trace.WriteLine(String.Format("Choice '{0}' has no content, property will not be rendered!", cc.Name), "warn"); return String.Empty; } StringWriter sw = new StringWriter(); // Output documentation if (cc.Documentation != null) sw.Write(DocumentationRenderer.Render(cc.Documentation, 2).Replace("<summary>",String.Format("<summary>({0}) ", cc.Conformance))); else if (cc is Property && (cc as Property).Type.ClassDocumentation != null) sw.Write(DocumentationRenderer.Render((cc as Property).Type.ClassDocumentation, 2).Replace("<summary>", String.Format("<summary>({0}) ", cc.Conformance))); // Correct documentation if (sw.ToString().Length == 0) sw.WriteLine("\t\t/// <summary>({0}) {1}</summary>", cc.Conformance, cc.BusinessName == null ? "Documentation was not found" : cc.BusinessName.Replace("\r", "").Replace("\n","").Replace("&", "&")); // Markers foreach (String s in Enum.GetNames(typeof(MarkerAttribute.MarkerAttributeType))) if (Util.Util.PascalCase(cc.Name) == s) sw.Write(CreateMarkerAttribute((MarkerAttribute.MarkerAttributeType)Enum.Parse(typeof(MarkerAttribute.MarkerAttributeType), s), 2)); // Determine property attributes if (cc is Property) { #region Properties Property property = cc as Property; // JF - 19/04/10 : This code is used to support the collapsing of C# classes foreach(var annotation in property.Annotations) if (annotation is CodeCollapseAnnotation) { CodeCollapseAnnotation cca = annotation as CodeCollapseAnnotation; sw.Write("\t\t[PropertyCollapse(Name = \"{0}\", Order = {1}", cca.Name, cca.Order); string fixedValueString = ""; // Create the fixed value string if(cca.OriginalType != null && cca.OriginalType.Class != null) foreach(var originalContent in cca.OriginalType.Class.Content) // Iterate through the original type's members if (originalContent is Property && (originalContent as Property).PropertyType == MohawkCollege.EHR.gpmr.COR.Property.PropertyTypes.Structural && !String.IsNullOrEmpty((originalContent as Property).FixedValue)) // If the member is a structural property and the value is fixed then add fixedValueString += String.Format("{0}={1}|", originalContent.Name, (originalContent as Property).FixedValue); if (!String.IsNullOrEmpty(fixedValueString)) // Set the fixed value string sw.Write(", FixedAttributeValues = \"{0}\"", fixedValueString.Substring(0, fixedValueString.Length - 1)); // Now end the property sw.WriteLine(")]"); } // Property attribute sw.Write(CreatePropertyAttribute(cc as Property, ownerNs, 2, propertySort)); sw.WriteLine("#if !WINDOWS_PHONE"); // Set browsing off for fixed values if (property.FixedValue != null && property.PropertyType != Property.PropertyTypes.TraversableAssociation) { sw.WriteLine("\t\t[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]"); sw.WriteLine("\t\t[System.ComponentModel.ReadOnly(true)]"); sw.WriteLine("\t\t[System.ComponentModel.Browsable(false)]"); } // Designer category, etc sw.WriteLine("\t\t[System.ComponentModel.Category(\"{0}\")]", property.Conformance); sw.WriteLine("\t\t[System.ComponentModel.Description(\"{0}\")]", Util.Util.StringEscape(property.BusinessName != null ? property.BusinessName.Replace("\n","").Replace("\r","") : property.Name)); // Which type converter? TypeReference tr = Datatypes.MapDatatype((cc as Property).Type); if (property.SupplierDomain != null) sw.WriteLine("\t\t[System.ComponentModel.TypeConverter(typeof(MARC.Everest.Design.DataTypeConverter))]"); else { sw.WriteLine("\t\t[System.ComponentModel.TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]"); if (!(property.MaxOccurs != "1" && (!Datatypes.IsCollectionType(tr)))) sw.WriteLine("\t\t[System.ComponentModel.Editor(typeof(MARC.Everest.Design.NewInstanceTypeEditor), typeof(System.Drawing.Design.UITypeEditor))]"); } // Default value if (property.DefaultValue != null) sw.WriteLine("\t\t[System.ComponentModel.DefaultValue(\"{0}\")]", property.DefaultValue); sw.WriteLine("#endif"); // Determine the datatype string dt = ""; dt = CreateDatatypeRef(tr, property); sw.Write("\t\tpublic "); // Property name // IF the property name is equal to the generic parameter, we don't pascal case it // IF the property name is equal to the containing class name, we use the name of the datatype it references as the property name // Is this a backing property string pName = CreatePascalCasedName(cc as Property); // JF: Are there any members in the parent that we're overriding? string modifier = "virtual"; if (property.Container != null && property.Container is Class) { var containerClassRef = (property.Container as Class).BaseClass; while (containerClassRef != null && containerClassRef.Class != null) { foreach (var content in containerClassRef.Class.Content) { if (content.ToString() == property.ToString()) modifier = "override"; else if (content is Property && CreatePascalCasedName(content as Property) == pName || content is Choice && CreatePascalCasedName(content as Choice) == pName) modifier = "new virtual"; } containerClassRef = containerClassRef.Class.BaseClass; } } sw.Write("{0} ", modifier); // Is it a list? if (property.MaxOccurs != "1" && (!Datatypes.IsCollectionType(tr))) sw.Write("List<{0}>", dt); else sw.Write(dt); sw.Write(" {0} {{", pName); // Property fixed if ((property.FixedValue != null || (property.DefaultValue != null && (property.Conformance == ClassContent.ConformanceKind.Populated || property.Conformance == ClassContent.ConformanceKind.Mandatory))) && property.PropertyType != Property.PropertyTypes.TraversableAssociation ) // Type Reference for default value { if (property.SupplierDomain != null && dt.Contains(Util.Util.MakeFriendly(property.SupplierDomain.Name) + ">") && property.SupplierStrength == MohawkCollege.EHR.gpmr.COR.Property.CodingStrengthKind.CodedNoExtensions) // supplier domain is known { // Get the real supplier (value set, or code system if concept domain) var splrCd = property.SupplierDomain as ConceptDomain; var bindingDomain = property.SupplierDomain; Enumeration.EnumerationValue ev = null; if (splrCd != null && splrCd.ContextBinding != null && splrCd.ContextBinding.Count == 1) bindingDomain = splrCd.ContextBinding[0]; ev = bindingDomain.GetEnumeratedLiterals().Find(o => o.Name == (property.FixedValue ?? property.DefaultValue)); if (ev == null) // Enumeration value is not known in the enumeration, fixed value fails { System.Diagnostics.Trace.WriteLine(String.Format("Can't find literal '{0}' in supplier domain for property '{1}'", property.FixedValue ?? property.DefaultValue, property.Name), "error"); sw.WriteLine(" get; set; }"); } else if(!Datatypes.IsCollectionType(tr)) // Fixed value is known sw.WriteLine(" get {{ return __{3}; }} set {{ __{3} = value; }} }}\r\n\t\tprivate {2} __{3} = {0}.{1};", Util.Util.MakeFriendly(EnumerationRenderer.WillRender(bindingDomain)), Util.Util.PascalCase(ev.BusinessName ?? ev.Name), dt, Util.Util.MakeFriendly(cc.Name)); else // Fixed value is known but it is some sort of collection sw.WriteLine(" get {{ return __{2}; }} set {{ __{2} = value; }} }}\r\n\t\tprivate {1} __{2} = MARC.Everest.Connectors.Util.Convert<{1}>(\"{0}\", false);", property.FixedValue ?? property.DefaultValue, CreateDatatypeRef(property.Type, property), Util.Util.MakeFriendly(cc.Name)); } else if (property.Type.Class == null) sw.WriteLine(" get {{ return __{2}; }} set {{ __{2} = value; }} }}\r\n\t\tprivate {1} __{2} = MARC.Everest.Connectors.Util.Convert<{1}>(\"{0}\", false);", property.FixedValue ?? property.DefaultValue, CreateDatatypeRef(property.Type, property), Util.Util.MakeFriendly(cc.Name)); else sw.Write(" get; set; }"); // Can't be cast } else if (property.MaxOccurs != "1" && (!Datatypes.IsCollectionType(tr))) sw.WriteLine(" get {{ return __{0}; }} set {{ __{0} = value; }} }}\r\n\t\tprivate List<{1}> __{0} = new List<{1}>();", Util.Util.MakeFriendly(cc.Name), dt); else sw.WriteLine(" get; set; }"); #endregion } // cc is property else // cc is choice { // Find the base type TypeReference tr = new TypeReference(); Choice choice = cc as Choice; if (cc.Documentation != null) sw.Write(DocumentationRenderer.Render(cc.Documentation, 2)); else { sw.WriteLine("\t\t/// <summary>\r\n\t\t/// Choice Of: <list><listheader><term>Traversal</term><description>Class</description></listheader>"); foreach (Property p in choice.Content) sw.WriteLine("\t\t/// <item><term>{1}</term><description>When class is <see cref=\"T:{2}.{0}\"/></description></item>", p.Type, p.Name, ownerNs); sw.WriteLine("\t\t/// </list></summary>"); } // Create property attributes foreach (Property p in choice.Content) sw.Write(CreatePropertyAttribute(p, ownerNs, 2, propertySort)); // Write editor attributes sw.WriteLine("#if !WINDOWS_PHONE"); sw.WriteLine("\t\t[System.ComponentModel.TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]"); if (!(cc.MaxOccurs != "1" && !Datatypes.IsCollectionType(tr))) sw.WriteLine("\t\t[System.ComponentModel.Editor(typeof(MARC.Everest.Design.NewInstanceTypeEditor), typeof(System.Drawing.Design.UITypeEditor))]"); sw.WriteLine("#endif"); // Get the type reference tr = (choice.Content[0] as Property).Type.Class.BaseClass; List<String> methods = new List<string>(); StringBuilder getTraversalFor = new StringBuilder(); foreach (Property p in choice.Content) { // Set the property if (p.Type.Class.BaseClass != null && tr != null && p.Type.Class.BaseClass.Name != tr.Name) tr = null; if (p.Type.Class != null && p.Type.Class.IsAbstract) continue; // don't output abstract classes getTraversalFor.AppendFormat("\t\tif(this.$$pcName$$ is {0}) return \"{1}\";\r\n", CreateDatatypeRef(p.Type, p), p.Name); // Generate getter // Generate a SETProperty method that sets for this permutation StringBuilder method_sb = new StringBuilder("\t\t"); method_sb.AppendFormat("/// <summary> Get <see cref=\"P:$$pcName$$\"/> cast as an instance of <see cref=\"T:{0}\"/>. This occurs when $$pcName$$ is represented as {1}. Null if <see cref=\"P:$$pcName$$\"/> is not an instance of <see cref=\"T:{0}\"/></summary>\r\n", CreateDatatypeRef(p.Type, p), p.Name); method_sb.AppendFormat("public {0} Get$$pcName$$If{2}() {{ return this.$$pcName$$ as {0}; }}\r\n", CreateDatatypeRef(p.Type, p), Util.Util.MakeFriendly(p.Type.Name), Util.Util.PascalCase(p.Name)); method_sb.AppendFormat("/// <summary> Set <see cref=\"P:$$pcName$$\"/> to an instance of <see cref=\"T:{0}\"/> </summary>\r\n", CreateDatatypeRef(p.Type, p)); method_sb.AppendFormat("\t\t/// <param name=\"value\">The value to set $$pcName$$ to</param>\r\n"); method_sb.AppendFormat("\t\tpublic void Set$$pcName$$({0} value) {{ this.$$pcName$$ = value; }}\r\n", CreateDatatypeRef(p.Type, p)); methods.Add(method_sb.ToString()); // Generate a shortcut SETProperty method if (factoryMethods.ContainsKey(p.Type.Name)) { foreach (FactoryMethodInfo mi in factoryMethods[p.Type.Name]) { method_sb = new StringBuilder(); StringBuilder methodSig = new StringBuilder(); method_sb.AppendFormat("\r\n\t\tpublic void Set{0}(", Util.Util.PascalCase(cc.Name)); methodSig.AppendFormat("public void Set{0}(", Util.Util.PascalCase(cc.Name)); // Get the parameters foreach (string parm in mi.parameters) if (parm.Length > 0) { string mParm = parm; method_sb.AppendFormat("{0},", mParm); methodSig.AppendFormat("{0},", mParm.Substring(0, mParm.LastIndexOf(" "))); } method_sb.Remove(method_sb.Length - 1, 1); // Ensure that we don't declare the same method signature twice if (m_methodDeclarations.Contains(methodSig.ToString())) continue; // Add a declaration m_methodDeclarations.Add(methodSig.ToString()); // Insert the documentation method_sb.Insert(0, mi.documentation); method_sb.Insert(0, String.Format("/// <summary> Set <see cref=\"P:{0}\"/> to an instance of <see cref=\"T:{1}\"/> using the parameters specified</summary>\r\n", Util.Util.PascalCase(cc.Name), p.Type.Name)); method_sb.AppendFormat(") {{ this.$$pcName$$ = {0}(", mi.name); foreach (var parm in mi.parameters) if (parm.Length > 0) method_sb.AppendFormat("{0},", parm.Split(' ')[1]); method_sb.Remove(method_sb.Length - 1, 1); method_sb.Append("); }"); methods.Add(method_sb.ToString()); } } } // If no type reference is agreed to, then the type reference is Object! string dt = tr == null ? "System.Object" : CreateDatatypeRef(tr, choice.Content[0] as Property); sw.Write("\t\tpublic "); // Is it a list? if (cc.MaxOccurs != "1" && (!Datatypes.IsCollectionType(tr))) sw.Write("List<{0}>", dt); else sw.Write(dt); // Property name // IF the property name is equal to the generic parameter, we don't pascal case it // IF the property name is equal to the containing class name, we use the name of the datatype it references as the property name string pName = CreatePascalCasedName(choice); sw.WriteLine(" {0} {{ get; set; }}", pName); // Get traversal name sw.WriteLine("\t/// <summary>Gets the actual traversal name used for the choice property <see cref=\"P:{0}\"/>, null if traversal was not provided </summary>", Util.Util.PascalCase(cc.Name)); sw.WriteLine("\tpublic String Get{0}TraversalName() {{", Util.Util.PascalCase(cc.Name)); sw.WriteLine(getTraversalFor.Replace("$$pcName$$", pName)); sw.WriteLine("\t\treturn null;"); sw.WriteLine("\t}"); // Write the setters foreach (string s in methods) sw.WriteLine(s.Replace("$$pcName$$", pName)); } return sw.ToString(); }
///----------------------------------------------------------------- private void GatherVariants(int s, int[] slots, List <FunctionVariant> variants, ScriptContent data, ClassContent contentSrc, ClassContent contentDst) { if (s < slots.Length) { for (var p = 0; p < 2; p++) { slots[s] = p; GatherVariants(s + 1, slots, variants, data, contentSrc, contentDst); } } else { var variant = new FunctionVariant(2); for (var sv = 0; sv < slots.Length; sv++) { if (slots[sv] == 0) { for (var i = 0; i < data.functionContents.Count; i++) { var info = data.functionContents[i].body; info = (Names[0] + contentSrc.names[sv * 2 + 0]).Apply(info); info = (Names[1] + contentSrc.names[sv * 2 + 1]).Apply(info); variant[i] = info; } } } if (variant.Call != string.Empty) { variants.Add(variant); } } }
public Dictionary <String, IEnumerable <String> > GetPackageFiles(Schema Schema, String NamespaceName) { var NamespaceToClasses = new Dictionary <String, List <KeyValuePair <String, List <String> > > >(); void AddClass(String ClassNamespaceName, String ClassName, IEnumerable <String> ClassContent) { if (!NamespaceToClasses.ContainsKey(ClassNamespaceName)) { NamespaceToClasses.Add(ClassNamespaceName, new List <KeyValuePair <String, List <String> > >()); } NamespaceToClasses[ClassNamespaceName].Add(new KeyValuePair <String, List <String> >(ClassName, ClassContent.ToList())); } foreach (var c in Schema.Types) { if (c.OnPrimitive) { if (c.VersionedName() == "Unit") { AddClass(c.NamespaceName(), "Unit", Primitive_Unit()); } else if (c.VersionedName() == "Set") { AddClass(c.NamespaceName(), "Set", Primitive_Set()); } else { var p = c.Primitive; if (PrimitiveMapping.ContainsKey(p.VersionedName())) { var Name = p.VersionedName(); var PlatformName = PrimitiveMapping[Name]; if (Name != PlatformName && p.GenericParameters.Count() == 0 && PlatformName != "Error") { AddClass(c.NamespaceName(), Name, Primitive(Name, PlatformName)); } else { continue; } } } } else if (c.OnAlias) { AddClass(c.NamespaceName(), c.DefinitionName(), Alias(c.Alias)); } else if (c.OnRecord) { AddClass(c.NamespaceName(), c.DefinitionName(), Record(c.Record)); } else if (c.OnTaggedUnion) { AddClass(c.NamespaceName(), c.DefinitionName(), TaggedUnion(c.TaggedUnion)); } else if (c.OnEnum) { AddClass(c.NamespaceName(), c.DefinitionName(), Enum(c.Enum)); } else if (c.OnClientCommand) { var tc = c.ClientCommand; var RequestRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Request"); var Request = new RecordDef { Name = RequestRef.Name, Version = RequestRef.Version, GenericParameters = new List <VariableDef> { }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description }; var ReplyRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Reply"); var Reply = new TaggedUnionDef { Name = ReplyRef.Name, Version = ReplyRef.Version, GenericParameters = new List <VariableDef> { }, Alternatives = tc.InParameters, Attributes = tc.Attributes, Description = tc.Description }; AddClass(c.NamespaceName(), Request.DefinitionName(), Record(Request)); AddClass(c.NamespaceName(), Reply.DefinitionName(), TaggedUnion(Reply)); } else if (c.OnServerCommand) { var tc = c.ServerCommand; var EventRef = GetSuffixedTypeRef(tc.Name, tc.Version, "Event"); var Event = new RecordDef { Name = EventRef.Name, Version = EventRef.Version, GenericParameters = new List <VariableDef> { }, Fields = tc.OutParameters, Attributes = tc.Attributes, Description = tc.Description }; AddClass(c.NamespaceName(), Event.DefinitionName(), Record(Event)); } else { throw new InvalidOperationException(); } } var scg = Schema.GetSchemaClosureGenerator(); var sc = scg.GetClosure(Schema.TypeRefs.Concat(Schema.Types), new List <TypeSpec> { }); var Tuples = sc.TypeSpecs.Where(t => t.OnTuple).ToList(); foreach (var t in Tuples) { AddClass(NamespaceName, t.SimpleName(NamespaceName), Tuple(t, NamespaceName)); } var Commands = Schema.Types.Where(t => t.OnClientCommand || t.OnServerCommand).Where(t => t.Version() == "").ToList(); if (Commands.Count > 0) { AddClass(NamespaceName, "IApplicationClient", IApplicationClient(Commands, NamespaceName)); } return(NamespaceToClasses.SelectMany(p => p.Value.Select(v => new KeyValuePair <String, IEnumerable <String> >(String.Join("/", p.Key.Split('.').Where(NamespacePart => NamespacePart != "").Select(NamespacePart => LowercaseCamelize(NamespacePart)).Concat(new String[] { v.Key })), WrapModule(p.Key, Schema.Imports, v.Value)))).ToDictionary(p => p.Key, p => p.Value)); }
///----------------------------------------------------------------- private void GatherVariantsSlots(int s, int[] slots, List <FunctionVariant> variants, ScriptContent data, ClassContent contentSrc, ClassContent contentDst) { var varCount = contentSrc.VarCount + 1; for (var c = 0; c < varCount; c++) { slots[s] = c; if (s + 1 < slots.Length) { GatherVariantsSlots(s + 1, slots, variants, data, contentSrc, contentDst); } else { if (data.classDefaultExportOnly) { var foundValid = false; for (var exp = 0; exp < slots.Length; exp++) { if (slots[exp] >= contentSrc.VarCount) { foundValid = true; break; } } if (!foundValid) { continue; } } var sn = 0; var variant = new FunctionVariant(3); variant[1] += Glossary.Code.argsV; for (var v = 0; v < slots.Length; v++) { var sv = slots[v]; if (sv < contentSrc.VarCount) { var name = sv < contentSrc.NameCount ? contentSrc.names[sv] : contentSrc.variables[sv]; variant.Call = name; var variable = contentSrc.variables[sv]; variant[2] = string.Format(Glossary.Code.varsV, variable); } else { variant.Call = Glossary.Code.callN; variant[1] = string.Format(Glossary.Code.argsNOpt, data.classDefaultType, sn, data.classDefaultValue); variant[2] = string.Format(Glossary.Code.varsN, sn); sn++; } } if (sn != slots.Length) { variants.Add(variant); } } } }
public void AddContent(ClassContent c) { c.Container = this; content.Add(c); // Sort, any structural properties come before non structural props. content.Sort(new ClassContent.Comparator()); }
///----------------------------------------------------------------- #region Rule internal protected override void GatherVariants(List <FunctionVariant> variants, ScriptContent scriptContent, ClassContent contentSrc, ClassContent contentDst) { keywords.Clear(); identifiers.Clear(); Glossary.Macros.GetTags(this); variants.Clear(); if (scriptContent.functionContents.Count == 0) { return; } var result = string.Empty; for (var k = 0; k < keywords.Count; k++) { result += scriptContent.functionContents[0].body; result = (Variables[0] + keywords[k]).Apply(result); } var variant = new FunctionVariant(result, 1); result = string.Empty; for (var i = 0; i < identifiers.Count; i++) { result += scriptContent.functionContents[0].body; result = (Variables[0] + identifiers[i]).Apply(result); } variant[1] = result; variants.Add(variant); }
/// <summary> /// Collapse the data type of <paramref name="cc"/> so that it is the only meaningful data type provided by its /// natural type /// </summary> private void CollapseMemberType(ClassContent cc, Class context) { if(!(cc is Property)) throw new InvalidOperationException("Can't collapse this member type"); // Not a candidate // The condition for this type of collection is that the referenced type: // 1. Provides only ONE property (after --collapse-ignore are removed) // 2. The ONE property is mandatory (must be provided) List<ClassContent> content = (cc as Property).Type.Class.GetFullContent(); content.RemoveAll(a => CorCollapserPipelineTrigger.collapseIgnore.Contains(a.Name)); // Remove the ignore if (CorCollapserPipelineTrigger.collapseIgnoreFixed) content.RemoveAll(o => o is Property && !String.IsNullOrEmpty((o as Property).FixedValue) && (o as Property).PropertyType == Property.PropertyTypes.Structural); if(content.Count != 1) throw new InvalidOperationException("Can't collapse type with more than one meaningful content"); // can't collapse this relation as there is more than sub-property ClassContent candidate = content[0]; cc.Annotations.Add(new CodeCollapseAnnotation() { Name = cc.Name, Order = 0, Property = cc as Property }); // Has this collapsed member had any collapsing if (candidate.Annotations.Count > 0) { // Get all code collapse annotations from the candidate List<Annotation> collapseAnnotations = candidate.Annotations.FindAll(o => o is CodeCollapseAnnotation); // Find one that links it to the candidate //collapseAnnotations.RemoveAll(o => candidate.Annotations.Count(ca => (ca as CodeCollapseAnnotation).Property == (o as CodeCollapseAnnotation).Property) != 1); CodeCollapseAnnotation oldCca = null; foreach (CodeCollapseAnnotation cca in collapseAnnotations) { cca.Order = cc.Annotations.Count; if (cc.Annotations.Count(ca =>ca is CodeCollapseAnnotation && (ca as CodeCollapseAnnotation).Property == cca.Property) == 0) cc.Annotations.Add(cca); oldCca = cca; } } else cc.Annotations.Add(new CodeCollapseAnnotation() { Name = candidate.Name, Order = 1, Property = candidate as Property }); // Determine a better name if (CorCollapserPipelineTrigger.collapseSpecialNaming) { // We collapse the collapsee's name into the parent by default. string preferredName = candidate.Name; // If the container for the property already has an element by the name we prefer, we must // or the collapsee's name is in the useless words list we must keep the current name, or if the // parent's name is in the structurally important collection if((cc.Container as Class).GetFullContent().Find(o=>o.Name == preferredName) != null || CorCollapserPipelineTrigger.uselessWords.Contains(preferredName) || CorCollapserPipelineTrigger.importantWords.Contains(cc.Name)) preferredName = cc.Name; cc.Name = preferredName; } // Now determine if we can collapse (cc as Property).Type = (candidate as Property).Type.Clone() as TypeReference; (cc as Property).SupplierDomain = (candidate as Property).SupplierDomain; (cc as Property).SupplierStrength = (candidate as Property).SupplierStrength; (cc as Property).Type.Container = cc; (cc as Property).Type.MemberOf = cc.MemberOf; // Update documentation if((cc as Property).Documentation == null && candidate.Documentation != null) (cc as Property).Documentation = candidate.Documentation; }