aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2019-10-07 14:20:11 -0700
committerRob Mensching <rob@firegiant.com>2019-10-07 21:44:46 -0700
commit3a2c3c799eead15c26f5d65d16e6e01b4a0e8c64 (patch)
treedeadf39b60bcf8591fd4a71fb59dfe3a7169e28a /src
parentd3b12de2f22eb552e073f0c949833a7ef4d4f13c (diff)
downloadwix-3a2c3c799eead15c26f5d65d16e6e01b4a0e8c64.tar.gz
wix-3a2c3c799eead15c26f5d65d16e6e01b4a0e8c64.tar.bz2
wix-3a2c3c799eead15c26f5d65d16e6e01b4a0e8c64.zip
Fix Feature parent
Diffstat (limited to 'src')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs1
-rw-r--r--src/WixToolset.Core/Compiler.cs43
-rw-r--r--src/WixToolset.Core/Linker.cs402
-rw-r--r--src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs4
4 files changed, 206 insertions, 244 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
index 170b138d..75a694d1 100644
--- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
@@ -185,6 +185,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
185 case TupleDefinitionType.WixFile: 185 case TupleDefinitionType.WixFile:
186 case TupleDefinitionType.WixComponentGroup: 186 case TupleDefinitionType.WixComponentGroup:
187 case TupleDefinitionType.WixDeltaPatchFile: 187 case TupleDefinitionType.WixDeltaPatchFile:
188 case TupleDefinitionType.WixFeatureGroup:
188 break; 189 break;
189 190
190 default: 191 default:
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs
index c4bbf86d..7f078dbc 100644
--- a/src/WixToolset.Core/Compiler.cs
+++ b/src/WixToolset.Core/Compiler.cs
@@ -4855,6 +4855,7 @@ namespace WixToolset.Core
4855 { 4855 {
4856 var tuple = new FeatureTuple(sourceLineNumbers, id) 4856 var tuple = new FeatureTuple(sourceLineNumbers, id)
4857 { 4857 {
4858 ParentFeatureRef = null, // this field is set in the linker
4858 Title = title, 4859 Title = title,
4859 Description = description, 4860 Description = description,
4860 Display = display, 4861 Display = display,
@@ -4867,46 +4868,6 @@ namespace WixToolset.Core
4867 }; 4868 };
4868 4869
4869 this.Core.AddTuple(tuple); 4870 this.Core.AddTuple(tuple);
4870 //var row = this.Core.CreateRow(sourceLineNumbers, TupleDefinitionType.Feature, id);
4871 //// row.Set(1, null); - this column is set in the linker
4872 //row.Set(2, title);
4873 //row.Set(3, description);
4874 //if (0 < display.Length)
4875 //{
4876 // switch (display)
4877 // {
4878 // case "collapse":
4879 // lastDisplay = (lastDisplay | 1) + 1;
4880 // row.Set(4, lastDisplay);
4881 // break;
4882 // case "expand":
4883 // lastDisplay = (lastDisplay + 1) | 1;
4884 // row.Set(4, lastDisplay);
4885 // break;
4886 // case "hidden":
4887 // row.Set(4, 0);
4888 // break;
4889 // default:
4890 // int value;
4891 // if (!Int32.TryParse(display, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
4892 // {
4893 // this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, "Display", display, "collapse", "expand", "hidden"));
4894 // }
4895 // else
4896 // {
4897 // row.Set(4, value);
4898 // // save the display value of this row (if its not hidden) for subsequent rows
4899 // if (0 != (int)row[4])
4900 // {
4901 // lastDisplay = (int)row[4];
4902 // }
4903 // }
4904 // break;
4905 // }
4906 //}
4907 //row.Set(5, level);
4908 //row.Set(6, configurableDirectory);
4909 //row.Set(7, bits);
4910 4871
4911 if (ComplexReferenceParentType.Unknown != parentType) 4872 if (ComplexReferenceParentType.Unknown != parentType)
4912 { 4873 {
@@ -6228,7 +6189,7 @@ namespace WixToolset.Core
6228 this.ParseFeatureElement(child, ComplexReferenceParentType.Unknown, null, ref featureDisplay); 6189 this.ParseFeatureElement(child, ComplexReferenceParentType.Unknown, null, ref featureDisplay);
6229 break; 6190 break;
6230 case "FeatureGroup": 6191 case "FeatureGroup":
6231 this.ParseFeatureGroupElement(child, ComplexReferenceParentType.Unknown, id.Id); 6192 this.ParseFeatureGroupElement(child, ComplexReferenceParentType.Unknown, id?.Id);
6232 break; 6193 break;
6233 case "FeatureRef": 6194 case "FeatureRef":
6234 this.ParseFeatureRefElement(child, ComplexReferenceParentType.Unknown, null); 6195 this.ParseFeatureRefElement(child, ComplexReferenceParentType.Unknown, null);
diff --git a/src/WixToolset.Core/Linker.cs b/src/WixToolset.Core/Linker.cs
index 1f28802b..9526ac95 100644
--- a/src/WixToolset.Core/Linker.cs
+++ b/src/WixToolset.Core/Linker.cs
@@ -244,12 +244,12 @@ namespace WixToolset.Core
244 break; 244 break;
245#endif 245#endif
246 246
247 case TupleDefinitionType.Class: 247 case TupleDefinitionType.Class:
248 if (SectionType.Product == resolvedSection.Type) 248 if (SectionType.Product == resolvedSection.Type)
249 { 249 {
250 this.ResolveFeatures(tuple, 2, 11, componentsToFeatures, multipleFeatureComponents); 250 this.ResolveFeatures(tuple, 2, 11, componentsToFeatures, multipleFeatureComponents);
251 } 251 }
252 break; 252 break;
253 253
254#if MOVE_TO_BACKEND 254#if MOVE_TO_BACKEND
255 case "CustomAction": 255 case "CustomAction":
@@ -303,12 +303,12 @@ namespace WixToolset.Core
303 } 303 }
304 break; 304 break;
305#endif 305#endif
306 case TupleDefinitionType.Extension: 306 case TupleDefinitionType.Extension:
307 if (SectionType.Product == resolvedSection.Type) 307 if (SectionType.Product == resolvedSection.Type)
308 { 308 {
309 this.ResolveFeatures(tuple, 1, 4, componentsToFeatures, multipleFeatureComponents); 309 this.ResolveFeatures(tuple, 1, 4, componentsToFeatures, multipleFeatureComponents);
310 } 310 }
311 break; 311 break;
312 312
313#if MOVE_TO_BACKEND 313#if MOVE_TO_BACKEND
314 case TupleDefinitionType.ModuleSubstitution: 314 case TupleDefinitionType.ModuleSubstitution:
@@ -320,12 +320,12 @@ namespace WixToolset.Core
320 break; 320 break;
321#endif 321#endif
322 322
323 case TupleDefinitionType.Assembly: 323 case TupleDefinitionType.Assembly:
324 if (SectionType.Product == resolvedSection.Type) 324 if (SectionType.Product == resolvedSection.Type)
325 { 325 {
326 this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents); 326 this.ResolveFeatures(tuple, 0, 1, componentsToFeatures, multipleFeatureComponents);
327 } 327 }
328 break; 328 break;
329 329
330#if MOVE_TO_BACKEND 330#if MOVE_TO_BACKEND
331 case "ProgId": 331 case "ProgId":
@@ -347,26 +347,26 @@ namespace WixToolset.Core
347 break; 347 break;
348#endif 348#endif
349 349
350 case TupleDefinitionType.PublishComponent: 350 case TupleDefinitionType.PublishComponent:
351 if (SectionType.Product == resolvedSection.Type) 351 if (SectionType.Product == resolvedSection.Type)
352 { 352 {
353 this.ResolveFeatures(tuple, 2, 4, componentsToFeatures, multipleFeatureComponents); 353 this.ResolveFeatures(tuple, 2, 4, componentsToFeatures, multipleFeatureComponents);
354 } 354 }
355 break; 355 break;
356 356
357 case TupleDefinitionType.Shortcut: 357 case TupleDefinitionType.Shortcut:
358 if (SectionType.Product == resolvedSection.Type) 358 if (SectionType.Product == resolvedSection.Type)
359 { 359 {
360 this.ResolveFeatures(tuple, 3, 4, componentsToFeatures, multipleFeatureComponents); 360 this.ResolveFeatures(tuple, 3, 4, componentsToFeatures, multipleFeatureComponents);
361 } 361 }
362 break; 362 break;
363 363
364 case TupleDefinitionType.TypeLib: 364 case TupleDefinitionType.TypeLib:
365 if (SectionType.Product == resolvedSection.Type) 365 if (SectionType.Product == resolvedSection.Type)
366 { 366 {
367 this.ResolveFeatures(tuple, 2, 6, componentsToFeatures, multipleFeatureComponents); 367 this.ResolveFeatures(tuple, 2, 6, componentsToFeatures, multipleFeatureComponents);
368 } 368 }
369 break; 369 break;
370 370
371#if SOLVE_CUSTOM_TABLE 371#if SOLVE_CUSTOM_TABLE
372 case "WixCustomTable": 372 case "WixCustomTable":
@@ -384,9 +384,9 @@ namespace WixToolset.Core
384 break; 384 break;
385#endif 385#endif
386 386
387 case TupleDefinitionType.WixEnsureTable: 387 case TupleDefinitionType.WixEnsureTable:
388 ensureTableRows.Add(tuple); 388 ensureTableRows.Add(tuple);
389 break; 389 break;
390 390
391 391
392#if MOVE_TO_BACKEND 392#if MOVE_TO_BACKEND
@@ -409,46 +409,46 @@ namespace WixToolset.Core
409 break; 409 break;
410#endif 410#endif
411 411
412 case TupleDefinitionType.WixMerge: 412 case TupleDefinitionType.WixMerge:
413 if (SectionType.Product == resolvedSection.Type) 413 if (SectionType.Product == resolvedSection.Type)
414 { 414 {
415 this.ResolveFeatures(tuple, 0, 7, modulesToFeatures, null); 415 this.ResolveFeatures(tuple, 0, 7, modulesToFeatures, null);
416 } 416 }
417 break; 417 break;
418
419 case TupleDefinitionType.WixComplexReference:
420 copyTuple = false;
421 break;
422 418
423 case TupleDefinitionType.WixSimpleReference: 419 case TupleDefinitionType.WixComplexReference:
424 copyTuple = false; 420 copyTuple = false;
425 break; 421 break;
426 422
427 case TupleDefinitionType.WixVariable: 423 case TupleDefinitionType.WixSimpleReference:
428 // check for colliding values and collect the wix variable rows 424 copyTuple = false;
429 { 425 break;
430 var row = (WixVariableTuple)tuple;
431 var id = row.Id.Id;
432 426
433 if (wixVariables.TryGetValue(id, out var collidingRow)) 427 case TupleDefinitionType.WixVariable:
428 // check for colliding values and collect the wix variable rows
434 { 429 {
435 if (collidingRow.Overridable && !row.Overridable) 430 var row = (WixVariableTuple)tuple;
431 var id = row.Id.Id;
432
433 if (wixVariables.TryGetValue(id, out var collidingRow))
436 { 434 {
437 wixVariables[id] = row; 435 if (collidingRow.Overridable && !row.Overridable)
436 {
437 wixVariables[id] = row;
438 }
439 else if (!row.Overridable || (collidingRow.Overridable && row.Overridable))
440 {
441 this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, id));
442 }
438 } 443 }
439 else if (!row.Overridable || (collidingRow.Overridable && row.Overridable)) 444 else
440 { 445 {
441 this.OnMessage(ErrorMessages.WixVariableCollision(row.SourceLineNumbers, id)); 446 wixVariables.Add(id, row);
442 } 447 }
443 } 448 }
444 else
445 {
446 wixVariables.Add(id, row);
447 }
448 }
449 449
450 copyTuple = false; 450 copyTuple = false;
451 break; 451 break;
452 } 452 }
453 453
454 if (copyTuple) 454 if (copyTuple)
@@ -1152,154 +1152,154 @@ namespace WixToolset.Core
1152 ConnectToFeature connection; 1152 ConnectToFeature connection;
1153 switch (wixComplexReferenceRow.ParentType) 1153 switch (wixComplexReferenceRow.ParentType)
1154 { 1154 {
1155 case ComplexReferenceParentType.Feature: 1155 case ComplexReferenceParentType.Feature:
1156 switch (wixComplexReferenceRow.ChildType) 1156 switch (wixComplexReferenceRow.ChildType)
1157 {
1158 case ComplexReferenceChildType.Component:
1159 connection = componentsToFeatures[wixComplexReferenceRow.Child];
1160 if (null == connection)
1161 {
1162 componentsToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary));
1163 }
1164 else if (wixComplexReferenceRow.IsPrimary)
1165 { 1157 {
1166 if (connection.IsExplicitPrimaryFeature) 1158 case ComplexReferenceChildType.Component:
1167 { 1159 connection = componentsToFeatures[wixComplexReferenceRow.Child];
1168 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), connection.PrimaryFeature ?? resolvedSection.Id)); 1160 if (null == connection)
1169 continue; 1161 {
1170 } 1162 componentsToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary));
1171 else 1163 }
1172 { 1164 else if (wixComplexReferenceRow.IsPrimary)
1173 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects 1165 {
1174 connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature 1166 if (connection.IsExplicitPrimaryFeature)
1175 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again 1167 {
1176 } 1168 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), connection.PrimaryFeature ?? resolvedSection.Id));
1177 } 1169 continue;
1178 else 1170 }
1179 { 1171 else
1180 connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent); 1172 {
1181 } 1173 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
1174 connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature
1175 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
1176 }
1177 }
1178 else
1179 {
1180 connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent);
1181 }
1182 1182
1183 // add a row to the FeatureComponents table 1183 // add a row to the FeatureComponents table
1184 var featureComponent = new FeatureComponentsTuple(); 1184 var featureComponent = new FeatureComponentsTuple();
1185 featureComponent.FeatureRef = wixComplexReferenceRow.Parent; 1185 featureComponent.FeatureRef = wixComplexReferenceRow.Parent;
1186 featureComponent.ComponentRef = wixComplexReferenceRow.Child; 1186 featureComponent.ComponentRef = wixComplexReferenceRow.Child;
1187 1187
1188 featureComponents.Add(featureComponent); 1188 featureComponents.Add(featureComponent);
1189 1189
1190 // index the component for finding orphaned records 1190 // index the component for finding orphaned records
1191 var symbolName = String.Concat("Component:", wixComplexReferenceRow.Child); 1191 var symbolName = String.Concat("Component:", wixComplexReferenceRow.Child);
1192 referencedComponents.Add(symbolName); 1192 referencedComponents.Add(symbolName);
1193 1193
1194 break; 1194 break;
1195 1195
1196 case ComplexReferenceChildType.Feature: 1196 case ComplexReferenceChildType.Feature:
1197 connection = featuresToFeatures[wixComplexReferenceRow.Child]; 1197 connection = featuresToFeatures[wixComplexReferenceRow.Child];
1198 if (null != connection) 1198 if (null != connection)
1199 { 1199 {
1200 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); 1200 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
1201 continue; 1201 continue;
1202 } 1202 }
1203 1203
1204 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); 1204 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary));
1205 break; 1205 break;
1206 1206
1207 case ComplexReferenceChildType.Module: 1207 case ComplexReferenceChildType.Module:
1208 connection = modulesToFeatures[wixComplexReferenceRow.Child]; 1208 connection = modulesToFeatures[wixComplexReferenceRow.Child];
1209 if (null == connection) 1209 if (null == connection)
1210 { 1210 {
1211 modulesToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary)); 1211 modulesToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, wixComplexReferenceRow.Parent, wixComplexReferenceRow.IsPrimary));
1212 } 1212 }
1213 else if (wixComplexReferenceRow.IsPrimary) 1213 else if (wixComplexReferenceRow.IsPrimary)
1214 { 1214 {
1215 if (connection.IsExplicitPrimaryFeature) 1215 if (connection.IsExplicitPrimaryFeature)
1216 { 1216 {
1217 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); 1217 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
1218 continue; 1218 continue;
1219 } 1219 }
1220 else 1220 else
1221 { 1221 {
1222 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects 1222 connection.ConnectFeatures.Add(connection.PrimaryFeature); // move the guessed primary feature to the list of connects
1223 connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature 1223 connection.PrimaryFeature = wixComplexReferenceRow.Parent; // set the new primary feature
1224 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again 1224 connection.IsExplicitPrimaryFeature = true; // and make sure we remember that we set it so we can fail if we try to set it again
1225 } 1225 }
1226 } 1226 }
1227 else 1227 else
1228 { 1228 {
1229 connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent); 1229 connection.ConnectFeatures.Add(wixComplexReferenceRow.Parent);
1230 }
1231 break;
1232
1233 default:
1234 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1230 } 1235 }
1231 break; 1236 break;
1232 1237
1233 default: 1238 case ComplexReferenceParentType.Module:
1234 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1239 switch (wixComplexReferenceRow.ChildType)
1235 }
1236 break;
1237
1238 case ComplexReferenceParentType.Module:
1239 switch (wixComplexReferenceRow.ChildType)
1240 {
1241 case ComplexReferenceChildType.Component:
1242 if (componentsToModules.ContainsKey(wixComplexReferenceRow.Child))
1243 {
1244 this.OnMessage(ErrorMessages.ComponentReferencedTwice(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.Child));
1245 continue;
1246 }
1247 else
1248 { 1240 {
1249 componentsToModules.Add(wixComplexReferenceRow.Child, wixComplexReferenceRow); // should always be new 1241 case ComplexReferenceChildType.Component:
1242 if (componentsToModules.ContainsKey(wixComplexReferenceRow.Child))
1243 {
1244 this.OnMessage(ErrorMessages.ComponentReferencedTwice(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.Child));
1245 continue;
1246 }
1247 else
1248 {
1249 componentsToModules.Add(wixComplexReferenceRow.Child, wixComplexReferenceRow); // should always be new
1250 1250
1251 // add a row to the ModuleComponents table 1251 // add a row to the ModuleComponents table
1252 var moduleComponent = new ModuleComponentsTuple(); 1252 var moduleComponent = new ModuleComponentsTuple();
1253 moduleComponent.Component = wixComplexReferenceRow.Child; 1253 moduleComponent.Component = wixComplexReferenceRow.Child;
1254 moduleComponent.ModuleID = wixComplexReferenceRow.Parent; 1254 moduleComponent.ModuleID = wixComplexReferenceRow.Parent;
1255 moduleComponent.Language = Convert.ToInt32(wixComplexReferenceRow.ParentLanguage); 1255 moduleComponent.Language = Convert.ToInt32(wixComplexReferenceRow.ParentLanguage);
1256 } 1256 }
1257
1258 // index the component for finding orphaned records
1259 var componentSymbolName = String.Concat("Component:", wixComplexReferenceRow.Child);
1260 referencedComponents.Add(componentSymbolName);
1257 1261
1258 // index the component for finding orphaned records 1262 break;
1259 var componentSymbolName = String.Concat("Component:", wixComplexReferenceRow.Child);
1260 referencedComponents.Add(componentSymbolName);
1261 1263
1264 default:
1265 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1266 }
1262 break; 1267 break;
1263 1268
1264 default: 1269 case ComplexReferenceParentType.Patch:
1265 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1270 switch (wixComplexReferenceRow.ChildType)
1266 } 1271 {
1267 break; 1272 case ComplexReferenceChildType.PatchFamily:
1273 case ComplexReferenceChildType.PatchFamilyGroup:
1274 break;
1268 1275
1269 case ComplexReferenceParentType.Patch: 1276 default:
1270 switch (wixComplexReferenceRow.ChildType) 1277 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1271 { 1278 }
1272 case ComplexReferenceChildType.PatchFamily:
1273 case ComplexReferenceChildType.PatchFamilyGroup:
1274 break; 1279 break;
1275 1280
1276 default: 1281 case ComplexReferenceParentType.Product:
1277 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1282 switch (wixComplexReferenceRow.ChildType)
1278 }
1279 break;
1280
1281 case ComplexReferenceParentType.Product:
1282 switch (wixComplexReferenceRow.ChildType)
1283 {
1284 case ComplexReferenceChildType.Feature:
1285 connection = featuresToFeatures[wixComplexReferenceRow.Child];
1286 if (null != connection)
1287 { 1283 {
1288 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id))); 1284 case ComplexReferenceChildType.Feature:
1289 continue; 1285 connection = featuresToFeatures[wixComplexReferenceRow.Child];
1290 } 1286 if (null != connection)
1287 {
1288 this.OnMessage(ErrorMessages.MultiplePrimaryReferences(wixComplexReferenceRow.SourceLineNumbers, wixComplexReferenceRow.ChildType.ToString(), wixComplexReferenceRow.Child, wixComplexReferenceRow.ParentType.ToString(), wixComplexReferenceRow.Parent, (null != connection.PrimaryFeature ? "Feature" : "Product"), (null != connection.PrimaryFeature ? connection.PrimaryFeature : resolvedSection.Id)));
1289 continue;
1290 }
1291
1292 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, null, wixComplexReferenceRow.IsPrimary));
1293 break;
1291 1294
1292 featuresToFeatures.Add(new ConnectToFeature(section, wixComplexReferenceRow.Child, null, wixComplexReferenceRow.IsPrimary)); 1295 default:
1296 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType)));
1297 }
1293 break; 1298 break;
1294 1299
1295 default: 1300 default:
1296 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceChildType), wixComplexReferenceRow.ChildType))); 1301 // Note: Groups have been processed before getting here so they are not handled by any case above.
1297 } 1302 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceParentType), wixComplexReferenceRow.ParentType)));
1298 break;
1299
1300 default:
1301 // Note: Groups have been processed before getting here so they are not handled by any case above.
1302 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, "Unexpected complex reference child type: {0}", Enum.GetName(typeof(ComplexReferenceParentType), wixComplexReferenceRow.ParentType)));
1303 } 1303 }
1304 } 1304 }
1305 1305
@@ -1614,7 +1614,7 @@ namespace WixToolset.Core
1614 groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Package, false); 1614 groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Package, false);
1615 groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Container, false); 1615 groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Container, false);
1616 groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Layout, false); 1616 groups.FlattenAndRewriteGroups(ComplexReferenceParentType.Layout, false);
1617 1617
1618 // Create Chain packages... 1618 // Create Chain packages...
1619 groups.UseTypes(new[] { ComplexReferenceParentType.PackageGroup }, new[] { ComplexReferenceChildType.Package, ComplexReferenceChildType.PackageGroup }); 1619 groups.UseTypes(new[] { ComplexReferenceParentType.PackageGroup }, new[] { ComplexReferenceChildType.Package, ComplexReferenceChildType.PackageGroup });
1620 groups.FlattenAndRewriteRows(ComplexReferenceChildType.PackageGroup, "WixChain", false); 1620 groups.FlattenAndRewriteRows(ComplexReferenceChildType.PackageGroup, "WixChain", false);
@@ -1631,17 +1631,17 @@ namespace WixToolset.Core
1631 { 1631 {
1632 foreach (ConnectToFeature connection in featuresToFeatures) 1632 foreach (ConnectToFeature connection in featuresToFeatures)
1633 { 1633 {
1634 var wixSimpleReferenceRow = new WixSimpleReferenceTuple(); 1634 var wixSimpleReferenceRow = new WixSimpleReferenceTuple
1635 wixSimpleReferenceRow.Table = "Feature"; 1635 {
1636 wixSimpleReferenceRow.PrimaryKeys = connection.ChildId; 1636 Table = "Feature",
1637 PrimaryKeys = connection.ChildId
1638 };
1637 1639
1638 if (!allSymbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbol)) 1640 if (allSymbols.TryGetValue(wixSimpleReferenceRow.SymbolicName, out var symbol))
1639 { 1641 {
1640 continue; 1642 var featureTuple = (FeatureTuple)symbol.Row;
1643 featureTuple.ParentFeatureRef = connection.PrimaryFeature;
1641 } 1644 }
1642
1643 var row = symbol.Row;
1644 row.Set(1, connection.PrimaryFeature);
1645 } 1645 }
1646 } 1646 }
1647 1647
diff --git a/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs b/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs
index 6ff4e237..c391abac 100644
--- a/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs
+++ b/src/test/WixToolsetTest.CoreIntegration/MsiQueryFixture.cs
@@ -217,7 +217,7 @@ namespace WixToolsetTest.CoreIntegration
217 } 217 }
218 } 218 }
219 219
220 [Fact(Skip = "Test demonstrates failure")] 220 [Fact]
221 public void PopulatesDirectoryTableWithValidDefaultDir() 221 public void PopulatesDirectoryTableWithValidDefaultDir()
222 { 222 {
223 var folder = TestData.Get(@"TestData"); 223 var folder = TestData.Get(@"TestData");
@@ -259,7 +259,7 @@ namespace WixToolsetTest.CoreIntegration
259 } 259 }
260 } 260 }
261 261
262 [Fact(Skip = "Test demonstrates failure")] 262 [Fact]
263 public void PopulatesFeatureTableWithParent() 263 public void PopulatesFeatureTableWithParent()
264 { 264 {
265 var folder = TestData.Get(@"TestData"); 265 var folder = TestData.Get(@"TestData");