diff options
author | Matt Ward <matt.ward@xamarin.com> | 2015-12-15 14:22:52 +0300 |
---|---|---|
committer | Matt Ward <matt.ward@xamarin.com> | 2015-12-15 15:45:29 +0300 |
commit | 2bbdea09fc4939c4590ee8a484f731eaea4cced9 (patch) | |
tree | 03c15121a22146ee7f5e697a3b0eac316bd1e84c /main | |
parent | 5dd4015a02e72f2f9c2f2fb34f69c0d24adcef9a (diff) |
[Ide] Prevent language keyword being used as new project name.
Fixed bug #15478 - MonoDevelop shouldn't accept language keywords as
Project Name
https://bugzilla.xamarin.com/show_bug.cgi?id=15478
If a new C# project was created with the name 'try' then the project
would not compile since the generated files would have an invalid
namespace of 'try'. To prevent this the new project dialog now checks
the CodeDomProvider for the template's language to see if the project
name is a valid identifier. If this is not the case an error message
is displayed and the project cannot be created until its name is
changed.
Another approach would be to escape the namespace in the
SingleFileDescriptionTemplate using the CodeDomProvider's
CreateEscapedIdentifier. Whilst that works for C# projects it
does not work for F# projects. If you try to create an F# project
named 'try' it does not escape the namespace or use the namespace
created by the IDE.
Diffstat (limited to 'main')
-rw-r--r-- | main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs index 5babfa528e..80488b90a3 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs @@ -35,6 +35,7 @@ using System; using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text;
using Mono.Addins;
using MonoDevelop.Core;
using MonoDevelop.Ide.Templates;
@@ -641,6 +642,12 @@ namespace MonoDevelop.Ide.Projects return false;
}
+ SolutionTemplate template = GetTemplateForProcessing ();
+ if (ProjectNameIsLanguageKeyword (template.Language, projectConfiguration.ProjectName)) {
+ MessageService.ShowError (GettextCatalog.GetString ("Illegal project name.\nName cannot contain a language keyword."));
+ return false;
+ }
+
ProcessedTemplateResult result = null;
try {
@@ -663,7 +670,7 @@ namespace MonoDevelop.Ide.Projects DisposeExistingNewItems ();
try {
- result = IdeApp.Services.TemplatingService.ProcessTemplate (GetTemplateForProcessing (), projectConfiguration, ParentFolder);
+ result = IdeApp.Services.TemplatingService.ProcessTemplate (template, projectConfiguration, ParentFolder);
if (!result.WorkspaceItems.Any ())
return false;
} catch (UserException ex) {
@@ -696,6 +703,42 @@ namespace MonoDevelop.Ide.Projects }
}
+ static bool ProjectNameIsLanguageKeyword (string language, string projectName)
+ {
+ LanguageBinding binding = LanguageBindingService.GetBindingPerLanguageName (language);
+ if (binding != null) {
+ var codeDomProvider = binding.GetCodeDomProvider ();
+ if (codeDomProvider != null) {
+ projectName = SanitisePotentialNamespace (projectName);
+ return !codeDomProvider.IsValidIdentifier (projectName);
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Taken from DotNetProject. This is needed otherwise an invalid namespace
+ /// can still be used if digits are used as the start of the project name
+ /// (e.g. '2try').
+ /// </summary>
+ static string SanitisePotentialNamespace (string potential)
+ {
+ var sb = new StringBuilder ();
+ foreach (char c in potential) {
+ if (char.IsLetter (c) || c == '_' || (sb.Length > 0 && (char.IsLetterOrDigit (sb[sb.Length - 1]) || sb[sb.Length - 1] == '_') && (c == '.' || char.IsNumber (c)))) {
+ sb.Append (c);
+ }
+ }
+ if (sb.Length > 0) {
+ if (sb[sb.Length - 1] == '.')
+ sb.Remove (sb.Length - 1, 1);
+
+ return sb.ToString ();
+ } else
+ return "Application";
+ }
+
void InstallProjectTemplatePackages (Solution sol)
{
if (!processedTemplate.HasPackages ())
|