public override bool Execute() { // In Xamarin Studio, if the project name isn't a valid C# identifier // then $(RootNamespace) is not set, and the generated Activity is // placed into the "Application" namespace. VS just munges the project // name to be a valid C# identifier. // Use "Application" as the default namespace name to work with XS. Namespace = Namespace ?? "Application"; Log.LogDebugMessage("GenerateResourceDesigner Task"); Log.LogDebugMessage(" NetResgenOutputFile: {0}", NetResgenOutputFile); Log.LogDebugMessage(" JavaResgenInputFile: {0}", JavaResgenInputFile); Log.LogDebugMessage(" Namespace: {0}", Namespace); Log.LogDebugMessage(" ResourceDirectory: {0}", ResourceDirectory); Log.LogDebugTaskItemsAndLogical(" AdditionalResourceDirectories:", AdditionalResourceDirectories); Log.LogDebugMessage(" IsApplication: {0}", IsApplication); Log.LogDebugMessage(" UseManagedResourceGenerator: {0}", UseManagedResourceGenerator); Log.LogDebugTaskItemsAndLogical(" Resources:", Resources); Log.LogDebugTaskItemsAndLogical(" References:", References); if (!File.Exists(JavaResgenInputFile) && !UseManagedResourceGenerator) { return(true); } // ResourceDirectory may be a relative path, and // we need to compare it to absolute paths ResourceDirectory = Path.GetFullPath(ResourceDirectory); // Create our capitalization maps so we can support mixed case resources foreach (var item in Resources) { if (!item.ItemSpec.StartsWith(ResourceDirectory)) { continue; } var name = item.ItemSpec.Substring(ResourceDirectory.Length); var logical_name = item.GetMetadata("LogicalName").Replace('\\', '/'); AddRename(name.Replace('/', Path.DirectorySeparatorChar), logical_name.Replace('/', Path.DirectorySeparatorChar)); } if (AdditionalResourceDirectories != null) { foreach (var additionalDir in AdditionalResourceDirectories) { var file = Path.Combine(ProjectDir, Path.GetDirectoryName(additionalDir.ItemSpec), "__res_name_case_map.txt"); if (File.Exists(file)) { foreach (var line in File.ReadAllLines(file).Where(l => !string.IsNullOrEmpty(l))) { string [] tok = line.Split(';'); AddRename(tok [1].Replace('/', Path.DirectorySeparatorChar), tok [0].Replace('/', Path.DirectorySeparatorChar)); } } } } // Parse out the resources from the R.java file CodeTypeDeclaration resources; if (UseManagedResourceGenerator) { var parser = new ManagedResourceParser() { Log = Log }; resources = parser.Parse(ResourceDirectory, AdditionalResourceDirectories?.Select(x => x.ItemSpec), IsApplication, resource_fixup); } else { var parser = new JavaResourceParser() { Log = Log }; resources = parser.Parse(JavaResgenInputFile, IsApplication, resource_fixup); } var extension = Path.GetExtension(NetResgenOutputFile); var language = string.Compare(extension, ".fs", StringComparison.OrdinalIgnoreCase) == 0 ? "F#" : CodeDomProvider.GetLanguageFromExtension(extension); bool isVB = string.Equals(extension, ".vb", StringComparison.OrdinalIgnoreCase); bool isFSharp = string.Equals(language, "F#", StringComparison.OrdinalIgnoreCase); bool isCSharp = string.Equals(language, "C#", StringComparison.OrdinalIgnoreCase); // Let VB put this in the default namespace if (isVB) { Namespace = string.Empty; } // Create static resource overwrite methods for each Resource class in libraries. var assemblyNames = new List <string> (); if (IsApplication && References != null && References.Any()) { // FIXME: should this be unified to some better code with ResolveLibraryProjectImports? using (var resolver = new DirectoryAssemblyResolver(this.CreateTaskLogger(), loadDebugSymbols: false)) { foreach (var assemblyName in References) { var suffix = assemblyName.ItemSpec.EndsWith(".dll") ? String.Empty : ".dll"; string hintPath = assemblyName.GetMetadata("HintPath").Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); string fileName = assemblyName.ItemSpec + suffix; string fullPath = Path.GetFullPath(assemblyName.ItemSpec); // Skip non existing files in DesignTimeBuild if (!File.Exists(fullPath) && DesignTimeBuild) { Log.LogDebugMessage("Skipping non existant dependancy '{0}' due to design time build.", fullPath); continue; } resolver.Load(fullPath); if (!String.IsNullOrEmpty(hintPath) && !File.Exists(hintPath)) // ignore invalid HintPath { hintPath = null; } string assemblyPath = String.IsNullOrEmpty(hintPath) ? fileName : hintPath; if (MonoAndroidHelper.IsFrameworkAssembly(fileName) && !MonoAndroidHelper.FrameworkEmbeddedJarLookupTargets.Contains(Path.GetFileName(fileName))) { continue; } Log.LogDebugMessage("Scan assembly {0} for resource generator", fileName); assemblyNames.Add(assemblyPath); } var assemblies = assemblyNames.Select(assembly => resolver.GetAssembly(assembly)); new ResourceDesignerImportGenerator(Namespace, resources, Log) .CreateImportMethods(assemblies); } } AdjustConstructor(isFSharp, resources); foreach (var member in resources.Members) { if (member is CodeTypeDeclaration) { AdjustConstructor(isFSharp, (CodeTypeDeclaration)member); } } // Write out our Resources.Designer.cs file WriteFile(NetResgenOutputFile, resources, language, isFSharp, isCSharp); return(!Log.HasLoggedErrors); }
public override bool RunTask() { // In Xamarin Studio, if the project name isn't a valid C# identifier // then $(RootNamespace) is not set, and the generated Activity is // placed into the "Application" namespace. VS just munges the project // name to be a valid C# identifier. // Use "Application" as the default namespace name to work with XS. Namespace = Namespace ?? "Application"; if (!File.Exists(JavaResgenInputFile) && !UseManagedResourceGenerator) { return(true); } // ResourceDirectory may be a relative path, and // we need to compare it to absolute paths ResourceDirectory = Path.GetFullPath(ResourceDirectory); var javaPlatformDirectory = Path.GetDirectoryName(JavaPlatformJarPath); // Create our capitalization maps so we can support mixed case resources foreach (var item in Resources) { if (!item.ItemSpec.StartsWith(ResourceDirectory)) { continue; } var name = item.ItemSpec.Substring(ResourceDirectory.Length); var logical_name = item.GetMetadata("LogicalName").Replace('\\', '/'); AddRename(name.Replace('/', Path.DirectorySeparatorChar), logical_name.Replace('/', Path.DirectorySeparatorChar)); } if (AdditionalResourceDirectories != null) { foreach (var additionalDir in AdditionalResourceDirectories) { var file = Path.Combine(ProjectDir, Path.GetDirectoryName(additionalDir.ItemSpec), "__res_name_case_map.txt"); if (File.Exists(file)) { foreach (var line in File.ReadAllLines(file).Where(l => !string.IsNullOrEmpty(l))) { string [] tok = line.Split(';'); AddRename(tok [1].Replace('/', Path.DirectorySeparatorChar), tok [0].Replace('/', Path.DirectorySeparatorChar)); } } } } // Parse out the resources from the R.java file CodeTypeDeclaration resources; if (UseManagedResourceGenerator) { var parser = new ManagedResourceParser() { Log = Log, JavaPlatformDirectory = javaPlatformDirectory, ResourceFlagFile = ResourceFlagFile }; resources = parser.Parse(ResourceDirectory, AdditionalResourceDirectories?.Select(x => x.ItemSpec), IsApplication, resource_fixup); } else { var parser = new JavaResourceParser() { Log = Log }; resources = parser.Parse(JavaResgenInputFile, IsApplication, resource_fixup); } var extension = Path.GetExtension(NetResgenOutputFile); var language = string.Compare(extension, ".fs", StringComparison.OrdinalIgnoreCase) == 0 ? "F#" : CodeDomProvider.GetLanguageFromExtension(extension); bool isVB = string.Equals(extension, ".vb", StringComparison.OrdinalIgnoreCase); bool isFSharp = string.Equals(language, "F#", StringComparison.OrdinalIgnoreCase); bool isCSharp = string.Equals(language, "C#", StringComparison.OrdinalIgnoreCase); if (isFSharp) { language = "C#"; isCSharp = true; NetResgenOutputFile = Path.ChangeExtension(NetResgenOutputFile, ".cs"); } // Let VB put this in the default namespace if (isVB) { Namespace = string.Empty; } List <string> aliases = new List <string> (); // Create static resource overwrite methods for each Resource class in libraries. if (IsApplication && References != null && References.Length > 0) { var assemblies = new List <ITaskItem> (References.Length); foreach (var assembly in References) { var assemblyPath = assembly.ItemSpec; var fileName = Path.GetFileName(assemblyPath); if (MonoAndroidHelper.IsFrameworkAssembly(fileName) && !MonoAndroidHelper.FrameworkEmbeddedJarLookupTargets.Contains(fileName)) { Log.LogDebugMessage($"Skipping framework assembly '{fileName}'."); continue; } if (!File.Exists(assemblyPath)) { Log.LogDebugMessage($"Skipping non-existent dependency '{assemblyPath}'."); continue; } ITaskItem item = new TaskItem(assemblyPath); assembly.CopyMetadataTo(item); assemblies.Add(item); string aliasMetaData = assembly.GetMetadata("Aliases"); if (!string.IsNullOrEmpty(aliasMetaData)) { foreach (var alias in aliasMetaData.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { string aliasName = alias.Trim(); // don't emit an `extern alias global` as it is implicitly done. if (string.Compare("global", aliasName, StringComparison.Ordinal) == 0) { continue; } aliases.Add(aliasName); // only add the first alias for each reference. break; } } Log.LogDebugMessage("Scan assembly {0} for resource generator", fileName); } new ResourceDesignerImportGenerator(Namespace, resources, Log) .CreateImportMethods(assemblies); } AdjustConstructor(resources); foreach (var member in resources.Members) { if (member is CodeTypeDeclaration) { AdjustConstructor((CodeTypeDeclaration)member); } } // Write out our Resources.Designer.cs file WriteFile(NetResgenOutputFile, resources, language, isCSharp, aliases); return(!Log.HasLoggedErrors); }