/// <summary> /// Проверить состояние переменной, найти зависимые пеменные, скомпилировать при необходимости /// </summary> /// <param name="allVariables"></param> public void Compile(IEnumerable <MetaVariable <H, I> > allVariables) { ValidateVariable(); FindDependentVariables(allVariables); CompileInternal(); State = CompilationState.Compiled; }
internal override bool TryEvaluate(Stack <Context> contextStack, CompilationState state, out Context context) { //Add the Identifier to the current context var memberSymbol = contextStack.Any() ? contextStack.Peek().Symbol.FindMember(_value) : state.Introspector.GetTypeSymbol(_value); if (memberSymbol != null) { var identifierContext = new Context(string.Join(".", contextStack.Peek().FullPath, _value), memberSymbol); if (_next == null) { //Last element => return IdentifierContext context = identifierContext; return(true); } else { //Push the identifier on the contextStack and keep going contextStack.Push(identifierContext); return(_next.TryEvaluate(contextStack, state, out context)); } } else { state.AddTypeError($"Could not find Member '{_value}' in Type '{contextStack.Peek().Symbol.ToDisplayString()}'!", HandlebarsTypeErrorKind.UnknownMember); context = null; return(false); } }
internal override bool TryEvaluate(CompilationState state, out Context context) { //Copy Stack as identifier elements manipulate (push, pop) var cpContextStack = new Stack <Context>(); cpContextStack = new Stack <Context>(state.ContextStack.Reverse()); return(Path.TryEvaluate(cpContextStack, state, out context)); }
protected bool InsideEachLoopCheck(CompilationState state) { if (state.LoopLevel > 0) { return(true); } state.AddTypeError("SpecialExpressions can only exist inside EachBlocks", HandlebarsTypeErrorKind.SpecialExpressionOutsideEachLoop); return(false); }
public void CloseMethod(BoundStatement body) { Debug.Assert((object)CurrentMethod != null); if (body.Kind != BoundKind.Block) { body = Block(body); } CompilationState.AddSynthesizedMethod(CurrentMethod, body); CurrentMethod = null; }
internal override bool TryEvaluate(Stack <Context> contextStack, CompilationState state, out Context context) { if (!contextStack.Any() || contextStack.Count == 1) { state.AddTypeError("Error in MemberExpression: Empty ContextStack but PathUp Element ('../')!", HandlebarsTypeErrorKind.EmptyContextStack); context = null; return(false); } contextStack.Pop(); return(_next.TryEvaluate(contextStack, state, out context)); }
private Operation GetNextOperation(CompilationState currentState) { return(currentState switch { CompilationState.NotScheduled => Operation.Execute, CompilationState.Building => Operation.Cancel, CompilationState.Scheduled => Operation.None, CompilationState.Executing => Operation.Cancel, CompilationState.Finished => Operation.Execute, CompilationState.Crashed => Operation.Execute, _ => throw new ArgumentOutOfRangeException("currentState") });
internal override bool TryEvaluate(Stack <Context> contextStack, CompilationState state, out Context context) { if (_next == null) { context = contextStack.Peek(); return(true); } else { return(_next.TryEvaluate(contextStack, state, out context)); } }
public override void SetNewContextChildren() { if (this.m_gaugeMember != null) { this.m_gaugeMember.ResetContext(); } if (this.m_gaugeRowMember != null) { this.m_gaugeRowMember.ResetContext(); } if (this.m_gaugeRowCollection != null) { this.m_gaugeRowCollection.SetNewContext(); } if (base.m_instance != null) { base.m_instance.SetNewContext(); } if (this.m_linearGauges != null) { this.m_linearGauges.SetNewContext(); } if (this.m_radialGauges != null) { this.m_radialGauges.SetNewContext(); } if (this.m_numericIndicators != null) { this.m_numericIndicators.SetNewContext(); } if (this.m_stateIndicators != null) { this.m_stateIndicators.SetNewContext(); } if (this.m_gaugeImages != null) { this.m_gaugeImages.SetNewContext(); } if (this.m_gaugeLabels != null) { this.m_gaugeLabels.SetNewContext(); } if (this.m_backFrame != null) { this.m_backFrame.SetNewContext(); } if (this.m_topImage != null) { this.m_topImage.SetNewContext(); } this.m_compilationState = CompilationState.NotCompiled; }
/// <summary> /// Will evaluate to a context inside a loop. Used for the context inside #each blocks /// </summary> /// <param name="state"></param> /// <returns></returns> internal Context EvaluateLoop(CompilationState state) { Context loopVariable; if (TryEvaluate(state, out loopVariable)) { var elementSymbol = loopVariable.Symbol.GetElementSymbol(); if (elementSymbol != null) { return(state.BuildLoopContext(loopVariable.Symbol.GetElementSymbol())); } } return(null); }
internal override bool TryEvaluate(Stack <Context> contextStack, CompilationState state, out Context context) { if (_next == null) { context = contextStack.Last(); return(true); } else { var rootedContextStack = new Stack <Context>(); rootedContextStack.Push(contextStack.Last()); return(_next.TryEvaluate(rootedContextStack, state, out context)); } }
internal override bool TryEvaluate(CompilationState state, out Context context) { var ctLoopContext = IsCompileTimeLoop(state); if (ctLoopContext != null) {//Inside CTLoop -> Return literal context = new Context(ctLoopContext.Index.ToString(), state.Introspector.GetIntTypeSymbol()); return(true); } else { context = new Context($"index{state.LoopLevel}", state.Introspector.GetIntTypeSymbol()); return(InsideEachLoopCheck(state)); } }
internal override bool TryEvaluate(CompilationState state, out Context context) { var ctLoopContext = IsCompileTimeLoop(state); if (ctLoopContext != null) { context = new Context($"\"{ctLoopContext.Key}\"", state.Introspector.GetStringTypeSymbol()); return(true); } else { state.AddTypeError("KeyExpression outside a compiletime loop over an Object", HandlebarsTypeErrorKind.IllegalKeyExpression); context = null; return(false); } }
internal void ProcessCompiledInstances() { if (RequiresCompilation && m_compilationState == CompilationState.NotCompiled) { try { m_compilationState = CompilationState.Compiling; GaugeMapperFactory.CreateGaugeMapperInstance(this, base.RenderingContext.OdpContext.ReportDefinition.DefaultFontFamily).RenderDataGaugePanel(); m_compilationState = CompilationState.Compiled; } catch (Exception innerException) { m_compilationState = CompilationState.NotCompiled; throw new RenderingObjectModelException(innerException); } } }
public CompilationResult Compile() { if (this.state != CompilationState.None) { throw new InvalidOperationException(); } this.state = CompilationState.Compiling; try { //すべて読み込み var trees = this.sources.AsParallel() .Select(s => CSharpSyntaxTree.ParseText(s)) .ToArray(); this.diagnostics.AddRange(trees.SelectMany(t => t.GetDiagnostics())); if (this.diagnostics.Any(d => d.IsWarningAsError)) { return(CompilationResult.ParsingError); } //すべてのクラスを取得(partial クラスに対応するため) var classes = this.GetAllClasses(trees); foreach (var ci in classes) { switch (ci.Type) { case ClassType.Class: this.createdClasses.Add(this.MakeClass(ci)); break; } } return(this.diagnostics.Any(d => d.IsWarningAsError) ? CompilationResult.ConvertingError : CompilationResult.Success); } finally { this.state = CompilationState.Completed; } }
private Operation GetNextOperation(CompilationState currentState) { switch (currentState) { case CompilationState.NotScheduled: return(Operation.Execute); case CompilationState.Scheduled: return(Operation.None); case CompilationState.Executing: return(Operation.Cancel); case CompilationState.Finished: return(Operation.Execute); case CompilationState.Crashed: return(Operation.Execute); default: throw new ArgumentOutOfRangeException("currentState"); } }
/// <inheritdoc /> public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze); context.RegisterCompilationStartAction(start => { var state = new CompilationState( Flatten( start.Compilation.GetTypeByMetadataName(Types.Package.FullName)?.GetMembers(Types.Package.GetService), start.Compilation.GetTypeByMetadataName(Types.AsyncPackage.FullName)?.GetMembers(Types.AsyncPackage.GetServiceAsync), start.Compilation.GetTypeByMetadataName(Types.AsyncPackage.FullName)?.GetMembers(Types.Package.GetService), start.Compilation.GetTypeByMetadataName(Types.ServiceProvider.FullName)?.GetMembers(Types.ServiceProvider.GetService), start.Compilation.GetTypeByMetadataName(Types.IServiceProvider.FullName)?.GetMembers(Types.IServiceProvider.GetService), start.Compilation.GetTypeByMetadataName(Types.IAsyncServiceProvider.FullName)?.GetMembers(Types.IAsyncServiceProvider.GetServiceAsync)), Flatten( start.Compilation.GetTypeByMetadataName(Types.Assumes.FullName)?.GetMembers(Types.Assumes.Present))); if (state.ShouldAnalyze) { start.RegisterSyntaxNodeAction(state.AnalyzeInvocationExpression, SyntaxKind.InvocationExpression); } }); }
public MetaVariable() { DependsOn = new List <MetaVariable <H, I> >(); State = CompilationState.NotCompiled; Readers = new List <Action <TimeArg <I> > >(); }
protected CompileTimeLoopContext IsCompileTimeLoop(CompilationState state) { return(state.ContextStack.Peek() as CompileTimeLoopContext); }
internal abstract bool TryEvaluate(Stack <Context> contextStack, CompilationState state, out Context context);
/// <summary> /// Introduce a frame around the translation of the given node. /// </summary> /// <param name="node">The node whose translation should be translated to contain a frame</param> /// <param name="frame">The frame for the translated node</param> /// <param name="F">A function that computes the translation of the node. It receives lists of added statements and added symbols</param> /// <returns>The translated statement, as returned from F</returns> private T IntroduceFrame <T>(BoundNode node, LambdaFrame frame, Func <ArrayBuilder <BoundExpression>, ArrayBuilder <LocalSymbol>, T> F) { NamedTypeSymbol frameType = frame.ConstructIfGeneric(StaticCast <TypeSymbol> .From(currentTypeParameters)); LocalSymbol framePointer = new LambdaFrameLocalSymbol(this.topLevelMethod, frameType, CompilationState); CSharpSyntaxNode syntax = node.Syntax; // assign new frame to the frame variable CompilationState.AddSynthesizedMethod(frame.Constructor, FlowAnalysisPass.AppendImplicitReturn(MethodCompiler.BindMethodBody(frame.Constructor, CompilationState, null), frame.Constructor)); var prologue = ArrayBuilder <BoundExpression> .GetInstance(); MethodSymbol constructor = frame.Constructor.AsMember(frameType); Debug.Assert(frameType == constructor.ContainingType); var newFrame = new BoundObjectCreationExpression( syntax: syntax, constructor: constructor); prologue.Add(new BoundAssignmentOperator(syntax, new BoundLocal(syntax, framePointer, null, frameType), newFrame, frameType)); CapturedSymbolReplacement oldInnermostFrameProxy = null; if ((object)innermostFramePointer != null) { proxies.TryGetValue(innermostFramePointer, out oldInnermostFrameProxy); if (analysis.needsParentFrame.Contains(node)) { var capturedFrame = new LambdaCapturedVariable(frame, innermostFramePointer); FieldSymbol frameParent = capturedFrame.AsMember(frameType); BoundExpression left = new BoundFieldAccess(syntax, new BoundLocal(syntax, framePointer, null, frameType), frameParent, null); BoundExpression right = FrameOfType(syntax, frameParent.Type as NamedTypeSymbol); BoundExpression assignment = new BoundAssignmentOperator(syntax, left, right, left.Type); if (this.currentMethod.MethodKind == MethodKind.Constructor && capturedFrame.Type == this.currentMethod.ContainingType && !this.seenBaseCall) { // Containing method is a constructor // Initialization statement for the "this" proxy must be inserted // after the constructor initializer statement block // This insertion will be done by the delegate F Debug.Assert(thisProxyInitDeferred == null); thisProxyInitDeferred = assignment; } else { prologue.Add(assignment); } if (CompilationState.Emitting) { CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(frame, capturedFrame); } proxies[innermostFramePointer] = new CapturedToFrameSymbolReplacement(capturedFrame); } } // Capture any parameters of this block. This would typically occur // at the top level of a method or lambda with captured parameters. // TODO: speed up the following by computing it in analysis. foreach (var v in analysis.variablesCaptured) { BoundNode varNode; if (!analysis.variableBlock.TryGetValue(v, out varNode) || varNode != node || analysis.declaredInsideExpressionLambda.Contains(v)) { continue; } InitVariableProxy(syntax, v, framePointer, prologue); } Symbol oldInnermostFramePointer = innermostFramePointer; innermostFramePointer = framePointer; var addedLocals = ArrayBuilder <LocalSymbol> .GetInstance(); addedLocals.Add(framePointer); framePointers.Add(frame, framePointer); var result = F(prologue, addedLocals); framePointers.Remove(frame); innermostFramePointer = oldInnermostFramePointer; if ((object)innermostFramePointer != null) { if (oldInnermostFrameProxy != null) { proxies[innermostFramePointer] = oldInnermostFrameProxy; } else { proxies.Remove(innermostFramePointer); } } return(result); }
private FieldSymbol GetAwaiterField(TypeSymbol awaiterType) { FieldSymbol result; if (!awaiterFields.TryGetValue(awaiterType, out result)) { result = F.StateMachineField(awaiterType, GeneratedNames.AsyncAwaiterFieldName(CompilationState.GenerateTempNumber()), isPublic: true); awaiterFields.Add(awaiterType, result); } return(result); }
private BoundNode RewriteLambdaConversion(BoundLambda node) { var wasInExpressionLambda = inExpressionLambda; inExpressionLambda = inExpressionLambda || node.Type.IsExpressionTree(); if (inExpressionLambda) { var newType = VisitType(node.Type); var newBody = (BoundBlock)Visit(node.Body); node = node.Update(node.Symbol, newBody, node.Diagnostics, node.Binder, newType); var result0 = wasInExpressionLambda ? node : ExpressionLambdaRewriter.RewriteLambda(node, CompilationState, Diagnostics); inExpressionLambda = wasInExpressionLambda; return(result0); } NamedTypeSymbol translatedLambdaContainer; BoundNode lambdaScope = null; if (analysis.lambdaScopes.TryGetValue(node.Symbol, out lambdaScope)) { translatedLambdaContainer = frames[lambdaScope]; } else { translatedLambdaContainer = topLevelMethod.ContainingType; } // Move the body of the lambda to a freshly generated synthetic method on its frame. bool lambdaIsStatic = analysis.captures[node.Symbol].IsEmpty(); var synthesizedMethod = new SynthesizedLambdaMethod(translatedLambdaContainer, topLevelMethod, node, lambdaIsStatic, CompilationState); if (CompilationState.Emitting) { CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(translatedLambdaContainer, synthesizedMethod); } for (int i = 0; i < node.Symbol.ParameterCount; i++) { parameterMap.Add(node.Symbol.Parameters[i], synthesizedMethod.Parameters[i]); } // rewrite the lambda body as the generated method's body var oldMethod = currentMethod; var oldFrameThis = currentFrameThis; var oldTypeParameters = currentTypeParameters; var oldInnermostFramePointer = innermostFramePointer; var oldTypeMap = currentLambdaBodyTypeMap; var oldAddedStatements = addedStatements; var oldAddedLocals = addedLocals; addedStatements = null; addedLocals = null; // switch to the generated method currentMethod = synthesizedMethod; if (lambdaIsStatic) { // no link from a static lambda to its container innermostFramePointer = currentFrameThis = null; } else { currentFrameThis = synthesizedMethod.ThisParameter; innermostFramePointer = null; framePointers.TryGetValue(translatedLambdaContainer, out innermostFramePointer); } if (translatedLambdaContainer.OriginalDefinition is LambdaFrame) { currentTypeParameters = translatedLambdaContainer.TypeParameters; currentLambdaBodyTypeMap = ((LambdaFrame)translatedLambdaContainer).TypeMap; } else { currentTypeParameters = synthesizedMethod.TypeParameters; currentLambdaBodyTypeMap = new TypeMap(topLevelMethod.TypeParameters, currentTypeParameters); } var body = AddStatementsIfNeeded((BoundStatement)VisitBlock(node.Body)); CheckLocalsDefined(body); CompilationState.AddSynthesizedMethod(synthesizedMethod, body); // return to the old method currentMethod = oldMethod; currentFrameThis = oldFrameThis; currentTypeParameters = oldTypeParameters; innermostFramePointer = oldInnermostFramePointer; currentLambdaBodyTypeMap = oldTypeMap; addedLocals = oldAddedLocals; addedStatements = oldAddedStatements; // Rewrite the lambda expression (and the enclosing anonymous method conversion) as a delegate creation expression NamedTypeSymbol constructedFrame = (translatedLambdaContainer is LambdaFrame) ? translatedLambdaContainer.ConstructIfGeneric(StaticCast <TypeSymbol> .From(currentTypeParameters)) : translatedLambdaContainer; BoundExpression receiver = lambdaIsStatic ? new BoundTypeExpression(node.Syntax, null, constructedFrame) : FrameOfType(node.Syntax, constructedFrame); MethodSymbol referencedMethod = synthesizedMethod.AsMember(constructedFrame); if (referencedMethod.IsGenericMethod) { referencedMethod = referencedMethod.Construct(StaticCast <TypeSymbol> .From(currentTypeParameters)); } TypeSymbol type = this.VisitType(node.Type); BoundExpression result = new BoundDelegateCreationExpression( node.Syntax, receiver, referencedMethod, isExtensionMethod: false, type: type); // if the block containing the lambda is not the innermost block, // or the lambda is static, then the lambda object should be cached in its frame. // NOTE: we are not caching static lambdas in static ctors - cannot reuse such cache. var shouldCacheForStaticMethod = lambdaIsStatic && currentMethod.MethodKind != MethodKind.StaticConstructor && !referencedMethod.IsGenericMethod; // NOTE: We require "lambdaScope != null". // We do not want to introduce a field into an actual user's class (not a synthetic frame). var shouldCacheInLoop = lambdaScope != null && lambdaScope != analysis.blockParent[node.Body] && InLoopOrLambda(node.Syntax, lambdaScope.Syntax); if (shouldCacheForStaticMethod || shouldCacheInLoop) { // replace the expression "new Delegate(frame.M)" with "(frame.cache == null) ? (frame.cache = new Delegate(frame.M)) : frame.cache" var F = new SyntheticBoundNodeFactory(currentMethod, node.Syntax, CompilationState, Diagnostics); try { var cacheVariableName = GeneratedNames.MakeLambdaCacheName(CompilationState.GenerateTempNumber()); BoundExpression cacheVariable; if (shouldCacheForStaticMethod || shouldCacheInLoop && translatedLambdaContainer is LambdaFrame) { var cacheVariableType = lambdaIsStatic ? type : (translatedLambdaContainer as LambdaFrame).TypeMap.SubstituteType(type); var cacheField = new SynthesizedFieldSymbol(translatedLambdaContainer, cacheVariableType, cacheVariableName, isPublic: !lambdaIsStatic, isStatic: lambdaIsStatic); CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(translatedLambdaContainer, cacheField); cacheVariable = F.Field(receiver, cacheField.AsMember(constructedFrame)); //NOTE: the field was added to the unconstructed frame type. } else { // the lambda captures at most the "this" of the enclosing method. We cache its delegate in a local variable. var cacheLocal = F.SynthesizedLocal(type, cacheVariableName); if (addedLocals == null) { addedLocals = ArrayBuilder <LocalSymbol> .GetInstance(); } addedLocals.Add(cacheLocal); if (addedStatements == null) { addedStatements = ArrayBuilder <BoundStatement> .GetInstance(); } cacheVariable = F.Local(cacheLocal); addedStatements.Add(F.Assignment(cacheVariable, F.Null(type))); } result = F.Coalesce(cacheVariable, F.AssignmentExpression(cacheVariable, result)); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { Diagnostics.Add(ex.Diagnostic); return(new BoundBadExpression(F.Syntax, LookupResultKind.Empty, ImmutableArray <Symbol> .Empty, ImmutableArray.Create <BoundNode>(node), node.Type)); } } return(result); }
internal abstract bool TryEvaluate(CompilationState state, out Context context);
public CodeGenerationVisitor(RoslynIntrospector introspector, HandlebarsTemplate template) { state = new CompilationState(introspector, template); state.Introspector = introspector; }
public CompilationInstance(RootNode root) { _root = root; _state = new CompilationState(root); _visitor = new Visitor(); }
internal override bool TryEvaluate(CompilationState state, out Context context) { context = new Context($"\"{_value}\"", state.Introspector.GetStringTypeSymbol()); return(true); }