internal bool CheckForSpecificVersionMetadataOnParentsReference(bool anyParentHasMetadata) { bool hasSpecificVersionMetadata = false; // We are our own parent, therefore the specific version metadata is what ever is passed into as wantspecificVersion for this reference. // this saves us from having to read the metadata from our item again. if (IsPrimary) { hasSpecificVersionMetadata = WantSpecificVersion; } else { // Go through all of the primary items which lead to this dependency, if they all have specificVersion set to true then // hasSpecificVersionMetadata will be true. If any item has the metadata set to false or not set then the value will be false. foreach (ITaskItem item in GetSourceItems()) { hasSpecificVersionMetadata = MetadataConversionUtilities.TryConvertItemMetadataToBool(item, ItemMetadataNames.specificVersion); // Break if one of the primary references has specific version false or not set if (anyParentHasMetadata == hasSpecificVersionMetadata) { break; } } } return(hasSpecificVersionMetadata); }
internal void MakePrimaryAssemblyReference ( ITaskItem sourceItem, bool wantSpecificVersionValue, string executableExtension ) { CopyLocal = CopyLocalState.Undecided; // This is a primary reference. IsPrimary = true; // This is the source item (from the list passed into the task) that // originally created this reference. _primarySourceItem = sourceItem; SDKName = sourceItem.GetMetadata("SDKName"); if (!string.IsNullOrEmpty(executableExtension)) { // Set the expected extension. SetExecutableExtension(executableExtension); } // The specific version indicator. WantSpecificVersion = wantSpecificVersionValue; // This is an assembly file, so we'll need to find dependencies later. DependenciesFound = false; ExternallyResolved = MetadataConversionUtilities.TryConvertItemMetadataToBool(sourceItem, "ExternallyResolved"); // Add source items from the original item. AddSourceItem(sourceItem); }
private void AddReferencesToCommandLine(CommandLineBuilderExtension commandLine) { if ((base.References != null) && (base.References.Length != 0)) { List <ITaskItem> list = new List <ITaskItem>(base.References.Length); List <ITaskItem> list2 = new List <ITaskItem>(base.References.Length); foreach (ITaskItem item in base.References) { if (MetadataConversionUtilities.TryConvertItemMetadataToBool(item, "EmbedInteropTypes")) { list2.Add(item); } else { list.Add(item); } } if (list2.Count > 0) { commandLine.AppendSwitchIfNotNull("/link:", list2.ToArray(), ","); } if (list.Count > 0) { commandLine.AppendSwitchIfNotNull("/reference:", list.ToArray(), ","); } } }
internal void AppendSwitchIfNotNull(string switchName, ITaskItem[] parameters, string[] metadataNames, bool[] treatAsFlags) { Microsoft.Build.Shared.ErrorUtilities.VerifyThrow((treatAsFlags == null) || (metadataNames.Length == treatAsFlags.Length), "metadataNames and treatAsFlags should have the same length."); if (parameters != null) { foreach (ITaskItem item in parameters) { base.AppendSwitchIfNotNull(switchName, item.ItemSpec); if (metadataNames != null) { for (int i = 0; i < metadataNames.Length; i++) { string metadata = item.GetMetadata(metadataNames[i]); if ((metadata != null) && (metadata.Length > 0)) { if ((treatAsFlags == null) || !treatAsFlags[i]) { base.CommandLine.Append(','); base.AppendTextWithQuoting(metadata); } else if (MetadataConversionUtilities.TryConvertItemMetadataToBool(item, metadataNames[i])) { base.CommandLine.Append(','); base.AppendTextWithQuoting(metadataNames[i]); } } else if ((treatAsFlags == null) || !treatAsFlags[i]) { break; } } } } } }
private void AddReferencesToCommandLine(CommandLineBuilderExtension commandLine) { if (base.References == null || base.References.Length == 0) { return; } ITaskItem[] references = base.References; for (int i = 0; i < references.Length; i++) { ITaskItem taskItem = references[i]; string metadata = taskItem.GetMetadata("Aliases"); string switchName = "/reference:"; bool flag = MetadataConversionUtilities.TryConvertItemMetadataToBool(taskItem, "EmbedInteropTypes"); if (flag) { switchName = "/link:"; } if (metadata == null || metadata.Length == 0) { commandLine.AppendSwitchIfNotNull(switchName, taskItem.ItemSpec); } else { string[] array = metadata.Split(new char[] { ',' }); string[] array2 = array; for (int j = 0; j < array2.Length; j++) { string text = array2[j]; string text2 = text.Trim(); if (text.Length != 0) { if (text2.IndexOfAny(new char[] { ',', ' ', ';', '"' }) != -1) { ErrorUtilities.VerifyThrowArgument(false, "Csc.AssemblyAliasContainsIllegalCharacters", taskItem.ItemSpec, text2); } if (string.Compare("global", text2, StringComparison.OrdinalIgnoreCase) == 0) { commandLine.AppendSwitchIfNotNull(switchName, taskItem.ItemSpec); } else { commandLine.AppendSwitchAliased(switchName, text2, taskItem.ItemSpec); } } } } } }
internal bool CheckForSpecificVersionMetadataOnParentsReference(bool anyParentHasMetadata) { bool flag = false; if (this.IsPrimary) { return(this.wantSpecificVersion); } foreach (ITaskItem item in this.GetSourceItems()) { flag = MetadataConversionUtilities.TryConvertItemMetadataToBool(item, "SpecificVersion"); if (anyParentHasMetadata == flag) { return(flag); } } return(flag); }
private void AddReferencesToCommandLine(CommandLineBuilderExtension commandLine) { if ((base.References != null) && (base.References.Length != 0)) { foreach (ITaskItem item in base.References) { string metadata = item.GetMetadata("Aliases"); string switchName = "/reference:"; if (MetadataConversionUtilities.TryConvertItemMetadataToBool(item, "EmbedInteropTypes")) { switchName = "/link:"; } if ((metadata == null) || (metadata.Length == 0)) { commandLine.AppendSwitchIfNotNull(switchName, item.ItemSpec); } else { foreach (string str3 in metadata.Split(new char[] { ',' })) { string str4 = str3.Trim(); if (str3.Length != 0) { if (str4.IndexOfAny(new char[] { ',', ' ', ';', '"' }) != -1) { Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgument(false, "Csc.AssemblyAliasContainsIllegalCharacters", item.ItemSpec, str4); } if (string.Compare("global", str4, StringComparison.OrdinalIgnoreCase) == 0) { commandLine.AppendSwitchIfNotNull(switchName, item.ItemSpec); } else { commandLine.AppendSwitchAliased(switchName, str4, item.ItemSpec); } } } } } } }
internal void SetFinalCopyLocalState ( AssemblyNameExtension assemblyName, string[] frameworkPaths, ProcessorArchitecture targetProcessorArchitecture, GetAssemblyRuntimeVersion getRuntimeVersion, Version targetedRuntimeVersion, FileExists fileExists, GetAssemblyPathInGac getAssemblyPathInGac, bool copyLocalDependenciesWhenParentReferenceInGac, bool doNotCopyLocalIfInGac, ReferenceTable referenceTable ) { // If this item was unresolvable, then copy-local is false. if (IsUnresolvable) { CopyLocal = CopyLocalState.NoBecauseUnresolved; return; } if (EmbedInteropTypes) { CopyLocal = CopyLocalState.NoBecauseEmbedded; return; } // If this item was a conflict victim, then it should not be copy-local. if (IsConflictVictim) { CopyLocal = CopyLocalState.NoBecauseConflictVictim; return; } // If this is a primary reference then see if there's a Private metadata on the source item if (IsPrimary) { bool found; bool result = MetadataConversionUtilities.TryConvertItemMetadataToBool ( PrimarySourceItem, ItemMetadataNames.privateMetadata, out found ); if (found) { CopyLocal = result ? CopyLocalState.YesBecauseReferenceItemHadMetadata : CopyLocalState.NoBecauseReferenceItemHadMetadata; return; } } else { // This is a dependency. If any primary reference that lead to this dependency // has Private=false, then this dependency should false too. bool privateTrueFound = false; bool privateFalseFound = false; foreach (ITaskItem item in _sourceItems.Values) { bool found; bool result = MetadataConversionUtilities.TryConvertItemMetadataToBool ( item, ItemMetadataNames.privateMetadata, out found ); if (found) { if (result) { privateTrueFound = true; // Once we hit this once we know there will be no modification to CopyLocal state. // so we can immediately... break; } else { privateFalseFound = true; } } } if (privateFalseFound && !privateTrueFound) { CopyLocal = CopyLocalState.NoBecauseReferenceItemHadMetadata; return; } } // If the item was determined to be an prereq assembly. if (IsPrerequisite && !UserRequestedSpecificFile) { CopyLocal = CopyLocalState.NoBecausePrerequisite; return; } // Items in the frameworks directory shouldn't be copy-local if (IsFrameworkFile(_fullPath, frameworkPaths)) { CopyLocal = CopyLocalState.NoBecauseFrameworkFile; return; } // We are a dependency, check to see if all of our parent references have come from the GAC if (!IsPrimary && !copyLocalDependenciesWhenParentReferenceInGac) { // Did we discover a parent reference which was not found in the GAC bool foundSourceItemNotInGac = false; // Go through all of the parent source items and check to see if they were found in the GAC foreach (string key in _sourceItems.Keys) { AssemblyNameExtension primaryAssemblyName = referenceTable.GetReferenceFromItemSpec(key); Reference primaryReference = referenceTable.GetReference(primaryAssemblyName); if (doNotCopyLocalIfInGac) { // Legacy behavior, don't copy local if the assembly is in the GAC at all if (!primaryReference.FoundInGac.HasValue) { primaryReference.FoundInGac = !string.IsNullOrEmpty(getAssemblyPathInGac(primaryAssemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists, true, false)); } if (!primaryReference.FoundInGac.Value) { foundSourceItemNotInGac = true; break; } } else { if (!primaryReference.ResolvedFromGac) { foundSourceItemNotInGac = true; break; } } } // All parent source items were found in the GAC. if (!foundSourceItemNotInGac) { CopyLocal = CopyLocalState.NoBecauseParentReferencesFoundInGAC; return; } } if (doNotCopyLocalIfInGac) { // Legacy behavior, don't copy local if the assembly is in the GAC at all if (!FoundInGac.HasValue) { FoundInGac = !string.IsNullOrEmpty(getAssemblyPathInGac(assemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists, true, false)); } if (FoundInGac.Value) { CopyLocal = CopyLocalState.NoBecauseReferenceFoundInGAC; return; } } if (ResolvedFromGac) { CopyLocal = CopyLocalState.NoBecauseReferenceResolvedFromGAC; return; } // It was resolved locally, so copy it. CopyLocal = CopyLocalState.YesBecauseOfHeuristic; }
/// <summary> /// Designed to handle the /link and /embed swithes: /// /// /embed[resource]:<filename>[,<name>[,Private]] /// /link[resource]:<filename>[,<name>[,Private]] /// /// Where the last flag--Private--is either present or not present /// depending on whether the ITaskItem has a Private="True" attribue. /// </summary> /// <param name="switchName"></param> /// <param name="parameters"></param> /// <param name="metadataNames"></param> /// <param name="treatAsFlags"></param> internal void AppendSwitchIfNotNull ( string switchName, ITaskItem[] parameters, string[] metadataNames, bool[] treatAsFlags // May be null. In this case no metadata are treated as flags. ) { ErrorUtilities.VerifyThrow ( treatAsFlags == null || (metadataNames.Length == treatAsFlags.Length), "metadataNames and treatAsFlags should have the same length." ); if (parameters != null) { foreach (ITaskItem parameter in parameters) { AppendSwitchIfNotNull(switchName, parameter.ItemSpec); if (metadataNames != null) { for (int i = 0; i < metadataNames.Length; ++i) { string metadataValue = parameter.GetMetadata(metadataNames[i]); if ((metadataValue != null) && (metadataValue.Length > 0)) { // Treat attribute as a boolean flag? if (treatAsFlags == null || treatAsFlags[i] == false) { // Not a boolean flag. CommandLine.Append(','); AppendTextWithQuoting(metadataValue); } else { // A boolean flag. bool flagSet = false; flagSet = MetadataConversionUtilities.TryConvertItemMetadataToBool(parameter, metadataNames[i]); if (flagSet) { CommandLine.Append(','); AppendTextWithQuoting(metadataNames[i]); } } } else { if (treatAsFlags == null || treatAsFlags[i] == false) { // If the caller of this method asked us to add metadata // A, B, and C, and metadata A doesn't exist on the item, // then it doesn't make sense to check for B and C. Because // since these metadata are just being appended on the // command-line switch with comma-separation, you can't pass // in the B metadata unless you've also passed in the A // metadata. Otherwise the tool's command-line parser will // get totally confused. // This only applies to non-flag attributes. break; } } } } } } }
internal void SetFinalCopyLocalState(AssemblyNameExtension assemblyName, string[] frameworkPaths, ProcessorArchitecture targetProcessorArchitecture, GetAssemblyRuntimeVersion getRuntimeVersion, Version targetedRuntimeVersion, Microsoft.Build.Shared.FileExists fileExists, bool copyLocalDependenciesWhenParentReferenceInGac, ReferenceTable referenceTable, CheckIfAssemblyInGac checkIfAssemblyInGac) { if (this.IsUnresolvable) { this.copyLocalState = CopyLocalState.NoBecauseUnresolved; } else if (this.EmbedInteropTypes) { this.copyLocalState = CopyLocalState.NoBecauseEmbedded; } else if (this.IsConflictVictim) { this.copyLocalState = CopyLocalState.NoBecauseConflictVictim; } else { if (this.IsPrimary) { bool flag; bool flag2 = MetadataConversionUtilities.TryConvertItemMetadataToBool(this.PrimarySourceItem, "Private", out flag); if (flag) { if (flag2) { this.copyLocalState = CopyLocalState.YesBecauseReferenceItemHadMetadata; return; } this.copyLocalState = CopyLocalState.NoBecauseReferenceItemHadMetadata; return; } } else { bool flag3 = false; bool flag4 = false; foreach (DictionaryEntry entry in this.sourceItems) { bool flag5; bool flag6 = MetadataConversionUtilities.TryConvertItemMetadataToBool((ITaskItem)entry.Value, "Private", out flag5); if (flag5) { if (flag6) { flag3 = true; break; } flag4 = true; } } if (flag4 && !flag3) { this.copyLocalState = CopyLocalState.NoBecauseReferenceItemHadMetadata; return; } } if (this.IsPrerequisite && !this.UserRequestedSpecificFile) { this.copyLocalState = CopyLocalState.NoBecausePrerequisite; } else if (IsFrameworkFile(this.fullPath, frameworkPaths)) { this.copyLocalState = CopyLocalState.NoBecauseFrameworkFile; } else { if (!this.FoundInGac.HasValue) { bool flag7 = checkIfAssemblyInGac(assemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists); this.FoundInGac = new bool?(flag7); } if (this.FoundInGac.Value) { this.copyLocalState = CopyLocalState.NoBecauseReferenceFoundInGAC; } else { if (!this.IsPrimary && !copyLocalDependenciesWhenParentReferenceInGac) { bool flag8 = false; foreach (DictionaryEntry entry2 in this.sourceItems) { AssemblyNameExtension referenceFromItemSpec = referenceTable.GetReferenceFromItemSpec((string)entry2.Key); Reference reference = referenceTable.GetReference(referenceFromItemSpec); bool flag9 = false; if (!reference.FoundInGac.HasValue) { flag9 = checkIfAssemblyInGac(referenceFromItemSpec, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists); reference.FoundInGac = new bool?(flag9); } else { flag9 = reference.FoundInGac.Value; } if (!flag9) { flag8 = true; break; } } if (!flag8) { this.copyLocalState = CopyLocalState.NoBecauseParentReferencesFoundInGAC; return; } } this.copyLocalState = CopyLocalState.YesBecauseOfHeuristic; } } } }
/// <summary> /// The C# compiler (starting with Whidbey) supports assembly aliasing for references. /// See spec at http://devdiv/spectool/Documents/Whidbey/VCSharp/Design%20Time/M3%20DCRs/DCR%20Assembly%20aliases.doc. /// This method handles the necessary work of looking at the "Aliases" attribute on /// the incoming "References" items, and making sure to generate the correct /// command-line on csc.exe. The syntax for aliasing a reference is: /// csc.exe /reference:Foo=System.Xml.dll /// /// The "Aliases" attribute on the "References" items is actually a comma-separated /// list of aliases, and if any of the aliases specified is the string "global", /// then we add that reference to the command-line without an alias. /// </summary> /// <param name="commandLine"></param> private void AddReferencesToCommandLine ( CommandLineBuilderExtension commandLine ) { // If there were no references passed in, don't add any /reference: switches // on the command-line. if ((this.References == null) || (this.References.Length == 0)) { return; } // Loop through all the references passed in. We'll be adding separate // /reference: switches for each reference, and in some cases even multiple // /reference: switches per reference. foreach (ITaskItem reference in this.References) { // See if there was an "Alias" attribute on the reference. string aliasString = reference.GetMetadata(ItemMetadataNames.aliases); string switchName = "/reference:"; bool embed = MetadataConversionUtilities.TryConvertItemMetadataToBool ( reference, ItemMetadataNames.embedInteropTypes ); if (embed == true) { switchName = "/link:"; } if ((aliasString == null) || (aliasString.Length == 0)) { // If there was no "Alias" attribute, just add this as a global reference. commandLine.AppendSwitchIfNotNull(switchName, reference.ItemSpec); } else { // If there was an "Alias" attribute, it contains a comma-separated list // of aliases to use for this reference. For each one of those aliases, // we're going to add a separate /reference: switch to the csc.exe // command-line string[] aliases = aliasString.Split(','); foreach (string alias in aliases) { // Trim whitespace. string trimmedAlias = alias.Trim(); if (alias.Length == 0) { continue; } // The alias should be a valid C# identifier. Therefore it cannot // contain comma, space, semicolon, or double-quote. Let's check for // the existence of those characters right here, and bail immediately // if any are present. There are a whole bunch of other characters // that are not allowed in a C# identifier, but we'll just let csc.exe // error out on those. The ones we're checking for here are the ones // that could seriously interfere with the command-line parsing or could // allow parameter injection. if (trimmedAlias.IndexOfAny(new char[] { ',', ' ', ';', '"' }) != -1) { ErrorUtilities.VerifyThrowArgument ( false, "Csc.AssemblyAliasContainsIllegalCharacters", reference.ItemSpec, trimmedAlias ); } // The alias called "global" is special. It means that we don't // give it an alias on the command-line. if (String.Compare("global", trimmedAlias, StringComparison.OrdinalIgnoreCase) == 0) { commandLine.AppendSwitchIfNotNull(switchName, reference.ItemSpec); } else { // We have a valid (and explicit) alias for this reference. Add // it to the command-line using the syntax: // /reference:Foo=System.Xml.dll commandLine.AppendSwitchAliased(switchName, trimmedAlias, reference.ItemSpec); } } } } }