Esempio n. 1
0
 public override void Interceptor(AspectMetadata metadata)
 {
     foreach (var item in metadata.Parameters)
     {
         Console.WriteLine(item);
         Console.WriteLine("方法调用前");
     }
     metadata.Processed();
     Console.WriteLine("放回值");
     Console.WriteLine(metadata.Return);
     Console.WriteLine("调用后");
 }
Esempio n. 2
0
        public void AddFunction(string name, AspectMetadata function)
        {
            if (Funcs.Builtins.ContainsKey(name))
            {
                throw new ArgumentException("Function " + name + " already exists, it is a builtin function");
            }

            if (DefinedFunctions.ContainsKey(name) && !function.ProfileInternal)
            {
                throw new ArgumentException("Function " + name + " already exists");
            }

            DefinedFunctions[name] = function;
        }
Esempio n. 3
0
        private static object CallInterceptorChina(IEnumerable <IAspect> aspects, AspectMetadata lastest)
        {
            var            enumerator = aspects.GetEnumerator();
            AspectMetadata metadata   = lastest;
            IAspect        first      = !enumerator.MoveNext() ? new DefaultAspectAttribute() : enumerator.Current;

            while (enumerator.MoveNext())
            {
                IAspect    current    = enumerator.Current;
                Type       aspectType = current.GetType();
                Type[]     types      = new Type[] { typeof(AspectMetadata) };
                MethodInfo method     = aspectType.GetMethod("CallInterecptor", types);
                metadata = CreateAspectMetadata(method, current, types, new object[] { metadata });
            }
            return(first.CallInterecptor(metadata));
        }
Esempio n. 4
0
        private (string implementation, HashSet <string> extraKeys) GenerateMembershipPreprocessor()
        {
            // Extra keys are the names of introduced tag-keys, e.g. '_relation:bicycle_fastest:cycle_highway'
            var extraKeys   = new HashSet <string>();
            var memberships = Analysis.MembershipMappingsFor(_profile, _context);

            foreach (var(calledInFunction, membership) in memberships)
            {
                var funcMetaData = new AspectMetadata(
                    membership,
                    "relation_preprocessing_for_" + calledInFunction.AsLuaIdentifier(),
                    "Function preprocessing needed for aspect " + calledInFunction +
                    ", called by the relation preprocessor",
                    "Generator", "", "NA"
                    );


                _skeleton.AddFunction(funcMetaData);
            }


            var func = new List <string>
            {
                "",
                "",
                "-- Processes the relation. All tags which are added to result.attributes_to_keep will be copied to 'attributes' of each individual way",
                "function relation_tag_processor(relation_tags, result)",
                "    local parameters = {}",
                "    local subresult = {}",
                "    local matched = false",
                "    result.attributes_to_keep = {}",
                "    ",
                "    -- Legacy to add colours to the bike networks",
                "    legacy_relation_preprocessor(relation_tags, result)"
            };

            _skeleton.AddDep("legacy");

            foreach (var(calledInFunction, expr) in memberships)
            {
                func.Add($"\n\n  -- {calledInFunction} ---");

                var usedParameters = expr.UsedParameters().Select(param => param.ParamName.TrimStart('#')).ToHashSet();

                // First, we calculate the value for the default parameters
                var preProcName = "relation_preprocessing_for_" + calledInFunction.AsLuaIdentifier();
                func.Add("");
                func.Add("");
                func.Add("    subresult.attributes_to_keep = {}");
                func.Add("    parameters = default_parameters()");
                func.Add($"    matched = {preProcName}(parameters, relation_tags, subresult)");
                func.Add("    if (matched) then");
                var tagKey = "_relation:" + calledInFunction.AsLuaIdentifier();
                extraKeys.Add(tagKey);
                func.Add(
                    "    -- " + tagKey +
                    " is the default value, which will be overwritten in 'remove_relation_prefix' for behaviours having a different parameter settign");
                func.Add($"        result.attributes_to_keep[\"{tagKey}\"] = \"yes\"");
                func.Add("    end");


                if (!usedParameters.Any())
                {
                    // Every behaviour uses the default parameters for this one
                    func.Add("    -- No parameter dependence for aspect " + calledInFunction);
                    continue;
                }

                foreach (var(behaviourName, parameters) in _profile.Behaviours)
                {
                    if (usedParameters.Except(parameters.Keys.ToHashSet()).Any())
                    {
                        // The parameters where the membership depends on, are not used here
                        // This is thus the same as the default. We don't have to calculate it
                        continue;
                    }

                    func.Add("");
                    func.Add("");
                    func.Add("    subresult.attributes_to_keep = {}");
                    func.Add("    parameters = default_parameters()");
                    func.Add(_parameterPrinter.DeclareParametersFor(parameters.Where(kv => usedParameters.Contains(kv.Key))
                                                                    .ToDictionary(kv => kv.Key, kv => kv.Value)));
                    func.Add($"    matched = {preProcName}(parameters, relation_tags, subresult)");
                    func.Add("    if (matched) then");
                    tagKey = "_relation:" + behaviourName.AsLuaIdentifier() + ":" + calledInFunction.AsLuaIdentifier();
                    extraKeys.Add(tagKey);
                    func.Add($"        result.attributes_to_keep[\"{tagKey}\"] = \"yes\"");
                    func.Add("    end");
                }
            }

            func.Add("end");

            return(string.Join("\n", func), extraKeys);
        }
        public void AddFunction(AspectMetadata meta)
        {
            if (_alreadyAddedFunctions.Contains(meta.Name))
            {
                // already added
                return;
            }

            _alreadyAddedFunctions.Add(meta.Name);

            var possibleTags = meta.PossibleTags() ?? new Dictionary <string, HashSet <string> >();
            int numberOfCombinations;

            numberOfCombinations = possibleTags.Values.Select(lst => 1 + lst.Count).Multiply();

            var usedParams = meta.UsedParameters();

            var funcNameDeclaration = "";

            meta.Visit(e => {
                if (e is Function f && f.Name.Equals(Funcs.MemberOf.Name))
                {
                    funcNameDeclaration = $"\n    local funcName = \"{meta.Name.AsLuaIdentifier()}\"";
                }

                return(true);
            });

            var expression = meta.ExpressionImplementation;

            var ctx = Context;

            _context = _context.WithAspectName(meta.Name);

            var body = "";

            if (_useSnippets)
            {
                if (expression.Types.First() is Curry c)
                {
                    expression = expression.Apply(new LuaLiteral(Typs.Tags, "tags"));
                }

                body = Utils.Lines(
                    "    local r = nil",
                    "    " + Snippets.Convert(this, "r", expression).Indent(),
                    "    return r"
                    );
            }
            else
            {
                body = "    return " + ToLua(expression);
            }


            var impl = Utils.Lines(
                "--[[",
                meta.Description,
                "",
                "Unit: " + meta.Unit,
                "Created by " + meta.Author,
                "Uses tags: " + string.Join(", ", possibleTags.Keys),
                "Used parameters: " + string.Join(", ", usedParams),
                "Number of combintations: " + numberOfCombinations,
                "Returns values: ",
                "]]",
                "function " + meta.Name.AsLuaIdentifier() + "(parameters, tags, result)" + funcNameDeclaration,
                body,
                "end"
                );

            _context = ctx;
            _functionImplementations.Add(impl);
        }