Example #1
0
        private static void ReflectAndCompileExample()
        {
            Console.WriteLine();
            Console.WriteLine("Library data reflect and compiler example.");
            Console.WriteLine();
            Console.WriteLine("======================");
            Console.WriteLine();


            var x = new LSLLibraryDataReflectionSerializer
            {
                PropertyBindingFlags =
                    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public |
                    BindingFlags.DeclaredOnly,
                FieldBindingFlags =
                    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public |
                    BindingFlags.DeclaredOnly,
                MethodBindingFlags =
                    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public |
                    BindingFlags.DeclaredOnly,

                //a fall back value string converter used by the serializer
                //or null.. not really used since the class we are reflecting
                //defines all of its converters explicitly at the class level via the LSLLibraryDataSerializable
                //
                //This is just demonstrating that you can have a fall back.
                //
                //It goes to say, if any converter in the serializer is null, and its actually required
                //to convert a type because a class or class member does not explicitly attribute itself
                //then the serializer will throw an informative exception about what member needed a converter
                //but could not find one to use.
                ValueStringConverter = new MyValueStringConverter(),

                //a fall back constant type converter used by the serializer when nothing else is available
                //or null..
                ConstantTypeConverter = new MySimpleConverter(),

                //fall back return type converter
                ReturnTypeConverter = new MySimpleConverter(),

                //fall back parameter type converter
                ParamTypeConverter = new MySimpleConverter(),


                //we have plenty of converters set up, might as well
                //serialize all the un-attributed methods as well?
                //sure, if you want.
                AttributedMethodsOnly = false,


                //Constants too.
                AttributedConstantsOnly = false,

                //we can converter non attributed parameter types, for sure.
                //don't exclude them from the de-serialized signatures.
                AttributedParametersOnly = false,
            };


            //a provider with no live filtering enabled, only load functions with the subset "my-lsl"
            LSLLibraryDataProvider myProvider = new LSLLibraryDataProvider(new[] { "my-lsl" }, false);


            //declare the subset my-lsl for use.
            myProvider.AddSubsetDescription(new LSLLibrarySubsetDescription("my-lsl", "My LSL Demo"));


            //define an event with no parameters, make sure its subsets are set so that it gets put in the "my-lsl" subset.
            myProvider.DefineEventHandler(new LSLLibraryEventSignature("my_event")
            {
                Subsets = { "my-lsl" }
            });

            myProvider.DefineEventHandler(new LSLLibraryEventSignature("my_deprecated_event")
            {
                Subsets    = { "my-lsl" },
                Deprecated = true
            });

            Console.WriteLine("Methods....\n\n");


            var methods = x.DeSerializeMethods(typeof(AttributeReflectionTestClass)).ToList();


            foreach (var c in methods)
            {
                //add this function to the my-lsl subset
                c.Subsets.Add("my-lsl");

                myProvider.DefineFunction(c);

                Console.WriteLine(c.ToString());
            }


            Console.WriteLine("\n\nWithout instance provided....\n\n");

            var constants = x.DeSerializeConstants(typeof(AttributeReflectionTestClass)).ToList();

            foreach (var c in constants)
            {
                //add this constant to the my-lsl subset

                c.Subsets.Add("my-lsl");

                myProvider.DefineConstant(c);

                Console.WriteLine(c.ToString());
            }


            Console.WriteLine("\n\nWith instance provided....\n\n");

            constants =
                x.DeSerializeConstants(typeof(AttributeReflectionTestClass), new AttributeReflectionTestClass()).ToList();

            foreach (var c in constants)
            {
                //Don't add anything to the provider here.  Just demonstrating the difference between
                //serializing classes that contain static or non-static fields when providing an object instance
                //to the serializer.
                Console.WriteLine(c.ToString());
            }


            //Set up the implementations LSLCodeValidator relies on's
            var validatorStrategies = new LSLCodeValidatorStrategies();

            validatorStrategies.ExpressionValidator       = new LSLDefaultExpressionValidator();
            validatorStrategies.StringLiteralPreProcessor = new LSLDefaultStringPreProcessor();

            //These both print to stdout by default.
            validatorStrategies.SyntaxErrorListener   = new LSLDefaultSyntaxErrorListener();
            validatorStrategies.SyntaxWarningListener = new LSLDefaultSyntaxWarningListener();

            //Use ours, we only defined a few things
            validatorStrategies.LibraryDataProvider = myProvider;


            Console.WriteLine("\n\nSyntax Checking Demo Code...\n\n");

            LSLCodeValidator validator = new LSLCodeValidator(validatorStrategies);


            StringReader strReader = new StringReader(
                @"

default{

    my_event(){
            
            //Valid to call AttributeReflectionTestClass.function(int arg1, string arg2, params int[] variadic);
            //No syntax errors, the function is overloaded and also variadic.
            
            string testStr = ""hello world"";

            integer i = 0;
            for(; i < CONSTANT_A ; i++)
            {
                //reference a deprecated constant, causes a warning
                integer expand = CONSTANT_B;

                function(expand, testStr , 1,2,3,4,5);

                list testList = myModuleFunction(""hi there"");
            }

    }


    my_deprecated_event(){
        //reference a deprecated event, causes a deprecation warning.

    }

}
");


            ILSLCompilationUnitNode tree = validator.Validate(strReader);

            //Validate returns null if a syntax error was encountered.
            //I do not want users to visit a tree with syntax errors.
            //
            //The 'IsError' property that tree node interfaces have is only
            //to propagate source code errors up to the root node of the syntax tree,
            //so that the validator can tell if it needs to return null or not.
            //
            if (tree != null)
            {
                Console.WriteLine("\n\nNo syntax errors!\n\n");

                var compilerSettings = new LSLOpenSimCompilerSettings();

                compilerSettings.InsertCoOpTerminationCalls = true;
                compilerSettings.GenerateClass                 = true;
                compilerSettings.GeneratedClassName            = "MyClass";
                compilerSettings.GeneratedConstructorSignature = "()";
                compilerSettings.GeneratedClassNamespace       = "MyNameSpace";

                LSLOpenSimCompiler compiler = new LSLOpenSimCompiler(myProvider, compilerSettings);


                MemoryStream memStream = new MemoryStream();
                var          memWriter = new StreamWriter(memStream);

                compiler.Compile(tree, memWriter);


                Console.WriteLine(Encoding.Default.GetString(memStream.ToArray()));
            }
        }