diff --git a/context.go b/context.go index 96946d4..f3b5c2c 100644 --- a/context.go +++ b/context.go @@ -106,16 +106,8 @@ type localBuildActions struct { } type moduleGroup struct { - // set during Parse - typeName string - ninjaName string - relBlueprintsFile string - pos scanner.Position - propertyPos map[string]scanner.Position - properties struct { - Name string - Deps []string - } + name string + ninjaName string modules []*moduleInfo @@ -131,6 +123,16 @@ type moduleGroup struct { } type moduleInfo struct { + // set during Parse + typeName string + relBlueprintsFile string + pos scanner.Position + propertyPos map[string]scanner.Position + properties struct { + Name string + Deps []string + } + name []subName logicModule Module group *moduleGroup @@ -663,12 +665,11 @@ func (c *Context) createVariants(origModule *moduleInfo, mutatorName string, newModules := []*moduleInfo{} origVariantName := origModule.name - group := origModule.group var errs []error for i, variantName := range variantNames { - typeName := group.typeName + typeName := origModule.typeName factory, ok := c.moduleFactories[typeName] if !ok { panic(fmt.Sprintf("unrecognized module type %q during cloning", typeName)) @@ -683,14 +684,14 @@ func (c *Context) createVariants(origModule *moduleInfo, mutatorName string, newProperties = origModule.moduleProperties } else { props := []interface{}{ - &group.properties, + &origModule.properties, } newLogicModule, newProperties = factory() newProperties = append(props, newProperties...) if len(newProperties) != len(origModule.moduleProperties) { - panic("mismatched properties array length in " + group.properties.Name) + panic("mismatched properties array length in " + origModule.properties.Name) } for i := range newProperties { @@ -708,13 +709,12 @@ func (c *Context) createVariants(origModule *moduleInfo, mutatorName string, } newVariantName = append(newVariantName, newSubName) - newModule := &moduleInfo{ - group: group, - directDeps: append([]*moduleInfo(nil), origModule.directDeps...), - logicModule: newLogicModule, - name: newVariantName, - moduleProperties: newProperties, - } + m := *origModule + newModule := &m + newModule.directDeps = append([]*moduleInfo(nil), origModule.directDeps...) + newModule.logicModule = newLogicModule + newModule.name = newVariantName + newModule.moduleProperties = newProperties newModules = append(newModules, newModule) c.moduleInfo[newModule.logicModule] = newModule @@ -747,9 +747,9 @@ func (c *Context) convertDepsToVariant(module *moduleInfo, newSubName subName) ( if newDep == nil { errs = append(errs, &Error{ Err: fmt.Errorf("failed to find variant %q for module %q needed by %q", - newSubName.variantName, dep.group.properties.Name, - module.group.properties.Name), - Pos: module.group.pos, + newSubName.variantName, dep.properties.Name, + module.properties.Name), + Pos: module.pos, }) continue } @@ -779,67 +779,69 @@ func (c *Context) processModuleDef(moduleDef *parser.Module, } logicModule, properties := factory() - group := &moduleGroup{ + + module := &moduleInfo{ + logicModule: logicModule, typeName: typeName, relBlueprintsFile: relBlueprintsFile, } props := []interface{}{ - &group.properties, + &module.properties, } properties = append(props, properties...) + module.moduleProperties = properties propertyMap, errs := unpackProperties(moduleDef.Properties, properties...) if len(errs) > 0 { return nil, errs } - ninjaName := toNinjaName(group.properties.Name) - - // The sanitizing in toNinjaName can result in collisions, uniquify the name if it - // already exists - for i := 0; c.moduleNinjaNames[ninjaName] != nil; i++ { - ninjaName = toNinjaName(group.properties.Name) + strconv.Itoa(i) - } - - c.moduleNinjaNames[ninjaName] = group - group.ninjaName = ninjaName - - group.pos = moduleDef.Type.Pos - group.propertyPos = make(map[string]scanner.Position) + module.pos = moduleDef.Type.Pos + module.propertyPos = make(map[string]scanner.Position) for name, propertyDef := range propertyMap { - group.propertyPos[name] = propertyDef.Pos + module.propertyPos[name] = propertyDef.Pos } - module := &moduleInfo{ - group: group, - logicModule: logicModule, - moduleProperties: properties, - } - group.modules = []*moduleInfo{module} - return module, nil } func (c *Context) addModules(modules []*moduleInfo) (errs []error) { for _, module := range modules { - name := module.group.properties.Name - if first, present := c.moduleGroups[name]; present { + name := module.properties.Name + c.moduleInfo[module.logicModule] = module + + if group, present := c.moduleGroups[name]; present { errs = append(errs, []error{ &Error{ Err: fmt.Errorf("module %q already defined", name), - Pos: module.group.pos, + Pos: module.pos, }, &Error{ Err: fmt.Errorf("<-- previous definition here"), - Pos: first.pos, + Pos: group.modules[0].pos, }, }...) continue - } + } else { + ninjaName := toNinjaName(module.properties.Name) - c.moduleGroups[name] = module.group - c.moduleInfo[module.logicModule] = module + // The sanitizing in toNinjaName can result in collisions, uniquify the name if it + // already exists + for i := 0; c.moduleNinjaNames[ninjaName] != nil; i++ { + ninjaName = toNinjaName(module.properties.Name) + strconv.Itoa(i) + } + + c.moduleNinjaNames[ninjaName] = group + + group := &moduleGroup{ + name: module.properties.Name, + ninjaName: ninjaName, + modules: []*moduleInfo{module}, + } + module.group = group + c.moduleGroups[name] = group + } } return errs @@ -873,29 +875,26 @@ func (c *Context) ResolveDependencies(config interface{}) []error { // this set consists of the union of those module names listed in its "deps" // property and those returned by its DynamicDependencies method. Otherwise it // is simply those names listed in its "deps" property. -func (c *Context) moduleDepNames(group *moduleGroup, +func (c *Context) moduleDepNames(module *moduleInfo, config interface{}) ([]string, []error) { depNamesSet := make(map[string]bool) depNames := []string{} - for _, depName := range group.properties.Deps { + for _, depName := range module.properties.Deps { if !depNamesSet[depName] { depNamesSet[depName] = true depNames = append(depNames, depName) } } - if len(group.modules) != 1 { - panic("expected a single module during moduleDepNames") - } - logicModule := group.modules[0].logicModule + logicModule := module.logicModule dynamicDepender, ok := logicModule.(DynamicDependerModule) if ok { ddmctx := &baseModuleContext{ context: c, config: config, - group: group, + module: module, } dynamicDeps := dynamicDepender.DynamicDependencies(ddmctx) @@ -920,23 +919,22 @@ func (c *Context) moduleDepNames(group *moduleGroup, // modules. func (c *Context) resolveDependencies(config interface{}) (errs []error) { for _, group := range c.moduleGroups { - depNames, newErrs := c.moduleDepNames(group, config) - if len(newErrs) > 0 { - errs = append(errs, newErrs...) - continue - } - - if len(group.modules) != 1 { - panic("expected a single module in resolveDependencies") - } - group.modules[0].directDeps = make([]*moduleInfo, 0, len(depNames)) - - for _, depName := range depNames { - newErrs := c.addDependency(group.modules[0], depName) + for _, module := range group.modules { + depNames, newErrs := c.moduleDepNames(module, config) if len(newErrs) > 0 { errs = append(errs, newErrs...) continue } + + module.directDeps = make([]*moduleInfo, 0, len(depNames)) + + for _, depName := range depNames { + newErrs := c.addDependency(module, depName) + if len(newErrs) > 0 { + errs = append(errs, newErrs...) + continue + } + } } } @@ -944,9 +942,9 @@ func (c *Context) resolveDependencies(config interface{}) (errs []error) { } func (c *Context) addDependency(module *moduleInfo, depName string) []error { - depsPos := module.group.propertyPos["deps"] + depsPos := module.propertyPos["deps"] - if depName == module.group.properties.Name { + if depName == module.properties.Name { return []error{&Error{ Err: fmt.Errorf("%q depends on itself", depName), Pos: depsPos, @@ -957,14 +955,14 @@ func (c *Context) addDependency(module *moduleInfo, depName string) []error { if !ok { return []error{&Error{ Err: fmt.Errorf("%q depends on undefined module %q", - module.group.properties.Name, depName), + module.properties.Name, depName), Pos: depsPos, }} } if len(depInfo.modules) != 1 { panic(fmt.Sprintf("cannot add dependency from %s to %s, it already has multiple variants", - module.group.properties.Name, depInfo.properties.Name)) + module.properties.Name, depInfo.modules[0].properties.Name)) } module.directDeps = append(module.directDeps, depInfo.modules[0]) @@ -1035,7 +1033,7 @@ func (c *Context) updateDependencies() (errs []error) { // their own module to the list. errs = append(errs, &Error{ Err: fmt.Errorf("encountered dependency cycle:"), - Pos: cycle[len(cycle)-1].pos, + Pos: cycle[len(cycle)-1].modules[0].pos, }) // Iterate backwards through the cycle list. @@ -1044,9 +1042,9 @@ func (c *Context) updateDependencies() (errs []error) { nextGroup := cycle[i] errs = append(errs, &Error{ Err: fmt.Errorf(" %q depends on %q", - curGroup.properties.Name, - nextGroup.properties.Name), - Pos: curGroup.propertyPos["deps"], + curGroup.name, + nextGroup.name), + Pos: curGroup.modules[0].propertyPos["deps"], }) curGroup = nextGroup } @@ -1214,10 +1212,9 @@ func (c *Context) runTopDownMutator(config interface{}, baseModuleContext: baseModuleContext{ context: c, config: config, - group: group, + module: module, }, - module: module, - name: name, + name: name, } mutator(mctx) @@ -1244,10 +1241,9 @@ func (c *Context) runBottomUpMutator(config interface{}, baseModuleContext: baseModuleContext{ context: c, config: config, - group: group, + module: module, }, - module: module, - name: name, + name: name, } mutator(mctx) @@ -1332,10 +1328,9 @@ func (c *Context) generateModuleBuildActions(config interface{}, baseModuleContext: baseModuleContext{ context: c, config: config, - group: group, + module: module, }, - module: module, - scope: scope, + scope: scope, } mctx.module.logicModule.GenerateBuildActions(mctx) @@ -2005,8 +2000,8 @@ func (s moduleGroupSorter) Len() int { } func (s moduleGroupSorter) Less(i, j int) bool { - iName := s[i].properties.Name - jName := s[j].properties.Name + iName := s[i].name + jName := s[j].name return iName < jName } @@ -2036,17 +2031,17 @@ func (c *Context) writeAllModuleActions(nw *ninjaWriter) error { // In order to make the bootstrap build manifest independent of the // build dir we need to output the Blueprints file locations in the // comments as paths relative to the source directory. - relPos := info.pos - relPos.Filename = info.relBlueprintsFile + relPos := info.modules[0].pos + relPos.Filename = info.modules[0].relBlueprintsFile // Get the name and location of the factory function for the module. - factory := c.moduleFactories[info.typeName] + factory := c.moduleFactories[info.modules[0].typeName] factoryFunc := runtime.FuncForPC(reflect.ValueOf(factory).Pointer()) factoryName := factoryFunc.Name() infoMap := map[string]interface{}{ - "properties": info.properties, - "typeName": info.typeName, + "properties": info.modules[0].properties, + "typeName": info.modules[0].typeName, "goFactory": factoryName, "pos": relPos, } diff --git a/module_ctx.go b/module_ctx.go index 4f65a8d..ac80d03 100644 --- a/module_ctx.go +++ b/module_ctx.go @@ -149,21 +149,21 @@ var _ BaseModuleContext = (*baseModuleContext)(nil) type baseModuleContext struct { context *Context config interface{} - group *moduleGroup + module *moduleInfo errs []error } func (d *baseModuleContext) ModuleName() string { - return d.group.properties.Name + return d.module.properties.Name } func (d *baseModuleContext) ContainsProperty(name string) bool { - _, ok := d.group.propertyPos[name] + _, ok := d.module.propertyPos[name] return ok } func (d *baseModuleContext) ModuleDir() string { - return filepath.Dir(d.group.relBlueprintsFile) + return filepath.Dir(d.module.relBlueprintsFile) } func (d *baseModuleContext) Config() interface{} { @@ -184,14 +184,14 @@ func (d *baseModuleContext) ModuleErrorf(format string, d.errs = append(d.errs, &Error{ Err: fmt.Errorf(format, args...), - Pos: d.group.pos, + Pos: d.module.pos, }) } func (d *baseModuleContext) PropertyErrorf(property, format string, args ...interface{}) { - pos, ok := d.group.propertyPos[property] + pos, ok := d.module.propertyPos[property] if !ok { panic(fmt.Errorf("property %q was not set for this module", property)) } @@ -210,24 +210,23 @@ var _ ModuleContext = (*moduleContext)(nil) type moduleContext struct { baseModuleContext - module *moduleInfo scope *localScope ninjaFileDeps []string actionDefs localBuildActions } -func (m *moduleContext) OtherModuleName(module Module) string { - info := m.context.moduleInfo[module] - return info.group.properties.Name +func (m *moduleContext) OtherModuleName(logicModule Module) string { + module := m.context.moduleInfo[logicModule] + return module.properties.Name } -func (m *moduleContext) OtherModuleErrorf(module Module, format string, +func (m *moduleContext) OtherModuleErrorf(logicModule Module, format string, args ...interface{}) { - info := m.context.moduleInfo[module] + module := m.context.moduleInfo[logicModule] m.errs = append(m.errs, &Error{ Err: fmt.Errorf(format, args...), - Pos: info.group.pos, + Pos: module.pos, }) } @@ -314,7 +313,6 @@ func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) { type mutatorContext struct { baseModuleContext - module *moduleInfo name string dependenciesModified bool } diff --git a/singleton_ctx.go b/singleton_ctx.go index 1426ff9..c9cfc8c 100644 --- a/singleton_ctx.go +++ b/singleton_ctx.go @@ -72,17 +72,17 @@ func (s *singletonContext) Config() interface{} { func (s *singletonContext) ModuleName(logicModule Module) string { module := s.context.moduleInfo[logicModule] - return module.group.properties.Name + return module.properties.Name } func (s *singletonContext) ModuleDir(logicModule Module) string { module := s.context.moduleInfo[logicModule] - return filepath.Dir(module.group.relBlueprintsFile) + return filepath.Dir(module.relBlueprintsFile) } func (s *singletonContext) BlueprintFile(logicModule Module) string { module := s.context.moduleInfo[logicModule] - return module.group.relBlueprintsFile + return module.relBlueprintsFile } func (s *singletonContext) ModuleErrorf(logicModule Module, format string, @@ -91,7 +91,7 @@ func (s *singletonContext) ModuleErrorf(logicModule Module, format string, module := s.context.moduleInfo[logicModule] s.errs = append(s.errs, &Error{ Err: fmt.Errorf(format, args...), - Pos: module.group.pos, + Pos: module.pos, }) }