88using System . IO ;
99using System . Linq ;
1010using System . Xml ;
11-
1211using Microsoft . Build . BackEnd ;
1312using Microsoft . Build . Collections ;
1413using Microsoft . Build . Construction ;
@@ -190,11 +189,6 @@ public class Toolset : ITranslatable
190189 /// </summary>
191190 private Expander < ProjectPropertyInstance , ProjectItemInstance > _expander ;
192191
193- /// <summary>
194- /// Bag of properties for the expander to expand the properties and items in the using tasks files
195- /// </summary>
196- private PropertyDictionary < ProjectPropertyInstance > _propertyBag ;
197-
198192 /// <summary>
199193 /// SubToolsets that map to this toolset.
200194 /// </summary>
@@ -901,79 +895,79 @@ private void RegisterDefaultTasks(ILoggingService loggingServices, BuildEventCon
901895 /// </summary>
902896 private void InitializeProperties ( ILoggingService loggingServices , BuildEventContext buildEventContext )
903897 {
898+ if ( _expander != null )
899+ {
900+ return ;
901+ }
902+
904903 try
905904 {
906- if ( _propertyBag == null )
907- {
908- List < ProjectPropertyInstance > reservedProperties = new List < ProjectPropertyInstance > ( ) ;
905+
906+ List < ProjectPropertyInstance > reservedProperties = new List < ProjectPropertyInstance > ( ) ;
909907
910- reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . binPath , EscapingUtilities . Escape ( ToolsPath ) , mayBeReserved : true ) ) ;
911- reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . toolsVersion , ToolsVersion , mayBeReserved : true ) ) ;
908+ reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . binPath , EscapingUtilities . Escape ( ToolsPath ) , mayBeReserved : true ) ) ;
909+ reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . toolsVersion , ToolsVersion , mayBeReserved : true ) ) ;
912910
913- reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . toolsPath , EscapingUtilities . Escape ( ToolsPath ) , mayBeReserved : true ) ) ;
914- reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . assemblyVersion , Constants . AssemblyVersion , mayBeReserved : true ) ) ;
915- reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . version , MSBuildAssemblyFileVersion . Instance . MajorMinorBuild , mayBeReserved : true ) ) ;
911+ reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . toolsPath , EscapingUtilities . Escape ( ToolsPath ) , mayBeReserved : true ) ) ;
912+ reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . assemblyVersion , Constants . AssemblyVersion , mayBeReserved : true ) ) ;
913+ reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . version , MSBuildAssemblyFileVersion . Instance . MajorMinorBuild , mayBeReserved : true ) ) ;
916914
917- reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . msbuildRuntimeType ,
915+ reservedProperties . Add ( ProjectPropertyInstance . Create ( ReservedPropertyNames . msbuildRuntimeType ,
918916#if RUNTIME_TYPE_NETCORE
919- Traits . Instance . ForceEvaluateAsFullFramework ? "Full" : "Core" ,
917+ Traits . Instance . ForceEvaluateAsFullFramework ? "Full" : "Core" ,
920918#elif MONO
921- NativeMethodsShared . IsMono ? "Mono" : "Full" ) ;
919+ NativeMethodsShared . IsMono ? "Mono" : "Full" ) ;
922920#else
923- "Full" ,
921+ "Full" ,
924922#endif
925- mayBeReserved: true) ) ;
923+ mayBeReserved: true) ) ;
926924
927925
928- // Add one for the subtoolset version property -- it may or may not be set depending on whether it has already been set by the
929- // environment or global properties, but it's better to create a dictionary that's one too big than one that's one too small.
930- int count = _environmentProperties . Count + reservedProperties . Count + Properties . Values . Count + _globalProperties . Count + 1 ;
926+ // Add one for the subtoolset version property -- it may or may not be set depending on whether it has already been set by the
927+ // environment or global properties, but it's better to create a dictionary that's one too big than one that's one too small.
928+ int count = _environmentProperties . Count + reservedProperties . Count + Properties . Values . Count + _globalProperties . Count + 1 ;
931929
932- // GenerateSubToolsetVersion checks the environment and global properties, so it's safe to go ahead and gather the
933- // subtoolset properties here without fearing that we'll have somehow come up with the wrong subtoolset version.
934- string subToolsetVersion = this . GenerateSubToolsetVersion ( ) ;
935- SubToolset subToolset ;
936- ICollection < ProjectPropertyInstance > subToolsetProperties = null ;
930+ // GenerateSubToolsetVersion checks the environment and global properties, so it's safe to go ahead and gather the
931+ // subtoolset properties here without fearing that we'll have somehow come up with the wrong subtoolset version.
932+ string subToolsetVersion = this . GenerateSubToolsetVersion ( ) ;
933+ SubToolset subToolset ;
934+ ICollection < ProjectPropertyInstance > subToolsetProperties = null ;
937935
938- if ( subToolsetVersion != null )
936+ if ( subToolsetVersion != null )
937+ {
938+ if ( SubToolsets . TryGetValue ( subToolsetVersion , out subToolset ) )
939939 {
940- if ( SubToolsets . TryGetValue ( subToolsetVersion , out subToolset ) )
941- {
942- subToolsetProperties = subToolset . Properties . Values ;
943- count += subToolsetProperties . Count ;
944- }
940+ subToolsetProperties = subToolset . Properties . Values ;
941+ count += subToolsetProperties . Count ;
945942 }
943+ }
946944
947- _propertyBag = new PropertyDictionary < ProjectPropertyInstance > ( count ) ;
948-
949- // Should be imported in the same order as in the evaluator:
950- // - Environment
951- // - Toolset
952- // - Subtoolset (if any)
953- // - Global
954- _propertyBag . ImportProperties ( _environmentProperties ) ;
945+ PropertyDictionary < ProjectPropertyInstance > propertyBag = new PropertyDictionary < ProjectPropertyInstance > ( count ) ;
955946
956- _propertyBag . ImportProperties ( reservedProperties ) ;
947+ // Should be imported in the same order as in the evaluator:
948+ // - Environment
949+ // - Toolset
950+ // - Subtoolset (if any)
951+ // - Global
952+ propertyBag . ImportProperties ( _environmentProperties ) ;
957953
958- _propertyBag . ImportProperties ( Properties . Values ) ;
954+ propertyBag . ImportProperties ( reservedProperties ) ;
959955
960- if ( subToolsetVersion != null )
961- {
962- _propertyBag . Set ( ProjectPropertyInstance . Create ( Constants . SubToolsetVersionPropertyName , subToolsetVersion ) ) ;
963- }
964-
965- if ( subToolsetProperties != null )
966- {
967- _propertyBag . ImportProperties ( subToolsetProperties ) ;
968- }
956+ propertyBag . ImportProperties ( Properties . Values ) ;
969957
970- _propertyBag . ImportProperties ( _globalProperties ) ;
958+ if ( subToolsetVersion != null )
959+ {
960+ propertyBag . Set ( ProjectPropertyInstance . Create ( Constants . SubToolsetVersionPropertyName , subToolsetVersion ) ) ;
971961 }
972962
973- if ( _expander = = null )
963+ if ( subToolsetProperties ! = null )
974964 {
975- _expander = new Expander < ProjectPropertyInstance , ProjectItemInstance > ( _propertyBag , FileSystems . Default ) ;
965+ propertyBag . ImportProperties ( subToolsetProperties ) ;
976966 }
967+
968+ propertyBag . ImportProperties ( _globalProperties ) ;
969+
970+ _expander = new Expander < ProjectPropertyInstance , ProjectItemInstance > ( propertyBag , FileSystems . Default ) ;
977971 }
978972 catch ( Exception e ) when ( ExceptionHandling . IsIoRelatedException ( e ) )
979973 {
@@ -1044,10 +1038,35 @@ private void RegisterOverrideTasks(ILoggingService loggingServices, BuildEventCo
10441038 /// </summary>
10451039 private void LoadAndRegisterFromTasksFile ( string [ ] defaultTaskFiles , ILoggingService loggingServices , BuildEventContext buildEventContext , string taskFileError , ProjectRootElementCacheBase projectRootElementCache , TaskRegistry registry )
10461040 {
1047- foreach ( string defaultTasksFile in defaultTaskFiles )
1041+ string currentTasksFile = null ;
1042+ try
10481043 {
1049- try
1044+ TaskRegistry . InitializeTaskRegistryFromUsingTaskElements < ProjectPropertyInstance , ProjectItemInstance > (
1045+ loggingServices ,
1046+ buildEventContext ,
1047+ EnumerateTasksRegistrations ( ) ,
1048+ registry ,
1049+ _expander ,
1050+ ExpanderOptions . ExpandProperties ,
1051+ FileSystems . Default ) ;
1052+ }
1053+ catch ( XmlException e )
1054+ {
1055+ // handle XML errors in the default tasks file
1056+ ProjectFileErrorUtilities . ThrowInvalidProjectFile ( new BuildEventFileInfo ( currentTasksFile , e ) ,
1057+ taskFileError , e . Message ) ;
1058+ }
1059+ catch ( Exception e ) when ( ExceptionHandling . IsIoRelatedException ( e ) )
1060+ {
1061+ loggingServices . LogError ( buildEventContext , new BuildEventFileInfo ( currentTasksFile ) ,
1062+ taskFileError , e . Message ) ;
1063+ }
1064+
1065+ IEnumerable < ( ProjectUsingTaskElement projectUsingTaskXml , string directoryOfImportingFile ) > EnumerateTasksRegistrations ( )
1066+ {
1067+ foreach ( string defaultTasksFile in defaultTaskFiles )
10501068 {
1069+ currentTasksFile = defaultTasksFile ;
10511070 // Important to keep the following line since unit tests use the delegate.
10521071 ProjectRootElement projectRootElement ;
10531072 if ( _loadXmlFromPath != null )
@@ -1074,27 +1093,9 @@ private void LoadAndRegisterFromTasksFile(string[] defaultTaskFiles, ILoggingSer
10741093 elementXml . XmlElement . Name ) ;
10751094 }
10761095
1077- TaskRegistry . RegisterTasksFromUsingTaskElement < ProjectPropertyInstance , ProjectItemInstance > (
1078- loggingServices ,
1079- buildEventContext ,
1080- Path . GetDirectoryName ( defaultTasksFile ) ,
1081- usingTask ,
1082- registry ,
1083- _expander ,
1084- ExpanderOptions . ExpandProperties ,
1085- FileSystems . Default ) ;
1096+ yield return ( usingTask , Path . GetDirectoryName ( defaultTasksFile ) ) ;
10861097 }
10871098 }
1088- catch ( XmlException e )
1089- {
1090- // handle XML errors in the default tasks file
1091- ProjectFileErrorUtilities . ThrowInvalidProjectFile ( new BuildEventFileInfo ( defaultTasksFile , e ) , taskFileError , e . Message ) ;
1092- }
1093- catch ( Exception e ) when ( ExceptionHandling . IsIoRelatedException ( e ) )
1094- {
1095- loggingServices . LogError ( buildEventContext , new BuildEventFileInfo ( defaultTasksFile ) , taskFileError , e . Message ) ;
1096- break ;
1097- }
10981099 }
10991100 }
11001101 }
0 commit comments