コード例 #1
0
ファイル: ProjectItems.cs プロジェクト: hmmueller/Archichect
        protected override ConfigureOptions CreateConfigureOptions([NotNull] GlobalContext globalContext,
                                                                   [CanBeNull] string configureOptionsString, bool forceReload)
        {
            var           localVars          = new ValuesFrame();
            var           options            = new ConfigureOptions();
            ProjectionSet orderedProjections = null;

            _projector = null;

            Option.Parse(globalContext, configureOptionsString,
                         MatcherStrategyOption.Action((args, j) => {
                string strategy = Option.ExtractRequiredOptionValue(args, ref j, "missing strategy");
                switch (strategy)
                {
                case "S":
                    _createProjector = (p, i) => new SimpleProjector(p, name: "default projector");
                    break;

                case "PT":
                    _createProjector = (p, i) => new SelfOptimizingPrefixTrieProjector(p, i, 10000, name: "PT projector");
                    break;

                case "FL":
                    _createProjector = (p, i) => new SelfOptimizingFirstLetterProjector(p, i, 10000, name: "FL projector");
                    break;

                default:
                    Log.WriteWarning($"Unrecognized matcher optimization strategy {strategy} - using default");
                    break;
                }
                return(j);
            }), ProjectionFileOption.Action((args, j) => {
                string fullSourceName =
                    Path.GetFullPath(Option.ExtractRequiredOptionValue(args, ref j, "missing projections filename"));
                orderedProjections = GetOrReadChildConfiguration(globalContext, () => new StreamReader(fullSourceName),
                                                                 fullSourceName, globalContext.IgnoreCase, "????", forceReload, localVars);
                return(j);
            }), ProjectionsOption.Action((args, j) => {
                orderedProjections = GetOrReadChildConfiguration(globalContext,
                                                                 () => new StringReader(string.Join(Environment.NewLine, args.Skip(j + 1))),
                                                                 ProjectionsOption.ShortName, globalContext.IgnoreCase, "????", forceReload: true, localVars: localVars);
                // ... and all args are read in, so the next arg index is past every argument.
                return(int.MaxValue);
            }));

            if (orderedProjections == null || !orderedProjections.AllProjections.Any())
            {
                Log.WriteWarning("No projections defined");
                _projector = new SimpleProjector(new Projection[0], name: "empty");
                _allProjectionsForMatchCountLoggingOnly = new Projection[0];
            }
            else
            {
                _projector = _createProjector(orderedProjections.AllProjections, globalContext.IgnoreCase);
                _allProjectionsForMatchCountLoggingOnly = orderedProjections.AllProjections;
            }
            return(options);
        }
コード例 #2
0
        protected TConfiguration GetOrReadChildConfiguration([NotNull] GlobalContext globalContext,
                                                             Func <TextReader> createReader, string containerUri, bool ignoreCase, string fileIncludeStack, bool forceReload,
                                                             ValuesFrame localVars)
        {
            TConfiguration childConfiguration;

            Dictionary <string, string> previousConfigValues;

            if (_container2configValues.TryGetValue(containerUri, out previousConfigValues))
            {
                if (!forceReload)
                {
                    // Check saved names against
                    var differences = new StringBuilder();
                    foreach (var kvp in previousConfigValues)
                    {
                        string currentValue = globalContext.GetValue(kvp.Key);
                        if (currentValue != kvp.Value)
                        {
                            differences.AppendLine($"{kvp.Key}: {currentValue} vs. {kvp.Value}");
                        }
                    }
                    if (differences.Length > 0)
                    {
                        throw new ApplicationException($"File {containerUri} is read with different values:{Environment.NewLine}{differences}");
                    }
                }
                previousConfigValues = null; // no collecting of config values!
            }
            else
            {
                // Collect new config values
                _container2configValues.Add(containerUri, previousConfigValues = new Dictionary <string, string>());
            }

            if (forceReload || !_configFile2Config.TryGetValue(containerUri, out childConfiguration))
            {
                using (var tr = createReader()) {
                    childConfiguration = CreateConfigurationFromText(globalContext, containerUri, 0, tr, ignoreCase,
                                                                     fileIncludeStack + "+" + containerUri, forceReload, previousConfigValues, localVars);
                    _configFile2Config[containerUri] = childConfiguration;
                }
            }
            return(childConfiguration);
        }
コード例 #3
0
ファイル: ModifyItems.cs プロジェクト: hmmueller/Archichect
        protected override ConfigureOptions CreateConfigureOptions([NotNull] GlobalContext globalContext,
                                                                   [CanBeNull] string configureOptionsString, bool forceReload)
        {
            var localVars = new ValuesFrame();

            var options = new ConfigureOptions();

            Option.Parse(globalContext, configureOptionsString,
                         ModificationsFileOption.Action((args, j) => {
                string fullSourceName  = Path.GetFullPath(Option.ExtractRequiredOptionValue(args, ref j, "missing modifications filename"));
                options.OrderedActions = GetOrReadChildConfiguration(globalContext,
                                                                     () => new StreamReader(fullSourceName), fullSourceName, globalContext.IgnoreCase, "????", forceReload, localVars);
                return(j);
            }),
                         ModificationsOption.Action((args, j) => {
                options.OrderedActions = GetOrReadChildConfiguration(globalContext,
                                                                     () => new StringReader(string.Join(Environment.NewLine, args.Skip(j + 1))),
                                                                     ModificationsOption.ShortName, globalContext.IgnoreCase, "????", forceReload: true, localVars: localVars);
                // ... and all args are read in, so the next arg index is past every argument.
                return(int.MaxValue);
            })
                         );
            return(options);
        }
コード例 #4
0
        protected void ProcessTextInner([NotNull] GlobalContext globalContext, string fullConfigFileName, int startLineNo,
                                        TextReader tr, bool ignoreCase, string fileIncludeStack, bool forceReloadConfiguration,
                                        [NotNull] Action <TConfiguration, string> onIncludedConfiguration,
                                        [NotNull] Func <string, int, string> onLineWithLineNo,
                                        [CanBeNull] Dictionary <string, string> configValueCollector, ValuesFrame localVars)
        {
            int lineNo = startLineNo;

            for (;;)
            {
                string line = NormalizeLine(globalContext, tr.ReadLine(), configValueCollector, localVars);

                if (line == null)
                {
                    break;
                }
                lineNo++;

                try {
                    if (line == "")
                    {
                        // ignore;
                    }
                    else if (line.StartsWith("+"))
                    {
                        string         includeFilename     = line.Substring(1).Trim();
                        string         fullIncludeFileName = Path.Combine(Path.GetDirectoryName(fullConfigFileName) ?? @"\", includeFilename);
                        TConfiguration childConfiguration  = GetOrReadChildConfiguration(globalContext,
                                                                                         () => new StreamReader(fullIncludeFileName), fullIncludeFileName,
                                                                                         ignoreCase, fileIncludeStack, forceReloadConfiguration, localVars);
                        onIncludedConfiguration(childConfiguration, fullConfigFileName);
                    }
                    else if (line.Contains(ASSIGN))
                    {
                        KeyValuePair <string, string>?kvp = ParseVariableDefinition(line);
                        if (kvp != null)
                        {
                            localVars.SetDefine(kvp.Value.Key, kvp.Value.Value, $"at {fullConfigFileName}:{lineNo}");
                        }
                    }
                    else
                    {
                        string errorOrNull = onLineWithLineNo(line, lineNo);
                        // line's content has been added to result as side-effect of onLineWithLineNo(...)
                        if (errorOrNull != null)
                        {
                            throw new ApplicationException($"Cannot parse line '{line}' at {fullConfigFileName}:{lineNo}; reason: {errorOrNull}");
                        }
                    }
                } catch (Exception ex) {
                    throw new ApplicationException($"{ex.Message}{Environment.NewLine}  at {fullConfigFileName}:{lineNo}");
                }
            }
        }
コード例 #5
0
 protected string NormalizeLine([NotNull] GlobalContext globalContext, [CanBeNull] string line,
                                [CanBeNull] Dictionary <string, string> configValueCollector, ValuesFrame localVars)
 {
     if (line != null)
     {
         int commentStart = line.IndexOf("//", StringComparison.InvariantCulture);
         if (commentStart >= 0)
         {
             line = line.Substring(0, commentStart);
         }
         return(globalContext.ExpandDefinesAndHexChars(localVars.ExpandDefines(line.Trim(), null), configValueCollector).Trim());
     }
     else
     {
         return(null);
     }
 }
コード例 #6
0
 protected abstract TConfiguration CreateConfigurationFromText([NotNull] GlobalContext globalContext, string fullConfigFileName,
                                                               int startLineNo, TextReader tr, bool ignoreCase, string fileIncludeStack, bool forceReloadConfiguration,
                                                               [CanBeNull] Dictionary <string, string> configValueCollector, ValuesFrame localVars);
コード例 #7
0
ファイル: CheckDeps.cs プロジェクト: hmmueller/Archichect
        protected override DependencyRuleSet CreateConfigurationFromText([NotNull] GlobalContext globalContext,
                                                                         string fullConfigFileName, int startLineNo, TextReader tr, bool ignoreCase, string fileIncludeStack,
                                                                         bool forceReloadConfiguration, Dictionary <string, string> configValueCollector, ValuesFrame localVars)
        {
            ItemType usingItemType = null;
            ItemType usedItemType  = null;

            string ruleSourceName = fullConfigFileName;

            string previousRawUsingPattern = "";

            var ruleGroups = new List <DependencyRuleGroup>();
            var children   = new List <DependencyRuleSet>();

            DependencyRuleGroup mainRuleGroup = new DependencyRuleGroup("", globalContext.IgnoreCase, null, null, "global rule group");
            DependencyRuleGroup currentGroup  = mainRuleGroup;

            ruleGroups.Add(currentGroup);

            ProcessTextInner(globalContext, fullConfigFileName, startLineNo, tr, ignoreCase, fileIncludeStack,
                             forceReloadConfiguration,
                             onIncludedConfiguration: (e, n) => children.Add(e),
                             onLineWithLineNo: (line, lineNo) => {
                if (line.StartsWith("$"))
                {
                    if (currentGroup != null && !currentGroup.IsGlobalGroup)
                    {
                        return("$ inside '{{ ... }}' not allowed");
                    }
                    else
                    {
                        string typeLine = line.Substring(1).Trim();
                        int i           = typeLine.IndexOf(MAY_USE, StringComparison.Ordinal);
                        if (i < 0)
                        {
                            Log.WriteError($"$-line '{line}' must contain " + MAY_USE, ruleSourceName, lineNo);
                            throw new ApplicationException($"$-line '{line}' must contain " + MAY_USE_TAIL);
                        }
                        usingItemType = ItemType.New(typeLine.Substring(0, i).Trim(), globalContext.IgnoreCase);
                        usedItemType  = ItemType.New(typeLine.Substring(i + MAY_USE.Length).Trim(), globalContext.IgnoreCase);
                        return(null);
                    }
                }
                else if (line.EndsWith("{"))
                {
                    if (currentGroup == null || usingItemType == null)
                    {
                        return($"Itemtypes not defined - $ line is missing in {ruleSourceName}, dependency rules are ignored");
                    }
                    else if (!currentGroup.IsGlobalGroup)
                    {
                        return("Nested '{{ ... {{' not possible");
                    }
                    else
                    {
                        string groupPattern = line.TrimEnd('{').Trim();
                        currentGroup        = new DependencyRuleGroup(groupPattern, globalContext.IgnoreCase, usingItemType, usedItemType, ruleSourceName + "_" + lineNo);
                        ruleGroups.Add(currentGroup);
                        return(null);
                    }
                }
                else if (line == "}")
                {
                    if (currentGroup != null && !currentGroup.IsGlobalGroup)
                    {
                        currentGroup = mainRuleGroup;
                        return(null);
                    }
                    else
                    {
                        return("'}}' without corresponding '... {{'");
                    }
                }
                else
                {
                    string currentRawUsingPattern;
                    bool ok = currentGroup.AddDependencyRules(usingItemType, usedItemType, ruleSourceName,
                                                              lineNo, line, ignoreCase, previousRawUsingPattern, out currentRawUsingPattern);
                    if (!ok)
                    {
                        return("Could not add dependency rule");
                    }
                    else
                    {
                        previousRawUsingPattern = currentRawUsingPattern;
                        return(null);
                    }
                }
            }, configValueCollector: configValueCollector, localVars: localVars);
            return(new DependencyRuleSet(ruleGroups, children));
        }
コード例 #8
0
ファイル: ProjectItems.cs プロジェクト: hmmueller/Archichect
        protected override ProjectionSet CreateConfigurationFromText([NotNull] GlobalContext globalContext, string fullConfigFileName,
                                                                     int startLineNo, TextReader tr, bool ignoreCase, string fileIncludeStack, bool forceReloadConfiguration,
                                                                     Dictionary <string, string> configValueCollector, ValuesFrame localVars)
        {
            ItemType sourceItemType = null;
            ItemType targetItemType = null;

            string ruleSourceName = fullConfigFileName;

            var elements = new List <IProjectionSetElement>();

            ProcessTextInner(globalContext, fullConfigFileName, startLineNo, tr, ignoreCase, fileIncludeStack,
                             forceReloadConfiguration, onIncludedConfiguration: (e, n) => elements.Add(e),
                             onLineWithLineNo: (line, lineNo) => {
                if (line.StartsWith("$"))
                {
                    string typeLine = line.Substring(1).Trim();
                    int i           = typeLine.IndexOf(MAP, StringComparison.Ordinal);
                    if (i < 0)
                    {
                        return($"{line}: $-line must contain " + MAP);
                    }
                    sourceItemType = ItemType.New(typeLine.Substring(0, i).Trim(), globalContext.IgnoreCase);
                    targetItemType = ItemType.New(typeLine.Substring(i + MAP.Length).Trim(), globalContext.IgnoreCase);
                    return(null);
                }
                else
                {
                    bool left  = line.StartsWith(ABSTRACT_IT_LEFT);
                    bool right = line.StartsWith(ABSTRACT_IT_RIGHT);
                    bool both  = line.StartsWith(ABSTRACT_IT_BOTH);
                    if (left || both || right)
                    {
                        Projection p = CreateProjection(sourceItemType, targetItemType,
                                                        ruleFileName: ruleSourceName, lineNo: lineNo, rule: line.Substring(1).Trim(),
                                                        ignoreCase: ignoreCase, forLeftSide: left || both, forRightSide: both || right);
                        elements.Add(p);
                        return(null);
                    }
                    else
                    {
                        return($"{line}: line must start with $, {ABSTRACT_IT_LEFT}, {ABSTRACT_IT_BOTH}, or {ABSTRACT_IT_RIGHT}");
                    }
                }
            }, configValueCollector: configValueCollector, localVars: localVars);
            return(new ProjectionSet(elements));
        }
コード例 #9
0
ファイル: ModifyItems.cs プロジェクト: hmmueller/Archichect
        protected override IEnumerable <ItemAction> CreateConfigurationFromText([NotNull] GlobalContext globalContext,
                                                                                string fullConfigFileName, int startLineNo, TextReader tr, bool ignoreCase, string fileIncludeStack,
                                                                                bool forceReloadConfiguration, Dictionary <string, string> configValueCollector, ValuesFrame localVars)
        {
            var actions = new List <ItemAction>();

            ProcessTextInner(globalContext, fullConfigFileName, startLineNo, tr, ignoreCase, fileIncludeStack,
                             forceReloadConfiguration, onIncludedConfiguration: (e, n) => actions.AddRange(e),
                             onLineWithLineNo: (line, lineNo) => {
                actions.Add(new ItemAction(line.Trim(), ignoreCase, fullConfigFileName, startLineNo));
                return(null);
            }, configValueCollector: configValueCollector, localVars: localVars);
            return(actions);
        }