public virtual CodeTypeDeclaration CreateClass(SettingsDocument setDoc)
		{
			CodeTypeDeclaration c = new CodeTypeDeclaration(setDoc.GeneratedClassName);
			c.AddAttribute(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute));
			c.AddAttribute(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute),
			               Easy.Prim(typeof(SettingsCodeGeneratorTool).FullName),
			               Easy.Prim(typeof(SettingsCodeGeneratorTool).Assembly.GetName().Version.ToString()));
			c.TypeAttributes = TypeAttributes.NotPublic | TypeAttributes.Sealed;
			c.IsPartial = true;
			c.BaseTypes.Add(Easy.TypeRef(typeof(ApplicationSettingsBase)));
			
			CodeMemberField f = c.AddField(Easy.TypeRef(c), "defaultInstance");
			f.Attributes = MemberAttributes.Private | MemberAttributes.Static;
			f.InitExpression = Easy.Type(typeof(ApplicationSettingsBase))
				.InvokeMethod("Synchronized", Easy.New(Easy.TypeRef(c)))
				.CastTo(Easy.TypeRef(c));
			
			var defaultProperty = c.AddProperty(f, "Default");
			
			if (setDoc.UseMySettingsClassName) {
				c.AddAttribute(typeof(EditorBrowsableAttribute), Easy.Prim(EditorBrowsableState.Advanced));
				AddAutoSaveLogic(c, defaultProperty);
			}
			
			foreach (SettingsEntry entry in setDoc.Entries) {
				Type entryType = entry.Type ?? typeof(string);
				SpecialSetting? specialSetting = null;
				foreach (SpecialTypeDescriptor desc in SpecialTypeDescriptor.Descriptors) {
					if (desc.type == entryType) {
						entryType = typeof(string);
						specialSetting = desc.specialSetting;
						break;
					}
				}
				EasyProperty p = c.AddProperty(entryType, entry.Name);
				if (entry.Scope == SettingScope.User) {
					p.AddAttribute(typeof(UserScopedSettingAttribute));
				} else {
					p.AddAttribute(typeof(ApplicationScopedSettingAttribute));
				}
				if (!string.IsNullOrEmpty(entry.Provider)) {
					p.AddAttribute(typeof(SettingsProviderAttribute),
					               Easy.TypeOf(new CodeTypeReference(entry.Provider)));
				}
				if (!string.IsNullOrEmpty(entry.Description)) {
					p.AddAttribute(typeof(SettingsDescriptionAttribute), Easy.Prim(entry.Description));
					Easy.AddSummary(p, entry.Description);
				}
				p.AddAttribute(typeof(DebuggerNonUserCodeAttribute));
				if (specialSetting != null) {
					p.AddAttribute(typeof(SpecialSettingAttribute),
					               Easy.Prim(specialSetting.Value));
				}
				if (entry.GenerateDefaultValueInCode) {
					p.AddAttribute(typeof(DefaultSettingValueAttribute), Easy.Prim(entry.SerializedValue));
				}
				if (entry.Scope == SettingScope.User && entry.Roaming) {
					p.AddAttribute(typeof(SettingsManageabilityAttribute),
					               Easy.Prim(SettingsManageability.Roaming));
				}
				p.Getter.Return(Easy.This.Index(Easy.Prim(entry.Name)).CastTo(entryType));
//				p.GetStatements.Add(new CodeMethodReturnStatement(
//					new CodeCastExpression(new CodeTypeReference(entryType),
//					                       new CodeIndexerExpression(new CodeThisReferenceExpression(),
//					                                                 new CodePrimitiveExpression(entry.Name))
//					                      )
//				));
				if (entry.Scope == SettingScope.User) {
					p.Setter.Assign(Easy.This.Index(Easy.Prim(entry.Name)), Easy.Value);
				}
			}
			
			return c;
		}
Example #2
0
		static void ProcessType(Type type, CodeTypeDeclaration ctd)
		{
			foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic)) {
				ctd.AddField(ConvertType(field.FieldType), field.Name).Attributes = 0;
			}
			foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic)) {
				EasyProperty p = ctd.AddProperty(ConvertType(field.FieldType), GetPropertyName(field.Name));
				p.Getter.Return(Easy.Var(field.Name));
				CodeExpression ex;
				if (field.FieldType.IsValueType)
					ex = new CodePropertySetValueReferenceExpression();
				else
					ex = GetDefaultValue("value", field);
				p.Setter.Assign(Easy.Var(field.Name), ex);
				if (typeof(INode).IsAssignableFrom(field.FieldType)) {
					if (typeof(INullable).IsAssignableFrom(field.FieldType)) {
						p.SetStatements.Add(new CodeSnippetStatement("\t\t\t\tif (!" +field.Name+".IsNull) "+field.Name+".Parent = this;"));
					} else {
						p.SetStatements.Add(new CodeSnippetStatement("\t\t\t\t"+field.Name+".Parent = this;"));
					}
				}
			}
			foreach (ConstructorInfo ctor in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
				CodeConstructor c = new CodeConstructor();
				if (type.IsAbstract)
					c.Attributes = MemberAttributes.Family;
				else
					c.Attributes = MemberAttributes.Public;
				ctd.Members.Add(c);
				ConstructorInfo baseCtor = GetBaseCtor(type);
				foreach(ParameterInfo param in ctor.GetParameters()) {
					c.Parameters.Add(new CodeParameterDeclarationExpression(ConvertType(param.ParameterType),
					                                                        param.Name));
					if (baseCtor != null && Array.Exists(baseCtor.GetParameters(), delegate(ParameterInfo p) { return param.Name == p.Name; }))
						continue;
					c.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(GetPropertyName(param.Name)),
					                                         new CodeVariableReferenceExpression(param.Name)));
				}
				if (baseCtor != null) {
					foreach(ParameterInfo param in baseCtor.GetParameters()) {
						c.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(param.Name));
					}
				}
				// initialize fields that were not initialized by parameter
				foreach (FieldInfo field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic)) {
					if (field.FieldType.IsValueType && field.FieldType != typeof(Location))
						continue;
					if (Array.Exists(ctor.GetParameters(), delegate(ParameterInfo p) { return field.Name == p.Name; }))
						continue;
					c.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(field.Name),
					                                         GetDefaultValue(null, field)));
				}
			}
		}
        /// <summary>
        /// Adds a property to the given type which raises PropertyChange Notifications when the property is set.
        /// </summary>
        /// <param name="type">The type to add property to.</param>
        /// <param name="propertyType">Type of the property.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <returns>Added property.</returns>
        protected CodeMemberProperty AddPropertyWithChangeNotification(CodeTypeDeclaration type, CodeTypeReference propertyType, string propertyName)
        {
            // Declare a private property to be the backing field
            string backingFieldName = string.Format(CultureInfo.InvariantCulture, "backing{0}", propertyName);
            type.AddField(propertyType, backingFieldName);
            CodeMemberProperty propertyWithChangeNotifications = new CodeMemberProperty()
            {
                Name = propertyName,
                Type = propertyType,
                Attributes = MemberAttributes.Public
            };
            CodeThisReferenceExpression thisReference = new CodeThisReferenceExpression();

            // this will hold the reference to the backing field
            CodeFieldReferenceExpression backingFieldReference = new CodeFieldReferenceExpression(thisReference, backingFieldName);

            // add a getter which returns the backing field
            propertyWithChangeNotifications.GetStatements.Add(new CodeMethodReturnStatement(backingFieldReference));

            // add a statement which sets the value of the backing field
            CodeAssignStatement setStatement = new CodeAssignStatement(backingFieldReference, new CodeArgumentReferenceExpression("value"));

            // This will call the RaisePropertyChanged method passing in the propertyName
            CodeMethodInvokeExpression invokePropertyChangeNotifier = new CodeMethodInvokeExpression(thisReference, "RaisePropertyChanged", new CodeExpression[] { new CodePrimitiveExpression(propertyName) });

            propertyWithChangeNotifications.SetStatements.Add(setStatement);
            propertyWithChangeNotifications.SetStatements.Add(invokePropertyChangeNotifier);
            type.Members.Add(propertyWithChangeNotifications);
            return propertyWithChangeNotifications;
        }
Example #4
0
		static CodeTypeDeclaration CreateAstVisitorClass(List<Type> nodeTypes, bool transformer)
		{
			CodeTypeDeclaration td = new CodeTypeDeclaration(transformer ? "AbstractAstTransformer" : "AbstractAstVisitor");
			td.TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract;
			td.BaseTypes.Add(new CodeTypeReference("IAstVisitor"));
			
			if (transformer) {
				string comment =
					"The AbstractAstTransformer will iterate through the whole Ast,\n " +
					"just like the AbstractAstVisitor. However, the AbstractAstTransformer allows\n " +
					"you to modify the Ast at the same time: It does not use 'foreach' internally,\n " +
					"so you can add members to collections of parents of the current node (but\n " +
					"you cannot insert or delete items as that will make the index used invalid).\n " +
					"You can use the methods ReplaceCurrentNode and RemoveCurrentNode to replace\n " +
					"or remove the current node, totally independent from the type of the parent node.";
				Easy.AddSummary(td, comment);
				
				CodeMemberField field = td.AddField(Easy.TypeRef("Stack", "INode"), "nodeStack");
				field.InitExpression = Easy.New(field.Type);
				
				/*
				CodeExpression nodeStack = Easy.Var("nodeStack");
				CodeMemberProperty p = new CodeMemberProperty();
				p.Name = "CurrentNode";
				p.Type = new CodeTypeReference("INode");
				p.Attributes = MemberAttributes.Public | MemberAttributes.Final;
				p.GetStatements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("currentNode")));
				p.SetStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("currentNode"),
				                                            new CodePropertySetValueReferenceExpression()));
				td.Members.Add(p);
				 */
				
				EasyMethod m = td.AddMethod("ReplaceCurrentNode");
				m.AddParameter(Easy.TypeRef("INode"), "newNode");
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop"));
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Var("newNode")));
				
				m = td.AddMethod("RemoveCurrentNode");
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Pop"));
				m.Statements.Add(Easy.Var("nodeStack").InvokeMethod("Push", Easy.Null));
			}
			
			foreach (Type type in nodeTypes) {
				if (!type.IsAbstract) {
					EasyMethod m = td.AddMethod(typeof(object), VisitPrefix + type.Name);
					m.Attributes = MemberAttributes.Public;
					m.AddParameter(ConvertType(type), GetFieldName(type.Name));
					m.AddParameter(typeof(object), "data");
					
					List<CodeStatement> assertions = new List<CodeStatement>();
					string varVariableName = GetFieldName(type.Name);
					CodeExpression var = Easy.Var(varVariableName);
					assertions.Add(AssertIsNotNull(var));
					
					AddFieldVisitCode(m, type, var, assertions, transformer);
					
					if (type.GetCustomAttributes(typeof(HasChildrenAttribute), true).Length > 0) {
						if (transformer) {
							m.Statements.Add(new CodeSnippetStatement(CreateTransformerLoop(varVariableName + ".Children", "INode")));
							m.Body.Return(Easy.Null);
						} else {
							m.Body.Return(var.InvokeMethod("AcceptChildren", Easy.This, Easy.Var("data")));
						}
					} else {
						CodeExpressionStatement lastStatement = null;
						if (m.Statements.Count > 0) {
							lastStatement = m.Statements[m.Statements.Count - 1] as CodeExpressionStatement;
						}
						if (lastStatement != null) {
							m.Statements.RemoveAt(m.Statements.Count - 1);
							m.Body.Return(lastStatement.Expression);
						} else {
							m.Body.Return(Easy.Null);
						}
					}
					
					for (int i = 0; i < assertions.Count; i++) {
						m.Statements.Insert(i, assertions[i]);
					}
				}
			}
			return td;
		}