static void GenerateAction(CodeTypeDeclaration type, string name, CodeTypeReference senderType, CodeDomProvider provider, CodeGeneratorOptions generatorOptions, ref StringWriter actionStubWriter) { if (provider is Microsoft.CSharp.CSharpCodeProvider) { type.Members.Add(new CodeSnippetTypeMember("[MonoTouch.Foundation.Export(\"" + name + "\")]")); type.Members.Add(new CodeSnippetTypeMember( String.Format("partial void {1} ({2} sender);\n", name, provider.CreateValidIdentifier(name.TrimEnd(':')), senderType.BaseType))); return; } else if (provider.FileExtension == "pas") { var m = new CodeMemberMethod(); m.Name = provider.CreateValidIdentifier(name.TrimEnd(':')); m.Parameters.Add(new CodeParameterDeclarationExpression(senderType.BaseType, "sender")); m.UserData ["OxygenePartial"] = "YES"; m.UserData ["OxygeneEmpty"] = "YES"; var a = new CodeAttributeDeclaration("MonoTouch.Foundation.Export"); a.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(name))); m.CustomAttributes.Add(a); type.Members.Add(m); return; } var meth = CreateEventMethod(name, senderType); bool actionStubWriterCreated = false; if (actionStubWriter == null) { actionStubWriterCreated = true; actionStubWriter = new StringWriter(); actionStubWriter.WriteLine("Action method stubs:"); actionStubWriter.WriteLine(); } try { provider.GenerateCodeFromMember(meth, actionStubWriter, generatorOptions); actionStubWriter.WriteLine(); } catch { //clear the header if generation failed if (actionStubWriterCreated) { actionStubWriter = null; } } }
private static string MakeValidIdentifier(this string s) { var id = InvalidCharsRegex.Replace(s, m => InvalidChars[m.Value[0]]); id = id.Replace("-", ""); return(Provider.CreateValidIdentifier(Regex.Replace(id, @"\W+", "_"))); }
private static string VerifyResourceName(string key, CodeDomProvider provider, bool isNameSpace) { if (key == null) { throw new ArgumentNullException("key"); } if (provider == null) { throw new ArgumentNullException("provider"); } foreach (char ch in CharsToReplace) { if (!isNameSpace || ((ch != '.') && (ch != ':'))) { key = key.Replace(ch, '_'); } } if (provider.IsValidIdentifier(key)) { return(key); } key = provider.CreateValidIdentifier(key); if (provider.IsValidIdentifier(key)) { return(key); } key = "_" + key; if (provider.IsValidIdentifier(key)) { return(key); } return(null); }
private static string GetSafeNameInternal(string name) { var safeName = name.Trim(); // RegEx to conform to C# spec // Mono can't handle \p{Cf} safeName = Regex.Replace(safeName, @"[^\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\s]+", ""); safeName = Regex.Replace(safeName, @"[\s]+", "_"); safeName = ReduceUnicodeNumbers(safeName); safeName = ReduceNonMonoCharacters(safeName); if (safeName.Length > 0 && !IsIdentifierStartCharacter(safeName[0])) { safeName = "_" + safeName; } safeName = _provider.CreateValidIdentifier(safeName); if (!IsSafeName(safeName)) { throw new Exception(string.Format("Failed to create a safe name ({0} -> {1})", name, safeName)); } return(safeName); }
public Dictionary <string, List <NSObjectTypeInfo> > GetTypeUpdates(IProgressMonitor monitor, CodeDomProvider provider, out Dictionary <string, NSObjectTypeInfo> newTypes, out Dictionary <string, ProjectFile> newFiles) { Dictionary <string, List <NSObjectTypeInfo> > designerFiles = new Dictionary <string, List <NSObjectTypeInfo> > (); string defaultNamespace; // First, we need to name any new user-defined types. foreach (var job in TypeSyncJobs) { if (!job.IsFreshlyAdded) { monitor.Log.WriteLine("Found updated class: {0}", job.Type.CliName); continue; } defaultNamespace = Project.GetDefaultNamespace(job.RelativePath); job.Type.CliName = defaultNamespace + "." + provider.CreateValidIdentifier(job.Type.ObjCName); monitor.Log.WriteLine("Found newly-added class: {0}", job.Type.CliName); ProjectInfo.InsertUpdatedType(job.Type); } // Next we can resolve base-types, outlet types, and action parameter types for each of our user-defined types. foreach (var job in TypeSyncJobs) { defaultNamespace = Project.GetDefaultNamespace(job.RelativePath); ProjectInfo.ResolveObjcToCli(monitor, job.Type, provider, defaultNamespace); } AggregateTypeUpdates(monitor, provider, designerFiles, out newTypes, out newFiles); MergeExistingTypes(designerFiles); return(designerFiles); }
/// <summary>Generates a valid identifier based on the specified input string and code provider.</summary> /// <returns>A valid identifier with any invalid tokens replaced with the underscore (_) character, or null if the string still contains invalid characters according to the language specified by the provider parameter.</returns> /// <param name="provider">A <see cref="T:System.CodeDom.Compiler.CodeDomProvider"></see> object that specifies the target language to use.</param> /// <param name="name">The string to verify and, if necessary, convert to a valid resource name.</param> /// <exception cref="T:System.ArgumentNullException">key or provider is null.</exception> public static string ValidateIdentifier(this CodeDomProvider provider, string name, bool isNameSpace = false) { for (var index = 0; index < InvalidIdentifierTokens.Length; index++) { var invalidToken = InvalidIdentifierTokens [index]; if (!isNameSpace || invalidToken != '.' && invalidToken != ':') { name = name.Replace(invalidToken, InvalidIdentifierTokenReplacement); } } if (provider.IsValidIdentifier(name, isNameSpace)) { return(name); } name = provider.CreateValidIdentifier(name); if (provider.IsValidIdentifier(name, isNameSpace)) { return(name); } name = "_" + name; if (provider.IsValidIdentifier(name, isNameSpace)) { return(name); } return(null); }
public static string CreateValidIdentifier(string identifier, CasingType casingType = CasingType.None) { string casedIdentifier; switch (casingType) { case CasingType.Camel: casedIdentifier = identifier.ToCamelCase(); break; case CasingType.Pascal: casedIdentifier = identifier.ToPascalCase(); break; default: casedIdentifier = identifier; break; } bool isValid = CodeProvider.IsValidIdentifier(casedIdentifier); if (!isValid) { // File name contains invalid chars, remove them casedIdentifier = Regex.Replace(casedIdentifier, string.Empty); // Class name doesn't begin with a letter, insert an underscore if (!char.IsLetter(casedIdentifier, 0)) { casedIdentifier = casedIdentifier.Insert(0, "_"); } } return(CodeProvider.CreateValidIdentifier(casedIdentifier.Replace(" ", string.Empty))); }
public static string Sanitize(this string s) { var regex = new Regex(@"[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Nl}\p{Mn}\p{Mc}\p{Cf}\p{Pc}\p{Lm}]"); var validIdentifier = regex.Replace(s, ""); validIdentifier = provider.CreateValidIdentifier(validIdentifier); return(validIdentifier); }
/// <summary> /// Fixes module names to remove invalid characters and make the name a valid C# identifier /// </summary> internal static string FixName(string name) { name = NameRegex.Replace(name, string.Empty); name = CsharpProvider.CreateValidIdentifier(name); if (!CsharpProvider.IsValidIdentifier(name)) { return(string.Empty); } return(name); }
public string GenerateDefaultDataContextTypeName() { Project activeProject = base.ActiveProject; string defaultModelsNamespace = MvcProjectUtil.GetDefaultModelsNamespace(ProjectExtensions.GetDefaultNamespace(activeProject)); CodeDomProvider codeDomProvider = ValidationUtil.GenerateCodeDomProvider(ProjectExtensions.GetCodeLanguage(activeProject)); string str = codeDomProvider.CreateValidIdentifier(ProjectExtensions.GetDefaultNamespace(activeProject).Replace(".", string.Empty)); this.DataContextName = string.Concat(defaultModelsNamespace, ".", str, MvcProjectUtil.DataContextSuffix); return(this.DataContextName); }
/// <summary> /// Function generates the default DataContext name. /// </summary> public string GenerateDefaultDataContextTypeName() { Project project = ActiveProject; string modelsNamespace = MvcProjectUtil.GetDefaultModelsNamespace(project.GetDefaultNamespace()); CodeDomProvider provider = ValidationUtil.GenerateCodeDomProvider(project.GetCodeLanguage()); // CreateValidIdentifier considers dot as a valid identifier hence replacing the dot explicitly. string projectName = provider.CreateValidIdentifier(project.GetDefaultNamespace().Replace(".", String.Empty)); DataContextName = modelsNamespace + "." + projectName + MvcProjectUtil.DataContextSuffix; return(DataContextName); }
/// <summary> /// Takes a candidate c# identifier and makes it valid by removing whitespace, /// checking collision with c# keywords, and ensuring the composing characters /// are valid identifier characters. /// </summary> /// <param name="candidate">the candidate identifier</param> /// <returns>a valid c# identifier</returns> internal static string GetValidCSharpIdentifier(string candidate) { // return CodeIdentifier.MakeValid(candidate); const char underscore = '_'; CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); //if the candidate is null, set it to a single underscore. if (candidate == null) { candidate = underscore.ToString(); } //remove any spaces candidate = candidate.Replace(" ", string.Empty); StringBuilder attempt; try { //the CreateValidIdentifier() call only checks collisions with reserved keywords attempt = new StringBuilder(provider.CreateValidIdentifier(candidate)); if (attempt.Length < 1) { attempt = new StringBuilder(new string(underscore, 1)); } } catch (Exception ex) { attempt = new StringBuilder(new string(underscore, 1)); Trace.TraceWarning(ex.ToString()); } //loop through the string, ensuring that each character is a letter, digit or underscore for (int index = 0; index < attempt.Length; index++) { if (!char.IsLetterOrDigit(attempt[index]) && attempt[index] != underscore) { attempt[index] = underscore; } } //finally check that the first digit is a letter or underscore if (char.IsDigit(attempt[0])) { attempt.Insert(0, underscore); } return(attempt.ToString()); }
public static string VerifyResourceName(string key, CodeDomProvider provider) { string keyToUse; char [] charKey; // check params if (key == null) { throw new ArgumentNullException("Parameter: key must not be null"); } if (provider == null) { throw new ArgumentNullException("Parameter: provider must not be null"); } if (key == String.Empty) { keyToUse = "_"; } else { // replaces special chars charKey = key.ToCharArray(); for (int i = 0; i < charKey.Length; i++) { charKey [i] = VerifySpecialChar(charKey [i]); } keyToUse = new string(charKey); } // resolve if keyword keyToUse = provider.CreateValidIdentifier(keyToUse); // check if still not valid for provider if (provider.IsValidIdentifier(keyToUse)) { return(keyToUse); } else { return(null); } }
// Once CodeDom provides a way to verify a namespace name, revisit this method. private static String VerifyResourceName(String key, CodeDomProvider provider, bool isNameSpace) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (provider == null) { throw new ArgumentNullException(nameof(provider)); } foreach (char c in s_charsToReplace) { // For namespaces, allow . and :: if (!(isNameSpace && (c == '.' || c == ':'))) { key = key.Replace(c, ReplacementChar); } } if (provider.IsValidIdentifier(key)) { return(key); } // Now try fixing up keywords like "for". key = provider.CreateValidIdentifier(key); if (provider.IsValidIdentifier(key)) { return(key); } // make one last ditch effort by prepending _. This fixes keys that start with a number key = "_" + key; if (provider.IsValidIdentifier(key)) { return(key); } return(null); }
static void AddToStringHelper(CodeTypeDeclaration type, CodeDomProvider provider) { var helperClass = Declare.Class("ToStringInstanceHelper") .AsNestedPublic() .WithReference(out var helperClassType); helperClass.AddField <IFormatProvider> ("formatProvider", TypeReference <System.Globalization.CultureInfo> .Global.Property("InvariantCulture")) .WithReference(out var formatProvider); helperClass.AddProperty <IFormatProvider> ("FormatProvider") .WithGet(formatProvider) .WithSetIgnoresNull(formatProvider); helperClass.AddMethod("ToStringWithCulture") .Returns <string> () .WithParameter <object> ("objectToConvert", out var objectToConvert) .WithStatements( objectToConvert.ThrowIfNull(), Declare.Variable <Type> ("type", objectToConvert.InvokeMethod("GetType"), out var objType), Declare.Variable <Type> ("iConvertibleType", Expression.TypeOf <IConvertible> (), out var iConvertibleType), Statement.If(iConvertibleType.InvokeMethod("IsAssignableFrom", objType), Then: Statement.Return(objectToConvert.Cast <IConvertible> ().InvokeMethod("ToString", formatProvider))), Declare.Variable <System.Reflection.MethodInfo> ("methInfo", objType.InvokeMethod("GetMethod", Expression.Primitive("ToString"), Expression.Array <Type> (iConvertibleType)), out var methInfoLocalRef), Statement.If(methInfoLocalRef.IsNotNull(), Then: Statement.Return(Expression.Cast <string> ( methInfoLocalRef.InvokeMethod("Invoke", objectToConvert, Expression.Array <object> (formatProvider))))), Statement.Return(objectToConvert.InvokeMethod("ToString")) ); var helperFieldName = provider.CreateValidIdentifier("_toStringHelper"); type.AddPropertyGetOnly("ToStringHelper", type.AddField(helperFieldName, helperClassType, Expression.New(helperClassType))); type.AddMember(helperClass); }
internal static string GenerateUniqueIdentifier(IServiceProvider serviceProvider, string baseIdentifier, string[] existingNames) { CodeDomProvider provider = null; if (serviceProvider != null) { provider = serviceProvider.GetService(typeof(CodeDomProvider)) as CodeDomProvider; if (provider == null) { IdentifierCreationService service = serviceProvider.GetService(typeof(IIdentifierCreationService)) as IdentifierCreationService; if (service != null) { provider = service.Provider; } } } if (provider != null) { baseIdentifier = provider.CreateValidIdentifier(baseIdentifier); } baseIdentifier = baseIdentifier.Replace('.', '_'); baseIdentifier = baseIdentifier.Replace('/', '_'); baseIdentifier = baseIdentifier.Replace('(', '_'); baseIdentifier = baseIdentifier.Replace(')', '_'); baseIdentifier = baseIdentifier.Replace(" ", ""); ArrayList list = new ArrayList(existingNames); int num = 1; string str = string.Format(CultureInfo.InvariantCulture, "{0}{1}", new object[] { baseIdentifier, num }); list.Sort(); while (list.BinarySearch(str.ToLowerInvariant(), StringComparer.OrdinalIgnoreCase) >= 0) { str = string.Format(CultureInfo.InvariantCulture, "{0}{1}", new object[] { baseIdentifier, num }); num++; } return(str); }
// very simplistic implementation to generate names like "button1", "someControl2", etc // string INameCreationService.CreateName(IContainer container, Type dataType) { if (dataType == null) { throw new ArgumentNullException("dataType"); } string name = dataType.Name; char lower = Char.ToLower(name[0]); name = name.Remove(0, 1); name = name.Insert(0, Char.ToString(lower)); int uniqueId = 1; bool unique = false; while (!unique) { if (container != null && container.Components[name + uniqueId] != null) { uniqueId++; } else { unique = true; name = name + uniqueId; } } if (this.CodeDomProvider != null) { name = CodeDomProvider.CreateValidIdentifier(name); } return(name); }
/// <summary> /// Produces a Pascal-case string from an input string. /// </summary> /// <param name="identifier">The name of a code entity, such as a method parameter.</param> /// <returns></returns> public static string ToPascalCase(string identifier) { Guard.ArgumentNotNullOrEmptyString(identifier, "identifier"); return(csProvider.CreateValidIdentifier(CodeIdentifier.MakePascal(identifier))); }
/// <summary> /// Resolves the type by mapping the known Objective-C type information to .NET types. /// </summary> /// <returns> /// The number of unresolved types still remaining. /// </returns> /// <param name='type'> /// The NSObjectTypeInfo that contains the known Objective-C type information. /// Typically this will be the result of NSObjectInfoService.ParseHeader(). /// </param> /// <param name='provider'> /// A CodeDom provider which is used to make sure type names don't conflict with language keywords. /// </param> /// <param name='defaultNamespace'> /// The default namespace used when forcing type resolution. /// </param> public void ResolveObjcToCli(IProgressMonitor monitor, NSObjectTypeInfo type, CodeDomProvider provider, string defaultNamespace) { NSObjectTypeInfo resolved; // Resolve our base type if (type.BaseCliType == null) { if (TryResolveObjcToCli(type.BaseObjCType, out resolved)) { type.BaseCliType = resolved.CliName; } else { var reference = new GetClassTypeReference(defaultNamespace, provider.CreateValidIdentifier(type.BaseObjCType)); type.BaseCliType = reference.Resolve(dom.Compilation).ReflectionName; var message = string.Format("Failed to resolve Objective-C type '{0}' to a type in the current solution.", type.BaseObjCType); message += string.Format(" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", type.BaseObjCType); monitor.ReportError(null, new UserException("Error while syncing", message)); } } // Resolve [Outlet] types foreach (var outlet in type.Outlets) { if (outlet.CliType != null) { continue; } if (TryResolveObjcToCli(outlet.ObjCType, out resolved)) { outlet.CliType = resolved.CliName; } else { outlet.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(outlet.ObjCType); var message = string.Format("Failed to resolve Objective-C outlet '{0}' of type '{1}' to a type in the current solution.", outlet.ObjCName, outlet.ObjCType); message += string.Format(" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", outlet.ObjCType); monitor.ReportError(null, new UserException("Error while syncing", message)); } } // Resolve [Action] param types foreach (var action in type.Actions) { foreach (var param in action.Parameters) { if (param.CliType != null) { continue; } if (TryResolveObjcToCli(param.ObjCType, out resolved)) { param.CliType = resolved.CliName; } else { param.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(param.ObjCType); var message = string.Format("Failed to resolve paramater '{0}' of type '{2}' on Objective-C action '{1}' to a type in the current solution.", param.Name, action.ObjCName, param.ObjCType); message += string.Format(" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", param.ObjCType); monitor.ReportError(null, new UserException("Error while syncing", message)); } } } }
public static CodeCompileUnit Create(IDictionary resourceList, string baseName, string generatedCodeNamespace, string resourcesNamespace, CodeDomProvider codeProvider, bool internalClass, out string [] unmatchable) { string baseNameToUse, generatedCodeNamespaceToUse; string resourcesToUse; // validate parameters, convert into useable form where necessary / possible if (resourceList == null) { throw new ArgumentNullException("Parameter resourceList must not be null"); } if (codeProvider == null) { throw new ArgumentNullException("Parameter: codeProvider must not be null"); } if (baseName == null) { throw new ArgumentNullException("Parameter: baseName must not be null"); } baseNameToUse = VerifyResourceName(baseName, codeProvider); if (baseNameToUse == null) { throw new ArgumentException("Parameter: baseName is invalid"); } if (generatedCodeNamespace == null) { generatedCodeNamespaceToUse = ""; } else { generatedCodeNamespaceToUse = CleanNamespaceChars(generatedCodeNamespace); generatedCodeNamespaceToUse = codeProvider.CreateValidIdentifier( generatedCodeNamespaceToUse); } if (resourcesNamespace == null) { resourcesToUse = generatedCodeNamespaceToUse + "." + baseNameToUse; } else if (resourcesNamespace == String.Empty) { resourcesToUse = baseNameToUse; } else { resourcesToUse = resourcesNamespace + "." + baseNameToUse; } // validate ResourceList IDictionary Dictionary <string, ResourceItem> resourceItemDict; resourceItemDict = new Dictionary <string, ResourceItem> (StringComparer.OrdinalIgnoreCase); //allow ArgumentException to be raised on case insensitive dupes,InvalidCastException on key not being string foreach (DictionaryEntry de in resourceList) { resourceItemDict.Add((string)de.Key, new ResourceItem(de.Value)); } ProcessResourceList(resourceItemDict, codeProvider); // Generate CodeDOM CodeCompileUnit ccu = GenerateCodeDOMBase(baseNameToUse, generatedCodeNamespaceToUse, resourcesToUse, internalClass); // add properties for resources unmatchable = ResourcePropertyGeneration(ccu.Namespaces [0].Types [0], resourceItemDict, internalClass); return(ccu); }
/// <summary> /// Resolves the type by mapping the known Objective-C type information to .NET types. /// </summary> /// <returns> /// The number of unresolved types still remaining. /// </returns> /// <param name='type'> /// The NSObjectTypeInfo that contains the known Objective-C type information. /// Typically this will be the result of NSObjectInfoService.ParseHeader(). /// </param> /// <param name='provider'> /// A CodeDom provider which is used to make sure type names don't conflict with language keywords. /// </param> /// <param name='defaultNamespace'> /// The default namespace used when forcing type resolution. /// </param> public void ResolveObjcToCli(IProgressMonitor monitor, NSObjectTypeInfo type, CodeDomProvider provider, string defaultNamespace) { NSObjectTypeInfo resolved; // Resolve our base type if (type.BaseCliType == null) { if (TryResolveObjcToCli(type.BaseObjCType, out resolved)) { type.BaseCliType = resolved.CliName; } else { type.BaseCliType = defaultNamespace + "." + provider.CreateValidIdentifier(type.BaseObjCType); monitor.ReportWarning(string.Format("Failed to resolve Objective-C type {0} to CLI type on type {1}", type.BaseObjCType, type.ObjCName)); } } // Resolve [Outlet] types foreach (var outlet in type.Outlets) { if (outlet.CliType != null) { continue; } if (TryResolveObjcToCli(outlet.ObjCType, out resolved)) { outlet.CliType = resolved.CliName; } else { outlet.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(outlet.ObjCType); monitor.ReportWarning(string.Format("Failed to resolve Objective-C type {0} to CLI type on outlet {1} on type {2}", outlet.ObjCType, outlet.ObjCName, type.ObjCName)); } } // Resolve [Action] param types foreach (var action in type.Actions) { foreach (var param in action.Parameters) { if (param.CliType != null) { continue; } if (TryResolveObjcToCli(param.ObjCType, out resolved)) { param.CliType = resolved.CliName; } else { param.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(param.ObjCType); monitor.ReportWarning(string.Format("Failed to resolve Objective-C type {0} to CLI type on action parameter {1} for action {2} on type {3}", param.ObjCType, param.Name, action.ObjCName, type.ObjCName)); } } } }
public string CreateValidIdentifier(string value) { return(provider.CreateValidIdentifier(value)); }