private void AssignReturnValueDeclaration() { string boxingSnippet; if (this.returnsValue) { var returnValueDefaultValueExpression = new CodeDefaultValueExpression( new CodeTypeReference(this.contractMethod.ReturnType)); var returnValueVariableDeclaration = new CodeVariableDeclarationStatement( this.contractMethod.ReturnType, VariableNames.ReturnValue, returnValueDefaultValueExpression); this.methodDeclaration.Statements.Add(returnValueVariableDeclaration); boxingSnippet = string.Format( "object {0} = {1};", VariableNames.BoxedReturnValue, VariableNames.ReturnValue); } else { boxingSnippet = string.Format("object {0} = null;", VariableNames.BoxedReturnValue); } var boxingStatement = new CodeSnippetStatement(boxingSnippet); this.methodDeclaration.Statements.Add(boxingStatement); }
public void Constructor0_Deny_Unrestricted() { CodeDefaultValueExpression cdve = new CodeDefaultValueExpression(); Assert.AreEqual("System.Void", cdve.Type.BaseType, "Type"); cdve.Type = new CodeTypeReference(); }
private void AssignParameters() { var parameterDeclarations = this.GetParameterDeclarations(); foreach (var parameterDeclaration in parameterDeclarations) { this.methodDeclaration.Parameters.Add(parameterDeclaration); if (parameterDeclaration.Direction == FieldDirection.Out) { var parameterExpression = new CodeVariableReferenceExpression(parameterDeclaration.Name); var defaultValueExpression = new CodeDefaultValueExpression(parameterDeclaration.Type); var defaultValueStatement = new CodeAssignStatement(parameterExpression, defaultValueExpression); this.methodDeclaration.Statements.Add(defaultValueStatement); } var prefix = parameterDeclaration.Direction == FieldDirection.Out ? "out " : (parameterDeclaration.Direction == FieldDirection.Ref ? "ref " : ""); var parameterPassExpression = new CodeVariableReferenceExpression(prefix + parameterDeclaration.Name); this.methodInvocation.Parameters.Add(parameterPassExpression); } }
/// <inheritdoc/> protected override bool HandleDynamic(CodeDefaultValueExpression obj, Context ctx) { ctx.Writer.Write("default("); ctx.HandlerProvider.TypeReferenceHandler.Handle(obj.Type, ctx); ctx.Writer.Write(")"); return(true); }
public void Constructor1_Deny_Unrestricted() { CodeTypeReference ctr = new CodeTypeReference(); CodeDefaultValueExpression cdve = new CodeDefaultValueExpression(ctr); Assert.AreSame(ctr, cdve.Type, "Type"); cdve.Type = new CodeTypeReference(); }
private static void CopyAttrs(IList <CustomAttributeData> list, CodeAttributeDeclarationCollection newAttrs) { foreach (CustomAttributeData attrData in list) { CodeAttributeDeclaration attrDec = new CodeAttributeDeclaration(new CodeTypeReference(attrData.Constructor.DeclaringType)); foreach (CustomAttributeTypedArgument arg in attrData.ConstructorArguments) { CodeExpression expr = null; if (arg.ArgumentType.IsEnum) { expr = new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(arg.ArgumentType.FullName), Enum.ToObject(arg.ArgumentType, arg.Value).ToString()); } else if (arg.ArgumentType == typeof(string) || arg.ArgumentType == typeof(int) || arg.ArgumentType == typeof(short)) { expr = new CodePrimitiveExpression(arg.Value); } else { expr = new CodeDefaultValueExpression(new CodeTypeReference(arg.ArgumentType)); } if (expr != null) { attrDec.Arguments.Add(new CodeAttributeArgument(expr)); } } foreach (CustomAttributeNamedArgument arg in attrData.NamedArguments) { CodeExpression expr = null; if (arg.MemberInfo is FieldInfo && Equals(arg.TypedValue.Value, 0) || Equals(arg.TypedValue.Value, (short)0)) { continue; } if (arg.TypedValue.ArgumentType.IsEnum) { expr = new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(arg.TypedValue.ArgumentType.FullName), Enum.ToObject(arg.TypedValue.ArgumentType, arg.TypedValue.Value).ToString()); } else if (arg.TypedValue.ArgumentType == typeof(string) || arg.TypedValue.ArgumentType == typeof(int) || arg.TypedValue.ArgumentType == typeof(short)) { expr = new CodePrimitiveExpression(arg.TypedValue.Value); } else { expr = new CodeDefaultValueExpression(new CodeTypeReference(arg.TypedValue.ArgumentType)); } if (expr != null) { attrDec.Arguments.Add(new CodeAttributeArgument(arg.MemberInfo.Name, expr)); } } //attr. newAttrs.Add(attrDec); } }
public TypescriptDefaultValueExpression( CodeDefaultValueExpression codeExpression, CodeGeneratorOptions options, ITypescriptTypeMapper typescriptTypeMapper) { _codeExpression = codeExpression; _options = options; _typescriptTypeMapper = typescriptTypeMapper; System.Diagnostics.Debug.WriteLine("TypescriptDefaultValueExpression Created"); }
public void Constructor1() { CodeTypeReference type = new CodeTypeReference("mono"); CodeDefaultValueExpression cdve = new CodeDefaultValueExpression(type); Assert.IsNotNull(cdve.Type, "#1"); Assert.AreSame(type, cdve.Type, "#2"); cdve = new CodeDefaultValueExpression((CodeTypeReference)null); Assert.IsNotNull(cdve.Type, "#3"); Assert.AreEqual(typeof(void).FullName, cdve.Type.BaseType, "#4"); }
private void AssignGetBlockWithAspectCode() { if (!this.propertyDeclaration.HasGet) { return; } var entryStatements = this.aspectGenerator.Entry.GenerateForPropertyGet().ToArray(); var exitStatements = this.aspectGenerator.Exit.GenerateForPropertyGet().ToArray(); var errorStatements = this.aspectGenerator.Error.GenerateForPropertyGet().ToArray(); var catchClause = Constructs.CatchClause; catchClause.Statements.AddRange(errorStatements); var tryCatchFinallyBlock = new CodeTryCatchFinallyStatement( this.getStatements, catchClause.AsArray(), exitStatements); var returnValueDefaultValueExpression = new CodeDefaultValueExpression( new CodeTypeReference(this.contractProperty.PropertyType)); var returnValueDeclarationStatement = new CodeVariableDeclarationStatement( this.contractProperty.PropertyType, VariableNames.ReturnValue, returnValueDefaultValueExpression); var boxingSnippet = string.Format( "object {0} = {1};", VariableNames.BoxedReturnValue, VariableNames.ReturnValue); var boxingStatement = new CodeSnippetStatement(boxingSnippet); var returnValueExpression = new CodeCastExpression( this.contractProperty.PropertyType, Constructs.BoxedReturnValueExpression); var returnValueStatement = new CodeMethodReturnStatement(returnValueExpression); this.propertyDeclaration.GetStatements.Add(returnValueDeclarationStatement); this.propertyDeclaration.GetStatements.Add(boxingStatement); this.propertyDeclaration.GetStatements.AddRange(entryStatements); this.propertyDeclaration.GetStatements.Add(tryCatchFinallyBlock); this.propertyDeclaration.GetStatements.Add(returnValueStatement); }
private CodeStatementCollection GenerateImperativeStatement(IdentifierExpression node) { var parserId = ParserIdentifier.FromIdentifierExpression(node); if (parserId.Name != "Error") { var typeRef = CodeHelper.TypeRef(parserId.Type ?? _config.BaseClass); typeRef = parserId.IsList ? ParserCode.GetListTypeRef(typeRef) : typeRef; var init = new CodeDefaultValueExpression(typeRef); var varDecl = new CodeVariableDeclarationStatement(typeRef, node.Identifier, init); _scope.Add(node.Identifier, AphidObject.Complex()); return(new CodeStatementCollection(new[] { varDecl })); } return(new CodeStatementCollection(new[] { new CodeThrowExceptionStatement( new CodeObjectCreateExpression( _config.ExceptionClass, CodeHelper.VarRef("CurrentToken"))) })); }
protected override void Visit(CodeDefaultValueExpression expr) { Enumerate(expr.Type); base.Visit(expr); }
/// <summary> /// Generates a class that clears the non-scalar properties on an entity. /// </summary> /// <param name="entity">The entity</param> /// <returns>The generated class</returns> private static IEntityPropertyClearer GeneratePropertyClearer(EntityObject entity) { Type entityType = entity.GetType(); //Set up the compile unit CodeCompileUnit compileUnit = new CodeCompileUnit(); compileUnit.ReferencedAssemblies.Add(typeof(System.ComponentModel.INotifyPropertyChanging).Assembly.Location); //System.dll compileUnit.ReferencedAssemblies.Add(typeof(EfUtil).Assembly.Location); compileUnit.ReferencedAssemblies.Add(typeof(EntityObject).Assembly.Location); compileUnit.ReferencedAssemblies.Add(entityType.Assembly.Location); //Create the namespace string namespaceName = typeof(EfUtil).Namespace + ".CodeGen"; CodeNamespace codeGenNamespace = new CodeNamespace(namespaceName); compileUnit.Namespaces.Add(codeGenNamespace); //Create the class string genTypeName = entityType.FullName.Replace('.', '_') + "PropertyClearer"; CodeTypeDeclaration genClass = new CodeTypeDeclaration(genTypeName); genClass.IsClass = true; codeGenNamespace.Types.Add(genClass); Type baseType = typeof(AbstractEntityPropertyClearer <>).MakeGenericType(entityType); genClass.BaseTypes.Add(new CodeTypeReference(baseType)); //Create the method CodeMemberMethod clearEntityMethod = new CodeMemberMethod(); genClass.Members.Add(clearEntityMethod); clearEntityMethod.Name = "ClearEntity"; clearEntityMethod.ReturnType = new CodeTypeReference(typeof(void)); clearEntityMethod.Parameters.Add(new CodeParameterDeclarationExpression(entityType, "entity")); clearEntityMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "clearEntityKeyProperties")); clearEntityMethod.Attributes = MemberAttributes.Override | MemberAttributes.Family; //Find all EntityCollection<> properties IEnumerable <PropertyInfo> entityCollections = from property in entityType.GetProperties() where property.PropertyType.IsGenericType && property.PropertyType.IsGenericTypeDefinition == false && property.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection <>) select property; //Emit Clear() calls on the EntityCollection<>s foreach (PropertyInfo propertyInfo in entityCollections) { CodePropertyReferenceExpression propertyReferenceExpression = new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("entity"), propertyInfo.Name); clearEntityMethod.Statements.Add(new CodeMethodInvokeExpression(propertyReferenceExpression, "Clear")); } //Find all single multiplicity relation ends IEnumerable <PropertyInfo> relationSingleEndProperties = from property in entityType.GetProperties() from attribute in property.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), true).Cast <EdmRelationshipNavigationPropertyAttribute>() select property; //Emit assignments that set the properties to their default value foreach (PropertyInfo propertyInfo in relationSingleEndProperties) { CodeExpression defaultExpression = new CodeDefaultValueExpression(new CodeTypeReference(propertyInfo.PropertyType)); CodePropertyReferenceExpression propertyReferenceExpression = new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("entity"), propertyInfo.Name); clearEntityMethod.Statements.Add(new CodeAssignStatement(propertyReferenceExpression, defaultExpression)); } //Find all entity key properties IEnumerable <PropertyInfo> idProperties = from property in entityType.GetProperties() from attribute in property.GetCustomAttributes(typeof(EdmScalarPropertyAttribute), true).Cast <EdmScalarPropertyAttribute>() where attribute.EntityKeyProperty select property; //Emit the if check for wiping ID properties CodeConditionStatement ifCondition = new CodeConditionStatement(new CodeArgumentReferenceExpression("clearEntityKeyProperties")); clearEntityMethod.Statements.Add(ifCondition); //Emit assignments that set the properties to their default value foreach (PropertyInfo propertyInfo in idProperties) { CodeExpression defaultExpression = new CodeDefaultValueExpression(new CodeTypeReference(propertyInfo.PropertyType)); CodePropertyReferenceExpression propertyReferenceExpression = new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("entity"), propertyInfo.Name); ifCondition.TrueStatements.Add(new CodeAssignStatement(propertyReferenceExpression, defaultExpression)); } //Compile the code and load the assembly CSharpCodeProvider provider = new CSharpCodeProvider(); CompilerParameters parameters = new CompilerParameters(); parameters.GenerateInMemory = true; #if DEBUG parameters.IncludeDebugInformation = true; #endif CompilerResults results = provider.CompileAssemblyFromDom(parameters, compileUnit); //Check for compile errors if (results.Errors.Count != 0) { StringBuilder error = new StringBuilder("Failed to generate the property clearer class. Compiler output:\r\n"); foreach (string str in results.Output) { error.Append(str); error.Append("\r\n"); } throw new Exception(error.ToString()); } //Instantiate the type and return it Type type = results.CompiledAssembly.GetType(namespaceName + "." + genTypeName); return((IEntityPropertyClearer)Activator.CreateInstance(type)); }
private void GenerateDefaultValueExpression(CodeDefaultValueExpression expression) { var strType = GetTypeOutput(expression.Type).ToLower(); if ((strType == "int") || (strType == "uint") || ((strType == "number"))) { Output.Write("0"); } else if (strType == "string") { Output.Write("''"); } else if (strType == "bool") { Output.Write("false"); } else if (strType == "boolean") { Output.Write("false"); } else { Output.Write(NullToken); } }
private static void ValidateDefaultValueExpression(CodeDefaultValueExpression e) { ValidateTypeReference(e.Type); }
protected virtual void GenerateDefaultValueExpression(CodeDefaultValueExpression e) { }
/// <inheritdoc cref="ICodeObjectHandler{T}.Handle"/> protected abstract bool HandleDynamic(CodeDefaultValueExpression obj, Context ctx);
protected virtual void GenerateDefaultValueExpression(CodeDefaultValueExpression e) { throw new NotImplementedException(); }
public void Visit(CodeDefaultValueExpression o) { g.GenerateDefaultValueExpression(o); }
protected virtual void Visit(CodeDefaultValueExpression expr) { }
/// <summary> /// Initializes the generated code property for the refined attribute /// </summary> /// <param name="scope">The scope in which the attribute is refined</param> /// <param name="attribute">The NMeta attribute that is refined</param> /// <param name="property">The generated code property</param> /// <param name="context">The transformation context</param> public override void Transform(IClass scope, IAttribute attribute, CodeMemberProperty property, ITransformationContext context) { if (!scope.Closure(c => c.BaseTypes).Contains((IClass)attribute.DeclaringType)) { throw new System.InvalidOperationException(string.Format("The attribute {0} cannot be refined in the scope of class {1} because {1} does not inherit from its declaring class.", attribute.Name, scope.Name)); } var classDeclaration = context.Trace.ResolveIn(Rule <Type2Type>(), scope); var originalAttribute = context.Trace.ResolveIn(Rule <Attribute2Property>(), attribute); property.Attributes = MemberAttributes.Private; property.Name = attribute.Name.ToPascalCase(); property.PrivateImplementationType = CreateReference(attribute.DeclaringType, false, context); lock (classDeclaration) { classDeclaration.Shadows(true).Add(originalAttribute); classDeclaration.DependentMembers(true).Add(property); } var implementations = scope.Attributes.Where(att => att.Refines == attribute).ToList(); var constraint = scope.AttributeConstraints.Where(c => c.Constrains == attribute).FirstOrDefault(); if (implementations.Count == 0 && constraint == null) { throw new System.InvalidOperationException("The RefinedAttributeGenerator rule was called irregularily as the attribute in question was not refined!"); } var attributeType = CreateReference(attribute.Type, false, context); if (attribute.UpperBound == 1) { property.Type = attributeType; if (implementations.Count > 1) { throw new System.InvalidOperationException("A single value typed attribute may only be refined once!"); } else if (implementations.Count == 1) { if (constraint != null) { throw new System.InvalidOperationException("A single values attribute must not be constrained and implemented at the same time!"); } if (implementations[0].Type != attribute.Type) { throw new System.InvalidOperationException("The refining attribute has a different type than the original attribute. Covariance is not supported for attributes!"); } var castedThisVariable = new CodeVariableDeclarationStatement(classDeclaration.GetReferenceForType(), "_this", new CodeThisReferenceExpression()); var castedThisVariableRef = new CodeVariableReferenceExpression("_this"); property.GetStatements.Add(castedThisVariable); property.SetStatements.Add(castedThisVariable); CodeExpression implementationRef = new CodePropertyReferenceExpression(castedThisVariableRef, implementations[0].Name.ToPascalCase()); property.GetStatements.Add(new CodeMethodReturnStatement(implementationRef)); property.SetStatements.Add(new CodeAssignStatement(implementationRef, new CodePropertySetValueReferenceExpression())); } else { var ifNotDefault = new CodeConditionStatement(); ifNotDefault.TrueStatements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.NotSupportedException)))); CodeExpression value; if (constraint.Values.Count == 0) { value = new CodeDefaultValueExpression(attributeType); } else { value = CodeDomHelper.CreatePrimitiveExpression(constraint.Values[0], attributeType); } property.GetStatements.Add(new CodeMethodReturnStatement(value)); ifNotDefault.Condition = new CodeBinaryOperatorExpression(new CodePropertySetValueReferenceExpression(), CodeBinaryOperatorType.IdentityInequality, value); property.SetStatements.Add(ifNotDefault); } CreateChangeEvent(property, implementations, context, "EventHandler<ValueChangedEventArgs>", "Changed"); CreateChangeEvent(property, implementations, context, "EventHandler", "Changing"); } else { if (attribute.IsUnique) { throw new System.InvalidOperationException("Unique attributes must not be refined."); } if (implementations.Count > 0 || (constraint != null && constraint.Values.Count > 0)) { var collectionType = context.Trace.ResolveIn(Rule <RefinedAttributeCollectionClassGenerator>(), scope, attribute); 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, attributeType)), "Instance"))); } } }
public override IEnumerable <CodeStatement> GetStubStatements() { /* * Required output: * 1. Create a target expression * 2. Call its method with the correct number of args * 3. Call its optimized method with the correct number of args * 4. Call its optimized method with an args array */ var targetType = new CodeTypeReference(manipulator.targetType, CodeTypeReferenceOptions.GlobalReference); var declaringType = new CodeTypeReference(stub.DeclaringType, CodeTypeReferenceOptions.GlobalReference); CodeExpression targetValue; CodeExpression targetReference; if (manipulator.requiresTarget && !manipulator.isExtension) { // default(Material) targetValue = new CodeDefaultValueExpression(targetType); // 1. Material target = default(Material); yield return(new CodeVariableDeclarationStatement(targetType, "target", targetValue)); targetReference = new CodeVariableReferenceExpression("target"); } else { // null targetValue = new CodePrimitiveExpression(null); if (manipulator.isExtension) { // 1. ShortcutExtensions targetReference = new CodeTypeReferenceExpression(declaringType); } else { // 1. Material targetReference = new CodeTypeReferenceExpression(targetType); } } // target.SetColor var methodReference = new CodeMethodReferenceExpression(targetReference, manipulator.name); var arguments = new List <CodeExpression>(); var includesOutOrRef = false; foreach (var parameterInfo in stub.GetParameters()) { var parameterType = new CodeTypeReference(parameterInfo.UnderlyingParameterType(), CodeTypeReferenceOptions.GlobalReference); var argumentName = $"arg{arguments.Count}"; // arg0 = default(string) // arg1 = default(Color) yield return(new CodeVariableDeclarationStatement(parameterType, argumentName, new CodeDefaultValueExpression(parameterType))); FieldDirection direction; if (parameterInfo.HasOutModifier()) { direction = FieldDirection.Out; includesOutOrRef = true; } else if (parameterInfo.ParameterType.IsByRef) { direction = FieldDirection.Ref; includesOutOrRef = true; } else { direction = FieldDirection.In; } var argument = new CodeDirectionExpression(direction, new CodeVariableReferenceExpression(argumentName)); arguments.Add(argument); } if (operatorTypes.ContainsKey(manipulator.name)) { // arg0 * arg1 var operation = new CodeBinaryOperatorExpression(arguments[0], operatorTypes[manipulator.name], arguments[1]); // 2. var operator = arg0 * arg1; yield return(new CodeVariableDeclarationStatement(manipulator.type, "operator", operation)); } else if (manipulator.isConversion) { // (Vector3)arg0 var cast = new CodeCastExpression(manipulator.type, arguments[0]); // 2. var conversion = (Vector3)arg0; yield return(new CodeVariableDeclarationStatement(manipulator.type, "conversion", cast)); } else if (manipulator.isPubliclyInvocable && !(manipulator.isOperator || manipulator.isConversion)) { // 2. target.SetColor(arg0, arg1); yield return(new CodeExpressionStatement(new CodeMethodInvokeExpression(methodReference, arguments.ToArray()))); } var optimizedInvokerType = new CodeTypeReference(stub.Prewarm().GetType(), CodeTypeReferenceOptions.GlobalReference); // var invoker = new InstanceActionInvoker<Material, string, Color>(default(MethodInfo)); yield return(new CodeVariableDeclarationStatement(optimizedInvokerType, "optimized", new CodeObjectCreateExpression(optimizedInvokerType, new CodeDefaultValueExpression(new CodeTypeReference(typeof(MethodInfo), CodeTypeReferenceOptions.GlobalReference))))); // [default(Material), arg0, arg1] var argumentsWithTarget = targetValue.Yield().Concat(arguments).ToArray(); // Ref and out parameters are not supported in the numbered argument signatures if (!includesOutOrRef) { // 3. invoker.Invoke(default(Material), arg0, arg1); yield return(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("optimized"), nameof(IOptimizedInvoker.Invoke), argumentsWithTarget))); } // 4. invoker.Invoke(default(Material), default(object[])); yield return(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("optimized"), nameof(IOptimizedInvoker.Invoke), new CodeDefaultValueExpression(new CodeTypeReference(typeof(object[])))))); }
/// <summary> /// Initializes the generated code property for the refined attribute /// </summary> /// <param name="scope">The scope in which the attribute is refined</param> /// <param name="attribute">The NMeta attribute that is refined</param> /// <param name="property">The generated code property</param> /// <param name="context">The transformation context</param> public override void Transform(IClass scope, IAttribute attribute, CodeMemberProperty property, ITransformationContext context) { var baseTypes = Layering <IClass> .CreateLayers(scope, c => c.BaseTypes).Select(c => c.Single()).ToList(); if (!baseTypes.Contains((IClass)attribute.DeclaringType)) { throw new InvalidOperationException(string.Format("The attribute {0} cannot be refined in the scope of class {1} because {1} does not inherit from its declaring class.", attribute.Name, scope.Name)); } var classDeclaration = context.Trace.ResolveIn(Rule <Type2Type>(), scope); var originalAttribute = context.Trace.ResolveIn(Rule <Attribute2Property>(), attribute); property.Attributes = MemberAttributes.Private; property.Name = originalAttribute.Name; property.PrivateImplementationType = CreateReference(attribute.DeclaringType, false, context); lock (classDeclaration) { classDeclaration.Shadows(true).Add(originalAttribute); classDeclaration.DependentMembers(true).Add(property); } var implementations = baseTypes.SelectMany(s => s.Attributes).Where(att => att.Refines == attribute).ToList(); var constraints = baseTypes.SelectMany(s => s.AttributeConstraints).Where(rc => rc.Constrains == attribute); foreach (var declClass in implementations.Select(a => a.DeclaringType).OfType <IClass>().Concat(constraints.Select(c => c.DeclaringType)).Distinct()) { if (declClass != scope) { var refinedAttribute = context.Trace.ResolveIn(this, declClass, attribute); if (refinedAttribute != null) { property.Shadows(true).Add(refinedAttribute); } } } if (implementations.Count == 0 && !constraints.Any()) { throw new InvalidOperationException( string.Format("The attribute {0} can not be refined in the scope of class {1} because no reference refines it. ", attribute, scope) ); } var attributeType = CreateReference(attribute.Type, false, context); if (attribute.UpperBound == 1) { property.Type = attributeType; if (implementations.Count > 1) { throw new System.InvalidOperationException("A single value typed attribute may only be refined once!"); } else if (implementations.Count == 1) { if (constraints.Any()) { throw new System.InvalidOperationException("A single values attribute must not be constrained and implemented at the same time!"); } if (implementations[0].Type != attribute.Type) { throw new System.InvalidOperationException("The refining attribute has a different type than the original attribute. Covariance is not supported for attributes!"); } var castedThisVariable = new CodeVariableDeclarationStatement(classDeclaration.GetReferenceForType(), "_this", new CodeThisReferenceExpression()); var castedThisVariableRef = new CodeVariableReferenceExpression("_this"); property.GetStatements.Add(castedThisVariable); property.SetStatements.Add(castedThisVariable); var implProperty = context.Trace.ResolveIn(Rule <Attribute2Property>(), implementations[0]); CodeExpression implementationRef = new CodePropertyReferenceExpression(castedThisVariableRef, implProperty.Name); property.GetStatements.Add(new CodeMethodReturnStatement(implementationRef)); property.SetStatements.Add(new CodeAssignStatement(implementationRef, new CodePropertySetValueReferenceExpression())); } else { var constraint = constraints.Last(); var ifNotDefault = new CodeConditionStatement(); ifNotDefault.TrueStatements.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.NotSupportedException)))); CodeExpression value; if (constraints.Sum(c => c.Values.Count) == 0) { value = new CodeDefaultValueExpression(attributeType); } else { value = CodeDomHelper.CreatePrimitiveExpression(constraint.Values[0], attributeType, attribute.Type is IEnumeration); if (value == null) { throw new InvalidOperationException(string.Format("The value {0} could not be serialized as a value for {1}", constraint.Values[0], attribute)); } } 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 (attribute.IsUnique) { throw new System.InvalidOperationException("Unique attributes must not be refined."); } if (implementations.Count > 0 || constraints.Any(c => c.Values.Any())) { var collectionType = context.Trace.ResolveIn(Rule <RefinedAttributeCollectionClassGenerator>(), scope, attribute); 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, attributeType)), "Instance"))); } } }
protected abstract void GenerateDefaultValueExpression(CodeDefaultValueExpression e);
public override IEnumerable <CodeStatement> GetStubStatements() { /* * Required output: * 1. Create a target variable * 2. Call its getter to prevent stripping * 3. Call its setter to prevent stripping * 4. Create its optimized accessor to explicitly compile generic type * 5. Call its optimized getter to explicitly compile generic method * 6. Call its optimized setter to explicitly compile generic method */ var targetType = new CodeTypeReference(manipulator.targetType, CodeTypeReferenceOptions.GlobalReference); var accessorType = new CodeTypeReference(manipulator.type, CodeTypeReferenceOptions.GlobalReference); CodeExpression property; if (manipulator.requiresTarget) { // 1. Material target = default(Material); yield return(new CodeVariableDeclarationStatement(targetType, "target", new CodeDefaultValueExpression(targetType))); property = new CodeVariableReferenceExpression("target"); } else { property = new CodeTypeReferenceExpression(targetType); } // target.color var propertyReference = new CodePropertyReferenceExpression(property, manipulator.name); if (manipulator.isPubliclyGettable) { // 2. Color accessor = target.color; yield return(new CodeVariableDeclarationStatement(accessorType, "accessor", propertyReference)); } if (manipulator.isPubliclySettable) { // 3. target.color = default(Color); yield return(new CodeAssignStatement(propertyReference, new CodeDefaultValueExpression(accessorType))); } var optimizedAccessorType = new CodeTypeReference(GetOptimizedAccessor(stub).GetType(), CodeTypeReferenceOptions.GlobalReference); // 4. var accessor = new PropertyAccessor<Material, Color>(default(PropertyInfo)); yield return(new CodeVariableDeclarationStatement(optimizedAccessorType, "optimized", new CodeObjectCreateExpression(optimizedAccessorType, new CodeDefaultValueExpression(new CodeTypeReference(typeof(TAccessor), CodeTypeReferenceOptions.GlobalReference))))); CodeExpression target; if (manipulator.requiresTarget) { // default(Material) target = new CodeDefaultValueExpression(targetType); } else { // null for static types target = new CodePrimitiveExpression(null); } if (manipulator.isGettable) { // 5. accessor.GetValue(default(Material)); yield return(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("optimized"), nameof(IOptimizedAccessor.GetValue), target))); } if (manipulator.isSettable) { // 6. accessor.SetValue(default(Material), default(Color)); yield return(new CodeExpressionStatement(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("optimized"), nameof(IOptimizedAccessor.SetValue), target, new CodeDefaultValueExpression(accessorType)))); } }
/// <inheritdoc /> protected override bool HandleDynamic(CodeDefaultValueExpression obj, Context ctx) { ctx.HandlerProvider.ExpressionHandler.Handle( new CodeCastExpression(obj.Type, new CodePrimitiveExpression(null)), ctx); return(true); }