/// <summary> /// Creates the code type declaration for the given input model element /// </summary> /// <param name="input">The input model element</param> /// <param name="context">The transformation context</param> /// <returns>The code type declaration that will be the transformation result for the given enumeration</returns> public override CodeTypeDeclaration CreateOutput(T input, Transformations.Core.ITransformationContext context) { var declaration = CodeDomHelper.CreateTypeDeclarationWithReference(GetName(input), true); declaration.IsEnum = true; return(declaration); }
/// <summary> /// Creates the code type declaration for the given input model element /// </summary> /// <param name="input">The input model element</param> /// <param name="context">The transformation context</param> /// <returns>The code type declaration that will be the transformation result for the given enumeration</returns> public override CodeTypeDeclaration CreateOutput(T input, Transformations.Core.ITransformationContext context) { var declaration = new CodeTypeDeclaration() { Name = GetName(input), IsEnum = true }; var reference = new CodeTypeReference(declaration.Name); CodeDomHelper.SetUserItem(declaration, CodeDomHelper.TypeReferenceKey, reference); CodeDomHelper.SetUserItem(reference, CodeDomHelper.ClassKey, declaration); return(declaration); }
/// <summary> /// Transform the input model element to an enumeration /// </summary> /// <param name="input">The input model element that is transformed to an enumeration</param> /// <param name="output">The output code type declaration that represents an enumeration</param> /// <param name="context">The transformation context</param> public override void Transform(T input, CodeTypeDeclaration output, Transformations.Core.ITransformationContext context) { var flagged = GetIsFlagged(input); if (flagged) { output.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(FlagsAttribute).Name)); } int nextValue = flagged ? 1 : 0; foreach (var item in GetMembers(input)) { if (item.Value.HasValue) { nextValue = item.Value.Value; } var literal = new CodeMemberField() { Name = item.Name, InitExpression = new CodePrimitiveExpression(nextValue) }; if (item.Summary != null || item.Remarks != null) { string comment = string.Empty; if (!string.IsNullOrEmpty(item.Summary)) { comment += "<summary>\r\n" + item.Summary + "\r\n</summary>"; } if (!string.IsNullOrEmpty(item.Remarks)) { comment += "\r\n<remarks>" + item.Remarks + "</remarks>"; } literal.Comments.Add(new CodeCommentStatement(comment, true)); } if (flagged) { nextValue <<= 1; } else { nextValue++; } output.Members.Add(literal); } }
public override void Transform(IClass scope, IReference reference, CodeMemberProperty property, Transformations.Core.ITransformationContext context) { var baseTypes = Layering <IClass> .CreateLayers(scope, c => c.BaseTypes).Select(c => c.Single()).ToList(); if (!baseTypes.Contains((IClass)reference.DeclaringType)) { throw new InvalidOperationException(string.Format("The reference {0} cannot be refined in the scope of class {1} because {1} does not inherit from its declaring class.", reference.Name, scope.Name)); } var classDeclaration = context.Trace.ResolveIn(Rule <Type2Type>(), scope); var originalReference = context.Trace.ResolveIn(Rule <Reference2Property>(), reference); property.Attributes = MemberAttributes.Private; property.Name = originalReference.Name; property.PrivateImplementationType = CreateReference(reference.DeclaringType, false, context); property.Type = originalReference.Type; lock (classDeclaration) { classDeclaration.Shadows(true).Add(originalReference); classDeclaration.DependentMembers(true).Add(property); } var implementations = baseTypes.SelectMany(s => s.References).Where(r => r.Refines == reference).ToList(); var constraints = baseTypes.SelectMany(s => s.ReferenceConstraints).Where(rc => rc.Constrains == reference); foreach (var declClass in implementations.Select(a => a.DeclaringType).OfType <IClass>().Concat(constraints.Select(c => c.DeclaringType)).Distinct()) { if (declClass != scope) { var refinedReference = context.Trace.ResolveIn(this, declClass, reference); if (refinedReference != null) { property.Shadows(true).Add(refinedReference); } } } if (implementations.Count == 0 && !constraints.Any()) { throw new InvalidOperationException( string.Format("The reference {0} can not be refined in the scope of class {1} because no reference refines it. ", reference, scope) ); } var referenceType = CreateReference(reference.Type, true, context); if (reference.UpperBound == 1) { var nullRef = new CodePrimitiveExpression(null); if (!constraints.Any()) { var castedThisVariable = new CodeVariableDeclarationStatement(classDeclaration.GetReferenceForType(), "_this", new CodeThisReferenceExpression()); var castedThisVariableRef = new CodeVariableReferenceExpression("_this"); property.GetStatements.Add(castedThisVariable); property.SetStatements.Add(castedThisVariable); var setRef = new CodePropertySetValueReferenceExpression(); var ifNull = new CodeConditionStatement(); ifNull.Condition = new CodeBinaryOperatorExpression(setRef, CodeBinaryOperatorType.IdentityInequality, nullRef); var foundMatch = false; foreach (var implementation in implementations) { var implementationRef = new CodePropertyReferenceExpression(castedThisVariableRef, context.Trace.ResolveIn(Rule <Reference2Property>(), implementation).Name); if (implementation.Type == reference.Type) { property.GetStatements.Add(new CodeMethodReturnStatement(implementationRef)); property.SetStatements.Add(new CodeAssignStatement(implementationRef, setRef)); foundMatch = true; break; } else { var getIfStmt = new CodeConditionStatement(); getIfStmt.Condition = new CodeBinaryOperatorExpression(implementationRef, CodeBinaryOperatorType.IdentityInequality, nullRef); getIfStmt.TrueStatements.Add(new CodeMethodReturnStatement(implementationRef)); property.GetStatements.Add(getIfStmt); var implementationType = CreateReference(implementation.Type, true, context); var asRef = new CodeMethodReferenceExpression(setRef, "As", implementationType); var localVar = new CodeVariableDeclarationStatement(implementationType, "__" + implementation.Name, new CodeMethodInvokeExpression(asRef)); var localVarRef = new CodeVariableReferenceExpression(localVar.Name); var setIfStmt = new CodeConditionStatement(); setIfStmt.Condition = new CodeBinaryOperatorExpression(localVarRef, CodeBinaryOperatorType.IdentityInequality, nullRef); setIfStmt.TrueStatements.Add(new CodeAssignStatement(implementationRef, localVarRef)); setIfStmt.TrueStatements.Add(new CodeMethodReturnStatement()); ifNull.TrueStatements.Add(localVar); ifNull.TrueStatements.Add(setIfStmt); ifNull.FalseStatements.Add(new CodeAssignStatement(implementationRef, nullRef)); } } ifNull.FalseStatements.Add(new CodeMethodReturnStatement()); if (ifNull.TrueStatements.Count > 0) { property.SetStatements.Add(ifNull); } if (!foundMatch) { property.GetStatements.Add(new CodeMethodReturnStatement(nullRef)); property.SetStatements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.ArgumentException), new CodePrimitiveExpression("There was no suitable refining reference found for this object")))); } } else { var constraint = constraints.Last(); var ifNotDefault = new CodeConditionStatement(); ifNotDefault.TrueStatements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.NotSupportedException)))); CodeExpression value; if (constraint.References.Count == 0) { value = nullRef; } else { var refEl = constraint.References[0]; var uri = refEl.AbsoluteUri; if (uri == null) { throw new System.InvalidOperationException(); } var metaRepositoryInstance = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(MetaRepository)), "Instance"); var refElExpression = new CodeMethodInvokeExpression(metaRepositoryInstance, "Resolve", new CodePrimitiveExpression(uri.AbsoluteUri)); refElExpression = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(refElExpression, "As", property.Type)); var retrieveValueMethod = new CodeMemberMethod { Name = "Retrieve" + reference.Name.ToPascalCase(), Attributes = MemberAttributes.Private | MemberAttributes.Static, ReturnType = property.Type }; retrieveValueMethod.Statements.Add(new CodeMethodReturnStatement(refElExpression)); property.DependentMembers(true).Add(retrieveValueMethod); var staticField = new CodeMemberField(new CodeTypeReference("Lazy", property.Type), "_" + reference.Name.ToPascalCase()); staticField.Attributes = MemberAttributes.Private | MemberAttributes.Static; staticField.InitExpression = new CodeObjectCreateExpression(staticField.Type, new CodeMethodReferenceExpression(null, retrieveValueMethod.Name)); property.DependentMembers(true).Add(staticField); value = new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(null, staticField.Name), "Value"); } property.GetStatements.Add(new CodeMethodReturnStatement(value)); ifNotDefault.Condition = new CodeBinaryOperatorExpression(new CodePropertySetValueReferenceExpression(), CodeBinaryOperatorType.IdentityInequality, value); property.SetStatements.Add(ifNotDefault); } CreateChangeEvent(property, implementations, context, "Changed"); CreateChangeEvent(property, implementations, context, "Changing"); } else { if (reference.IsUnique) { throw new System.InvalidOperationException("Unique references must not be refined!"); } if (implementations.Count > 0 || constraints.Any(c => c.References.Any())) { var collectionType = context.Trace.ResolveIn(Rule <RefinedReferenceCollectionClassGenerator>(), scope, reference); property.GetStatements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(collectionType.GetReferenceForType(), new CodeThisReferenceExpression()))); property.DependentTypes(true).Add(collectionType); } else { property.GetStatements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(new CodeTypeReference(typeof(EmptyList <>).Name, referenceType)), "Instance"))); } } }
public override CodeTypeDeclaration CreateOutput(IPrimitiveType input, Transformations.Core.ITransformationContext context) { return(null); }