예제 #1
0
 public CompileRequest(
     ICollection <CompilableClass> classes,
     ModuleCompileTimeServices moduleCompileTimeServices)
 {
     _classes = classes;
     _moduleCompileTimeServices = moduleCompileTimeServices;
 }
예제 #2
0
        public Type CompileStandInClass(
            CodegenClassType classType,
            string classNameSimple,
            ModuleCompileTimeServices services)
        {
            var namespaceScope = new CodegenNamespaceScope(services.Namespace, null, false);
            var classScope = new CodegenClassScope(true, namespaceScope, null);
            var clazz = new CodegenClass(
                classType,
                null,
                classNameSimple,
                classScope,
                EmptyList<CodegenTypedParam>.Instance,
                null,
                new CodegenClassMethods(),
                new CodegenClassProperties(),
                EmptyList<CodegenInnerClass>.Instance);
            
            // This is a bit hacky... basically, Esper has to generate a "Type" that can be returned and
            // included as the "Underlying" type for the JsonEventType.  This method is called during the
            // portion of the sequence where we are attempting to build the forgeables, so the real type
            // doesnt exist yet.  Esper builds the stand-in but expects that the real type will be used
            // at runtime.  In Java, type erasure allows this to happen because there is no real type in
            // backing arrays and collections.  In .NET we need the types to match.
            //
            // We are creating a "capsule" class which will act as a placeholder.  When we detect that
            // the type is a capsule type in the JsonEventType, we will attempt to "resolve" and replace
            // it.
            
            var classNameFull = namespaceScope.Namespace + '.' + classNameSimple;
            var capsuleClass = CapsuleEmitter.CreateCapsule(classNameFull);

            return capsuleClass.TargetType;
        }
        protected internal static EPCompiled Compile(
            IList<Compilable> compilables,
            string optionalModuleName,
            IDictionary<ModuleProperty, object> moduleProperties,
            ModuleCompileTimeServices compileTimeServices,
            CompilerOptions compilerOptions)
        {
            ICollection<Assembly> assemblies = new HashSet<Assembly>();
            
            try {
                EPCompiledManifest manifest = CompileToModules(
                    assemblies,
                    compilables,
                    optionalModuleName,
                    moduleProperties,
                    compileTimeServices,
                    compilerOptions,
                    out var assembly);

                return new EPCompiled(assemblies, manifest);
            }
            catch (EPCompileException) {
                throw;
            }
            catch (Exception ex) {
                throw new EPCompileException(
                    "Unexpected exception compiling module: " + ex.Message,
                    ex,
                    new EmptyList<EPCompileExceptionItem>());
            }
        }
예제 #4
0
        private static EPCompiledManifest CompileToAssembly(
            FAFQueryMethodForge query,
            string classPostfix,
            CompilerOptions compilerOptions,
            ModuleCompileTimeServices compileTimeServices,
            out Assembly assembly)
        {
            string queryMethodProviderClassName;
            try {
                queryMethodProviderClassName = CompilerHelperFAFQuery.CompileQuery(query, classPostfix,compileTimeServices, out assembly);
            }
            catch (StatementSpecCompileException ex) {
                EPCompileExceptionItem first;
                if (ex is StatementSpecCompileSyntaxException) {
                    first = new EPCompileExceptionSyntaxItem(ex.Message, ex.Expression, -1);
                }
                else {
                    first = new EPCompileExceptionItem(ex.Message, ex.Expression, -1);
                }

                var items = Collections.SingletonList(first);
                throw new EPCompileException(ex.Message + " [" + ex.Expression + "]", ex, items);
            }

            // compile query provider
            var fafProviderClassName = MakeFAFProvider(
                queryMethodProviderClassName,
                classPostfix,
                compileTimeServices,
                out assembly);

            // create manifest
            return new EPCompiledManifest(COMPILER_VERSION, null, fafProviderClassName, false);
        }
 public static ExprValidationContext Make(
     IContainer container,
     StreamTypeService streamTypeService)
 {
     var moduleServices = new ModuleCompileTimeServices(container);
     moduleServices.Configuration = new Configuration();
     moduleServices.ImportServiceCompileTime = SupportClasspathImport.GetInstance(container);
     var services = new StatementCompileTimeServices(1, moduleServices);
     var raw = new StatementRawInfo(1, "abc", null, StatementType.SELECT, null, null, null, null);
     return new ExprValidationContextBuilder(streamTypeService, raw, services).Build();
 }
예제 #6
0
 CompileCallable(
     CompilableItem compilableItem,
     ModuleCompileTimeServices compileTimeServices,
     Semaphore semaphore,
     ICollection <Assembly> statementAssemblies)
 {
     _compilableItem      = compilableItem;
     _compileTimeServices = compileTimeServices;
     _semaphore           = semaphore;
     _statementAssemblies = statementAssemblies;
 }
예제 #7
0
 private void AddModuleImports(
     ICollection<Import> imports,
     ModuleCompileTimeServices compileTimeServices)
 {
     if (imports != null) {
         foreach (var imported in imports) {
             try {
                 compileTimeServices.ImportServiceCompileTime.AddImport(imported);
             }
             catch (ImportException e) {
                 throw new EPCompileException("Invalid module import: " + e.Message, e);
             }
         }
     }
 }
예제 #8
0
        public static string CompileQuery(
            FAFQueryMethodForge query,
            string classPostfix,
            ModuleCompileTimeServices compileTimeServices,
            out Assembly assembly)
        {
            var statementFieldsClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementFields),
                classPostfix);
            var packageScope = new CodegenNamespaceScope(
                compileTimeServices.Namespace,
                statementFieldsClassName,
                compileTimeServices.IsInstrumented());

            var queryMethodProviderClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(FAFQueryMethodProvider),
                classPostfix);
            var forgeablesQueryMethod = query.MakeForgeables(queryMethodProviderClassName, classPostfix, packageScope);

            IList<StmtClassForgeable> forgeables = new List<StmtClassForgeable>(forgeablesQueryMethod);
            forgeables.Add(new StmtClassForgeableStmtFields(statementFieldsClassName, packageScope, 0));

            // forge with statement-fields last
            var classes = new List<CodegenClass>(forgeables.Count);
            foreach (var forgeable in forgeables) {
                var clazz = forgeable.Forge(true, true);
                classes.Add(clazz);
            }

            // assign the assembly (required for completeness)
            assembly = null;

            // compile with statement-field first
            classes = classes
                .OrderBy(c => c.ClassType.GetSortCode())
                .ToList();

            var container = compileTimeServices.Container;
            var compiler = container
                .RoslynCompiler()
                .WithCodeLogging(compileTimeServices.Configuration.Compiler.Logging.IsEnableCode)
                .WithCodeAuditDirectory(compileTimeServices.Configuration.Compiler.Logging.AuditDirectory)
                .WithCodegenClasses(classes);

            assembly = compiler.Compile();

            return queryMethodProviderClassName;
        }
        internal static CodegenMethod MakeInitEventTypes(
            CodegenClassScope classScope,
            ModuleCompileTimeServices compileTimeServices)
        {
            var symbolsEventTypeInit = new ModuleEventTypeInitializeSymbol();
            var initializeEventTypesMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsEventTypeInit, classScope)
                .AddParam(
                    typeof(EPModuleEventTypeInitServices),
                    ModuleEventTypeInitializeSymbol.REF_INITSVC.Ref);
            foreach (var eventType in compileTimeServices.EventTypeCompileTimeRegistry.NewTypesAdded) {
                var addType = RegisterEventTypeCodegen(
                    eventType,
                    initializeEventTypesMethod,
                    classScope,
                    symbolsEventTypeInit);
                initializeEventTypesMethod.Block.Expression(LocalMethod(addType));
            }

            return initializeEventTypesMethod;
        }
예제 #10
0
        public static EPCompiled Compile(
            Compilable compilable,
            ModuleCompileTimeServices services,
            CompilerArguments args)
        {
            var compileTimeServices = new StatementCompileTimeServices(0, services);
            var walkResult = CompilerHelperSingleEPL.ParseCompileInlinedClassesWalk(compilable, compileTimeServices);
            var raw = walkResult.StatementSpecRaw;

            var statementType = StatementTypeUtil.GetStatementType(raw);
            if (statementType != StatementType.SELECT) {
                // the fire-and-forget spec is null for "select" and populated for I/U/D
                throw new StatementSpecCompileException(
                    "Provided EPL expression is a continuous query expression (not an on-demand query)",
                    compilable.ToEPL());
            }

            var annotations = AnnotationUtil.CompileAnnotations(
                raw.Annotations,
                services.ImportServiceCompileTime,
                compilable);

            // walk subselects, alias expressions, declared expressions, dot-expressions
            var visitor = StatementSpecRawWalkerSubselectAndDeclaredDot.WalkSubselectAndDeclaredDotExpr(raw);

            // compile context descriptor
            ContextCompileTimeDescriptor contextDescriptor = null;
            var optionalContextName = raw.OptionalContextName;
            if (optionalContextName != null) {
                var detail = services.ContextCompileTimeResolver.GetContextInfo(optionalContextName);
                if (detail == null) {
                    throw new StatementSpecCompileException(
                        "Context by name '" + optionalContextName + "' could not be found",
                        compilable.ToEPL());
                }

                contextDescriptor = new ContextCompileTimeDescriptor(
                    optionalContextName,
                    detail.ContextModuleName,
                    detail.ContextVisibility,
                    new ContextPropertyRegistry(detail),
                    detail.ValidationInfos);
            }

            var statementNameFromAnnotation = GetNameFromAnnotation(annotations);
            var statementName = statementNameFromAnnotation == null ? GetDefaultStatementName() : statementNameFromAnnotation.Trim();
            var statementRawInfo = new StatementRawInfo(
                0,
                statementName,
                annotations,
                statementType.Value,
                contextDescriptor,
                null,
                compilable,
                null);
            StatementSpecCompiledDesc compiledDesc = StatementRawCompiler.Compile(
                raw,
                compilable,
                false,
                true,
                annotations,
                visitor.Subselects,
                new List<ExprTableAccessNode>(raw.TableExpressions),
                statementRawInfo,
                compileTimeServices);
            StatementSpecCompiled specCompiled = compiledDesc.Compiled;

            var fafSpec = specCompiled.Raw.FireAndForgetSpec;

            //var @namespace = "generated";
            var classPostfix = IdentifierUtil.GetIdentifierMayStartNumeric(statementName);

            EPCompiledManifest manifest;
            Assembly assembly;

            FAFQueryMethodForge query;
            if (specCompiled.Raw.InsertIntoDesc != null) {
                query = new FAFQueryMethodIUDInsertIntoForge(
                    specCompiled,
                    compilable,
                    statementRawInfo,
                    compileTimeServices);
            }
            else if (fafSpec == null) { // null indicates a select-statement, same as continuous query
                var desc = new FAFQueryMethodSelectDesc(
                    specCompiled,
                    compilable,
                    statementRawInfo,
                    compileTimeServices);
                var classNameResultSetProcessor =
                    CodeGenerationIDGenerator.GenerateClassNameSimple(
                        typeof(ResultSetProcessorFactoryProvider),
                        classPostfix);
                query = new FAFQueryMethodSelectForge(desc, classNameResultSetProcessor, statementRawInfo);
            }
            else if (fafSpec is FireAndForgetSpecDelete) {
                query = new FAFQueryMethodIUDDeleteForge(
                    specCompiled,
                    compilable,
                    statementRawInfo,
                    compileTimeServices);
            }
            else if (fafSpec is FireAndForgetSpecUpdate) {
                query = new FAFQueryMethodIUDUpdateForge(
                    specCompiled,
                    compilable,
                    statementRawInfo,
                    compileTimeServices);
            }
            else {
                throw new IllegalStateException("Unrecognized FAF code " + fafSpec);
            }

            // verify substitution parameters
            VerifySubstitutionParams(raw.SubstitutionParameters);

            try {
                manifest = CompileToAssembly(query, classPostfix, args.Options, services, out assembly);
            }
            catch (EPCompileException) {
                throw;
            }
            catch (Exception ex) {
                throw new EPCompileException(
                    "Unexpected exception compiling module: " + ex.Message,
                    ex,
                    new EmptyList<EPCompileExceptionItem>());
            }

            return new EPCompiled(new [] { assembly }, manifest);
        }
예제 #11
0
        private static string MakeFAFProvider(
            string queryMethodProviderClassName,
            string classPostfix,
            ModuleCompileTimeServices compileTimeServices,
            out Assembly assembly)
        {
            var statementFieldsClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementFields), classPostfix);
            var namespaceScope = new CodegenNamespaceScope(
                compileTimeServices.Namespace, statementFieldsClassName, compileTimeServices.IsInstrumented());
            var fafProviderClassName =
                CodeGenerationIDGenerator.GenerateClassNameSimple(typeof(FAFProvider), classPostfix);
            var classScope = new CodegenClassScope(true, namespaceScope, fafProviderClassName);
            var methods = new CodegenClassMethods();
            var properties = new CodegenClassProperties();

            // --------------------------------------------------------------------------------
            // Add statementFields
            // --------------------------------------------------------------------------------

            var ctor = new CodegenCtor(
                typeof(CompilerHelperFAFProvider),
                classScope,
                new List<CodegenTypedParam>());

            ctor.Block.AssignRef(Ref("statementFields"), NewInstanceInner(statementFieldsClassName));

            // initialize-event-types
            var initializeEventTypesMethod = MakeInitEventTypes(classScope, compileTimeServices);

            // initialize-query
            var initializeQueryMethod = CodegenMethod
                .MakeMethod(
                    typeof(void),
                    typeof(EPCompilerImpl),
                    CodegenSymbolProviderEmpty.INSTANCE,
                    classScope)
                .AddParam(
                    typeof(EPStatementInitServices),
                    EPStatementInitServicesConstants.REF.Ref);
            initializeQueryMethod.Block.AssignMember(
                MEMBERNAME_QUERY_METHOD_PROVIDER,
                NewInstanceInner(queryMethodProviderClassName, EPStatementInitServicesConstants.REF, Ref("statementFields")));

            // get-execute
            var queryMethodProviderProperty = CodegenProperty.MakePropertyNode(
                typeof(FAFQueryMethodProvider),
                typeof(EPCompilerImpl),
                CodegenSymbolProviderEmpty.INSTANCE,
                classScope);
            queryMethodProviderProperty.GetterBlock.BlockReturn(Ref(MEMBERNAME_QUERY_METHOD_PROVIDER));

            // provide module dependencies
            var moduleDependenciesProperty = CodegenProperty.MakePropertyNode(
                typeof(ModuleDependenciesRuntime),
                typeof(EPCompilerImpl),
                CodegenSymbolProviderEmpty.INSTANCE,
                classScope);
            moduleDependenciesProperty.GetterBlock
                .BlockReturn(compileTimeServices.ModuleDependencies.Make(
                    initializeQueryMethod, classScope));

            // build stack
            CodegenStackGenerator.RecursiveBuildStack(moduleDependenciesProperty, "ModuleDependencies", methods, properties);
            CodegenStackGenerator.RecursiveBuildStack(initializeEventTypesMethod, "InitializeEventTypes", methods, properties);
            CodegenStackGenerator.RecursiveBuildStack(initializeQueryMethod, "InitializeQuery", methods, properties);
            CodegenStackGenerator.RecursiveBuildStack(queryMethodProviderProperty, "QueryMethodProvider", methods, properties);

            IList<CodegenTypedParam> members = new List<CodegenTypedParam>();
            members.Add(new CodegenTypedParam(statementFieldsClassName, null, "statementFields"));
            var typedParam = new CodegenTypedParam(typeof(FAFQueryMethodProvider), MEMBERNAME_QUERY_METHOD_PROVIDER);
            typedParam.IsReadonly = false;
            members.Add(typedParam);

            var clazz = new CodegenClass(
                CodegenClassType.FAFPROVIDER,
                typeof(FAFProvider),
                fafProviderClassName,
                classScope,
                members,
                ctor,
                methods,
                properties,
                new EmptyList<CodegenInnerClass>());

            var container = compileTimeServices.Container;
            var compiler = container
                .RoslynCompiler()
                .WithCodeLogging(compileTimeServices.Configuration.Compiler.Logging.IsEnableCode)
                .WithCodeAuditDirectory(compileTimeServices.Configuration.Compiler.Logging.AuditDirectory)
                .WithCodegenClasses(new List<CodegenClass>() { clazz });

            assembly = compiler.Compile();

            return CodeGenerationIDGenerator.GenerateClassNameWithNamespace(
                compileTimeServices.Namespace,
                typeof(FAFProvider),
                classPostfix);
        }
예제 #12
0
 public EPCompilerSPIExpressionImpl(ModuleCompileTimeServices moduleServices)
 {
     this.moduleServices = moduleServices;
 }
        public static CompilableItem CompileItem(
            Compilable compilable,
            string optionalModuleName,
            string moduleIdentPostfix,
            int statementNumber,
            ISet<string> statementNames,
            ModuleCompileTimeServices moduleCompileTimeServices,
            CompilerOptions compilerOptions,
            out Assembly assembly)
        {
            var compileTimeServices = new StatementCompileTimeServices(statementNumber, moduleCompileTimeServices);

            // Stage 0 - parse and compile-inline-classes and walk statement
            var walked = ParseCompileInlinedClassesWalk(compilable, compileTimeServices);
            var raw = walked.StatementSpecRaw;
            string classNameCreateClass = null;
            if (raw.CreateClassProvided != null) {
                classNameCreateClass = DetermineClassNameCreateClass(walked.ClassesInlined);
            }
            
            try {
                // Stage 2(a) - precompile: compile annotations
                var annotations = AnnotationUtil.CompileAnnotations(
                    raw.Annotations,
                    compileTimeServices.ImportServiceCompileTime,
                    compilable);

                // Stage 2(b) - walk subselects, alias expressions, declared expressions, dot-expressions
                ExprNodeSubselectDeclaredDotVisitor visitor;
                try {
                    visitor = StatementSpecRawWalkerSubselectAndDeclaredDot.WalkSubselectAndDeclaredDotExpr(raw);
                }
                catch (ExprValidationException ex) {
                    throw new StatementSpecCompileException(ex.Message, compilable.ToEPL());
                }

                var subselectNodes = visitor.Subselects;

                // Determine a statement name
                var statementNameProvided = GetNameFromAnnotation(annotations);
                if (compilerOptions.StatementName != null) {
                    var assignedName = compilerOptions.StatementName.Invoke(
                        new StatementNameContext(
                            () => compilable.ToEPL(),
                            statementNameProvided,
                            optionalModuleName,
                            annotations,
                            statementNumber));
                    if (assignedName != null) {
                        statementNameProvided = assignedName;
                    }
                }

                var statementName = statementNameProvided ?? Convert.ToString(statementNumber);
                if (statementNames.Contains(statementName)) {
                    var count = 1;
                    var newStatementName = statementName + "-" + count;
                    while (statementNames.Contains(newStatementName)) {
                        count++;
                        newStatementName = statementName + "-" + count;
                    }

                    statementName = newStatementName;
                }

                statementName = statementName.Trim();
                statementNames.Add(statementName);

                // Determine table access nodes
                var tableAccessNodes = DetermineTableAccessNodes(raw.TableExpressions, visitor);

                // compile scripts once in this central place, may also compile later in expression
                ScriptValidationPrecompileUtil.ValidateScripts(
                    raw.ScriptExpressions,
                    raw.ExpressionDeclDesc,
                    compileTimeServices);

                // Determine subselects for compilation, and lambda-expression shortcut syntax for named windows
                if (!visitor.ChainedExpressionsDot.IsEmpty()) {
                    RewriteNamedWindowSubselect(
                        visitor.ChainedExpressionsDot,
                        subselectNodes,
                        compileTimeServices.NamedWindowCompileTimeResolver);
                }

                // Stage 2(c) compile context descriptor
                ContextCompileTimeDescriptor contextDescriptor = null;
                var optionalContextName = raw.OptionalContextName;
                if (optionalContextName != null) {
                    var detail = compileTimeServices.ContextCompileTimeResolver.GetContextInfo(optionalContextName);
                    if (detail == null) {
                        throw new StatementSpecCompileException(
                            "Context by name '" + optionalContextName + "' could not be found",
                            compilable.ToEPL());
                    }

                    contextDescriptor = new ContextCompileTimeDescriptor(
                        optionalContextName,
                        detail.ContextModuleName,
                        detail.ContextVisibility,
                        new ContextPropertyRegistry(detail),
                        detail.ValidationInfos);
                }

                // Stage 2(d) compile raw statement spec
                var statementType = StatementTypeUtil.GetStatementType(raw).Value;
                var statementRawInfo = new StatementRawInfo(
                    statementNumber,
                    statementName,
                    annotations,
                    statementType,
                    contextDescriptor,
                    raw.IntoTableSpec?.Name,
                    compilable,
                    optionalModuleName);
                var compiledDesc = StatementRawCompiler.Compile(
                    raw,
                    compilable,
                    false,
                    false,
                    annotations,
                    subselectNodes,
                    tableAccessNodes,
                    statementRawInfo,
                    compileTimeServices);
                var specCompiled = compiledDesc.Compiled;
                var statementIdentPostfix = IdentifierUtil.GetIdentifierMayStartNumeric(statementName);

                // get compile-time user object
                object userObjectCompileTime = null;
                if (compilerOptions.StatementUserObject != null) {
                    userObjectCompileTime = compilerOptions.StatementUserObject.Invoke(
                        new StatementUserObjectContext(
                            () => compilable.ToEPL(),
                            statementName,
                            optionalModuleName,
                            annotations,
                            statementNumber));
                }

                // handle hooks
                HandleStatementCompileHook(annotations, compileTimeServices, specCompiled);

                // Stage 3(a) - statement-type-specific forge building
                var @base = new StatementBaseInfo(
                    compilable,
                    specCompiled,
                    userObjectCompileTime,
                    statementRawInfo,
                    optionalModuleName);
                StmtForgeMethod forgeMethod;
                if (raw.UpdateDesc != null) {
                    forgeMethod = new StmtForgeMethodUpdate(@base);
                }
                else if (raw.OnTriggerDesc != null) {
                    forgeMethod = new StmtForgeMethodOnTrigger(@base);
                }
                else if (raw.CreateIndexDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateIndex(@base);
                }
                else if (raw.CreateVariableDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateVariable(@base);
                }
                else if (raw.CreateDataFlowDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateDataflow(@base);
                }
                else if (raw.CreateTableDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateTable(@base);
                }
                else if (raw.CreateExpressionDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateExpression(@base);
                }
                else if (raw.CreateClassProvided != null) {
                    forgeMethod = new StmtForgeMethodCreateClass(@base, walked.ClassesInlined, classNameCreateClass);
                }
                else if (raw.CreateWindowDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateWindow(@base);
                }
                else if (raw.CreateContextDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateContext(@base);
                }
                else if (raw.CreateSchemaDesc != null) {
                    forgeMethod = new StmtForgeMethodCreateSchema(@base);
                }
                else {
                    forgeMethod = new StmtForgeMethodSelect(@base);
                }

                // check context-validity conditions for this statement
                if (contextDescriptor != null) {
                    try {
                        foreach (var validator in contextDescriptor.ValidationInfos) {
                            validator.ValidateStatement(
                                contextDescriptor.ContextName,
                                specCompiled,
                                compileTimeServices);
                        }
                    }
                    catch (ExprValidationException ex) {
                        throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL());
                    }
                }

                // Stage 3(b) - forge-factory-to-forge
                var classPostfix = moduleIdentPostfix + "_" + statementIdentPostfix;
                var forgeables = new List<StmtClassForgeable>();
                
                // add forgeables from filter-related processing i.e. multikeys
                foreach (var additional in compiledDesc.AdditionalForgeables) {
                    var namespaceScope = new CodegenNamespaceScope(compileTimeServices.Namespace, null, false);
                    forgeables.Add(additional.Make(namespaceScope, classPostfix));
                }
                
                var filterSpecCompileds = new List<FilterSpecCompiled>();
                var scheduleHandleCallbackProviders = new List<ScheduleHandleCallbackProvider>();
                var namedWindowConsumers = new List<NamedWindowConsumerStreamSpec>();
                var filterBooleanExpressions = new List<FilterSpecParamExprNodeForge>();
                
                var result = forgeMethod.Make(compileTimeServices.Namespace, classPostfix, compileTimeServices);
                forgeables.AddAll(result.Forgeables);
                VerifyForgeables(forgeables);
                
                filterSpecCompileds.AddAll(result.Filtereds);
                scheduleHandleCallbackProviders.AddAll(result.Scheduleds);
                namedWindowConsumers.AddAll(result.NamedWindowConsumers);
                filterBooleanExpressions.AddAll(result.FilterBooleanExpressions);

                // Stage 3(c) - filter assignments: assign filter callback ids and filter-path-num for boolean expressions
                var filterId = -1;
                foreach (var provider in filterSpecCompileds) {
                    var assigned = ++filterId;
                    provider.FilterCallbackId = assigned;
                }

                // Stage 3(d) - schedule assignments: assign schedule callback ids
                var scheduleId = 0;
                foreach (var provider in scheduleHandleCallbackProviders) {
                    provider.ScheduleCallbackId = scheduleId++;
                }

                // Stage 3(e) - named window consumers: assign consumer id
                var namedWindowConsumerId = 0;
                foreach (var provider in namedWindowConsumers) {
                    provider.NamedWindowConsumerId = namedWindowConsumerId++;
                }

                // Stage 3(f) - filter boolean expression id assignment
                var filterBooleanExprNum = 0;
                foreach (var expr in filterBooleanExpressions) {
                    expr.FilterBoolExprId = filterBooleanExprNum++;
                }

                // Stage 3(f) - verify substitution parameters
                VerifySubstitutionParams(raw.SubstitutionParameters);

                // Stage 4 - forge-to-class (forge with statement-fields last)
                var classes = forgeables
                    .Select(forgeable => forgeable.Forge(true, false))
                    .ToList();

                // Stage 5 - refactor methods to make sure the constant pool does not grow too large for any given class
                CompilerHelperRefactorToStaticMethods.RefactorMethods(
                    classes, compileTimeServices.Configuration.Compiler.ByteCode.MaxMethodsPerClass);

                // Stage 6 - sort to make the "fields" class first and all the rest later
                var sorted = classes
                    .OrderBy(c => c.ClassType.GetSortCode())
                    .ToList();

                // We are making sure JsonEventType receives the underlying class itself
                CompilableItemPostCompileLatch postCompile = CompilableItemPostCompileLatchDefault.INSTANCE;
                foreach (var eventType in compileTimeServices.EventTypeCompileTimeRegistry.NewTypesAdded) {
                    if (eventType is JsonEventType) {
                        postCompile = new CompilableItemPostCompileLatchJson(
                            compileTimeServices.EventTypeCompileTimeRegistry.NewTypesAdded,
                            compileTimeServices.ParentClassLoader);
                        break;
                    }
                }

                var container = compileTimeServices.Container;
                var compiler = container
                    .RoslynCompiler()
                    .WithCodeLogging(compileTimeServices.Configuration.Compiler.Logging.IsEnableCode)
                    .WithCodeAuditDirectory(compileTimeServices.Configuration.Compiler.Logging.AuditDirectory)
                    .WithCodegenClasses(sorted);

                assembly = compiler.Compile();

                string statementProviderClassName = CodeGenerationIDGenerator.GenerateClassNameWithNamespace(
                    compileTimeServices.Namespace,
                    typeof(StatementProvider),
                    classPostfix);

                var additionalClasses = new HashSet<Type>();
                additionalClasses.AddAll(walked.ClassesInlined.Classes);
                compileTimeServices.ClassProvidedCompileTimeResolver.AddTo(additionalClasses);
                compileTimeServices.ClassProvidedCompileTimeRegistry.AddTo(additionalClasses);

                return new CompilableItem(
                    statementProviderClassName,
                    classes,
                    postCompile,
                    additionalClasses);
            }
            catch (StatementSpecCompileException) {
                throw;
            }
            catch (ExprValidationException ex) {
                throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL());
            }
            catch (EPException ex) {
                throw new StatementSpecCompileException(ex.Message, ex, compilable.ToEPL());
            }
            catch (Exception ex) {
                var text = ex.Message ?? ex.GetType().FullName;
                throw new StatementSpecCompileException(text, ex, compilable.ToEPL());
            }
        }
예제 #14
0
        private static EPCompiledManifest CompileToModules(
            ICollection<Assembly> assemblies,
            IList<Compilable> compilables,
            string optionalModuleName,
            IDictionary<ModuleProperty, object> moduleProperties,
            ModuleCompileTimeServices compileTimeServices,
            CompilerOptions compilerOptions,
            out Assembly assembly)
        {
            var moduleAssignedName = optionalModuleName ?? Guid.NewGuid().ToString();
            var moduleIdentPostfix = IdentifierUtil.GetIdentifierMayStartNumeric(moduleAssignedName);

            // compile each statement
            var statementNumber = 0;
            IList<string> statementClassNames = new List<string>();
            ISet<string> statementNames = new HashSet<string>();
            IList<EPCompileExceptionItem> exceptions = new List<EPCompileExceptionItem>();
            IList<EPCompileExceptionItem> postLatchExceptions = new List<EPCompileExceptionItem>();

            foreach (var compilable in compilables) {
                string className = null;
                EPCompileExceptionItem exception = null;

                try {
                    CompilableItem compilableItem = CompilerHelperStatementProvider.CompileItem(
                        compilable,
                        optionalModuleName,
                        moduleIdentPostfix,
                        statementNumber,
                        statementNames,
                        compileTimeServices,
                        compilerOptions,
                        out assembly);

                    assemblies.Add(assembly);
                    className = compilableItem.ProviderClassName;
                    compilableItem.PostCompileLatch.Completed(assemblies);
                    
                    // there can be a post-compile step, which may block submitting further compilables
                    try {
                        compilableItem.PostCompileLatch.AwaitAndRun();
                    } catch (Exception e) {
                        postLatchExceptions.Add(
                            new EPCompileExceptionItem(
                                e.Message,
                                e,
                                compilable.ToEPL(),
                                -1));
                    }
                }
                catch (StatementSpecCompileException ex) {
                    if (ex is StatementSpecCompileSyntaxException) {
                        exception = new EPCompileExceptionSyntaxItem(ex.Message, ex.Expression, -1);
                    }
                    else {
                        exception = new EPCompileExceptionItem(
                            ex.Message,
                            ex,
                            ex.Expression,
                            -1);
                    }

                    exceptions.Add(exception);
                }

                if (exception == null) {
                    statementClassNames.Add(className);
                    statementNumber++;
                }
            }
            
            exceptions.AddAll(postLatchExceptions);
            if (!exceptions.IsEmpty()) {
                var ex = exceptions[0];
                throw new EPCompileException(
                    "Error during compilation: " + ex.Message + " [" + ex.Expression + "]", ex, exceptions);
            }

            // compile module resource
            var moduleProviderClassName = CompileModule(
                optionalModuleName,
                moduleProperties,
                statementClassNames,
                moduleIdentPostfix,
                compileTimeServices,
                out assembly);
            
#if TBD // revisit
            // remove path create-class class-provided byte code
            compileTimeServices.ClassProvidedCompileTimeResolver.RemoveFrom(moduleBytes);

            // add class-provided create-class classes to module bytes
            foreach (var entry in compileTimeServices.ClassProvidedCompileTimeRegistry.Classes) {
                moduleBytes.Put(entry.Value.Assembly);
            }
#endif

            // create module XML
            return new EPCompiledManifest(COMPILER_VERSION, moduleProviderClassName, null, compileTimeServices.SerdeResolver.IsTargetHA);
        }
예제 #15
0
        private static string CompileModule(
            string optionalModuleName,
            IDictionary<ModuleProperty, object> moduleProperties,
            IList<string> statementClassNames,
            string moduleIdentPostfix,
            ModuleCompileTimeServices compileTimeServices,
            out Assembly assembly)
        {
            // write code to create an implementation of StatementResource
            var statementFieldsClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(StatementFields),
                moduleIdentPostfix);
            var namespaceScope = new CodegenNamespaceScope(
                compileTimeServices.Namespace,
                statementFieldsClassName,
                compileTimeServices.IsInstrumented());
            var moduleClassName = CodeGenerationIDGenerator.GenerateClassNameSimple(
                typeof(ModuleProvider),
                moduleIdentPostfix);
            var classScope = new CodegenClassScope(true, namespaceScope, moduleClassName);
            var methods = new CodegenClassMethods();
            var properties = new CodegenClassProperties();

            // provide module name
            var moduleNameProp = CodegenProperty.MakePropertyNode(
                typeof(string),
                typeof(EPCompilerImpl),
                CodegenSymbolProviderEmpty.INSTANCE,
                classScope);
            moduleNameProp.GetterBlock.BlockReturn(Constant(optionalModuleName));

            // provide module properties
            var modulePropertiesProp = CodegenProperty.MakePropertyNode(
                typeof(IDictionary<ModuleProperty, object>),
                typeof(EPCompilerImpl),
                CodegenSymbolProviderEmpty.INSTANCE,
                classScope);
            MakeModuleProperties(moduleProperties, modulePropertiesProp);

            // provide module dependencies
            var moduleDependenciesProp = CodegenProperty.MakePropertyNode(
                typeof(ModuleDependenciesRuntime),
                typeof(EPCompilerImpl),
                CodegenSymbolProviderEmpty.INSTANCE,
                classScope);
            compileTimeServices.ModuleDependencies.Inject(moduleDependenciesProp.GetterBlock);

            // register types
            var initializeEventTypesMethod = MakeInitEventTypes(classScope, compileTimeServices);

            // register named windows
            var symbolsNamedWindowInit = new ModuleNamedWindowInitializeSymbol();
            var initializeNamedWindowsMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsNamedWindowInit, classScope)
                .AddParam(
                    typeof(EPModuleNamedWindowInitServices),
                    ModuleNamedWindowInitializeSymbol.REF_INITSVC.Ref);
            foreach (var namedWindow in compileTimeServices.NamedWindowCompileTimeRegistry.NamedWindows) {
                var addNamedWindow = RegisterNamedWindowCodegen(
                    namedWindow,
                    initializeNamedWindowsMethod,
                    classScope,
                    symbolsNamedWindowInit);
                initializeNamedWindowsMethod.Block.Expression(LocalMethod(addNamedWindow));
            }

            // register tables
            var symbolsTableInit = new ModuleTableInitializeSymbol();
            var initializeTablesMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsTableInit, classScope)
                .AddParam(typeof(EPModuleTableInitServices), ModuleTableInitializeSymbol.REF_INITSVC.Ref);
            foreach (var table in compileTimeServices.TableCompileTimeRegistry.Tables) {
                var addTable = RegisterTableCodegen(table, initializeTablesMethod, classScope, symbolsTableInit);
                initializeTablesMethod.Block.Expression(LocalMethod(addTable));
            }

            // register indexes
            var symbolsIndexInit = new ModuleIndexesInitializeSymbol();
            var initializeIndexesMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsIndexInit, classScope)
                .AddParam(typeof(EPModuleIndexInitServices), EPModuleIndexInitServicesConstants.REF.Ref);
            foreach (KeyValuePair<IndexCompileTimeKey, IndexDetailForge> index in compileTimeServices
                .IndexCompileTimeRegistry.Indexes) {
                var addIndex = RegisterIndexCodegen(index, initializeIndexesMethod, classScope, symbolsIndexInit);
                initializeIndexesMethod.Block.Expression(LocalMethod(addIndex));
            }

            // register contexts
            var symbolsContextInit = new ModuleContextInitializeSymbol();
            var initializeContextsMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsContextInit, classScope)
                .AddParam(
                    typeof(EPModuleContextInitServices),
                    ModuleContextInitializeSymbol.REF_INITSVC.Ref);
            foreach (var context in compileTimeServices.ContextCompileTimeRegistry.Contexts) {
                var addContext = RegisterContextCodegen(
                    context,
                    initializeContextsMethod,
                    classScope,
                    symbolsContextInit);
                initializeContextsMethod.Block.Expression(LocalMethod(addContext));
            }

            // register variables
            var symbolsVariablesInit = new ModuleVariableInitializeSymbol();
            var initializeVariablesMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsVariablesInit, classScope)
                .AddParam(
                    typeof(EPModuleVariableInitServices),
                    ModuleVariableInitializeSymbol.REF_INITSVC.Ref);
            foreach (var variable in compileTimeServices.VariableCompileTimeRegistry.Variables) {
                var addVariable = RegisterVariableCodegen(
                    variable,
                    initializeVariablesMethod,
                    classScope,
                    symbolsVariablesInit);
                initializeVariablesMethod.Block.Expression(LocalMethod(addVariable));
            }

            // register expressions
            var symbolsExprDeclaredInit = new ModuleExpressionDeclaredInitializeSymbol();
            var initializeExprDeclaredMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsExprDeclaredInit, classScope)
                .AddParam(
                    typeof(EPModuleExprDeclaredInitServices),
                    ModuleExpressionDeclaredInitializeSymbol.REF_INITSVC.Ref);
            foreach (var expression in compileTimeServices.ExprDeclaredCompileTimeRegistry.Expressions) {
                var addExpression = RegisterExprDeclaredCodegen(
                    expression,
                    initializeExprDeclaredMethod,
                    classScope,
                    symbolsExprDeclaredInit);
                initializeExprDeclaredMethod.Block.Expression(LocalMethod(addExpression));
            }

            // register scripts
            var symbolsScriptInit = new ModuleScriptInitializeSymbol();
            var initializeScriptsMethod = CodegenMethod
                .MakeMethod(typeof(void), typeof(EPCompilerImpl), symbolsScriptInit, classScope)
                .AddParam(typeof(EPModuleScriptInitServices), ModuleScriptInitializeSymbol.REF_INITSVC.Ref);
            foreach (var expression in compileTimeServices.ScriptCompileTimeRegistry.Scripts) {
                var addScript = RegisterScriptCodegen(
                    expression,
                    initializeScriptsMethod,
                    classScope,
                    symbolsScriptInit);
                initializeScriptsMethod.Block.Expression(LocalMethod(addScript));
            }

            // register provided classes
            var symbolsClassProvidedInit = new ModuleClassProvidedInitializeSymbol();
            var initializeClassProvidedMethod = CodegenMethod
                .MakeParentNode(typeof(void), typeof(EPCompilerImpl), symbolsClassProvidedInit, classScope)
                .AddParam(typeof(EPModuleClassProvidedInitServices), ModuleClassProvidedInitializeSymbol.REF_INITSVC.Ref);
            foreach (var currClazz in compileTimeServices.ClassProvidedCompileTimeRegistry.Classes) {
                var addClassProvided = RegisterClassProvidedCodegen(
                    currClazz,
                    initializeClassProvidedMethod,
                    classScope,
                    symbolsClassProvidedInit);
                initializeClassProvidedMethod.Block.Expression(LocalMethod(addClassProvided));
            }
            
            // instantiate factories for statements
            var statementsProp = CodegenProperty.MakePropertyNode(
                typeof(IList<StatementProvider>),
                typeof(EPCompilerImpl),
                CodegenSymbolProviderEmpty.INSTANCE,
                classScope);
            statementsProp.GetterBlock.DeclareVar<IList<StatementProvider>>(
                "statements",
                NewInstance(typeof(List<StatementProvider>), Constant(statementClassNames.Count)));
            foreach (var statementClassName in statementClassNames) {
                statementsProp.GetterBlock.ExprDotMethod(
                    Ref("statements"),
                    "Add",
                    NewInstanceInner(statementClassName));
            }

            statementsProp.GetterBlock.BlockReturn(Ref("statements"));

            // build stack
            CodegenStackGenerator.RecursiveBuildStack(
                moduleNameProp,
                "ModuleName",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                modulePropertiesProp,
                "ModuleProperties",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                moduleDependenciesProp,
                "ModuleDependencies",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeEventTypesMethod,
                "InitializeEventTypes",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeNamedWindowsMethod,
                "InitializeNamedWindows",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeTablesMethod,
                "InitializeTables",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeIndexesMethod,
                "InitializeIndexes",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeContextsMethod,
                "InitializeContexts",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeVariablesMethod,
                "InitializeVariables",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeExprDeclaredMethod,
                "InitializeExprDeclareds",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeScriptsMethod,
                "InitializeScripts",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                initializeClassProvidedMethod,
                "InitializeClassProvided",
                methods,
                properties);
            CodegenStackGenerator.RecursiveBuildStack(
                statementsProp,
                "Statements",
                methods,
                properties);

            var clazz = new CodegenClass(
                CodegenClassType.MODULEPROVIDER,
                typeof(ModuleProvider),
                moduleClassName,
                classScope,
                new EmptyList<CodegenTypedParam>(),
                null,
                methods,
                properties,
                new EmptyList<CodegenInnerClass>());
            
            var container = compileTimeServices.Container;
            var compiler = container
                .RoslynCompiler()
                .WithCodeLogging(compileTimeServices.Configuration.Compiler.Logging.IsEnableCode)
                .WithCodeAuditDirectory(compileTimeServices.Configuration.Compiler.Logging.AuditDirectory)
                .WithCodegenClasses(new[] {clazz});

            assembly = compiler.Compile();

            return CodeGenerationIDGenerator.GenerateClassNameWithNamespace(
                compileTimeServices.Namespace,
                typeof(ModuleProvider),
                moduleIdentPostfix);
        }