/// <summary> /// Visits the children of <see cref="System.Linq.Expressions.SwitchCase"/>. /// </summary> /// <param name="node">The expression to visit.</param> /// <returns>The modified expression, if it or any subexpression was modified; otherwise, /// returns the original expression.</returns> protected override SwitchCase VisitSwitchCase(SwitchCase node) { throw new NotSupportedException(string.Format(Resources.EX_PROCESS_NODE_NOT_SUPPORT, node.GetType().Name)); }
public virtual SwitchCase VisitSwitchCase(SwitchCase switchCase){ if (switchCase == null) return null; switchCase.Label = this.VisitExpression(switchCase.Label); switchCase.Body = this.VisitBlock(switchCase.Body); return switchCase; }
// SwitchCase protected internal virtual bool Walk(SwitchCase node) { return true; }
public override SwitchCase VisitSwitchCase(SwitchCase switchCase) { if (switchCase == null) return null; this.switchCaseCount++; switchCase.Body = this.VisitBlock(switchCase.Body); this.switchCaseCount--; return switchCase; }
private void GenerateDiscrValueOkTest(ILGenerator gen, SwitchCase switchCase, Label jumpOnOk, ConstructorInfo exceptionToThrowConstr, int exceptionMinorCode) { // check if discr value ok, special for default case if (!(SwitchCase.IsDefaultCase(switchCase.DiscriminatorValues))) { for (int i = 0; i < switchCase.DiscriminatorValues.Length; i++) { // generate compare + branch on ok to jumpOnOk gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, m_discrField); // fieldvalue of discriminator field PushDiscriminatorValueToStack(gen, switchCase.DiscriminatorValues[i]); gen.Emit(OpCodes.Beq, jumpOnOk); } } else { Label exceptionLabel = gen.DefineLabel(); // compare current discr val with all covered discr val, if matching -> not ok foreach (object discrVal in m_coveredDiscrs) { gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, m_discrField); // fieldvalue of discriminator field PushDiscriminatorValueToStack(gen, discrVal); gen.Emit(OpCodes.Beq, exceptionLabel); } // after all tests, no forbidden value for default case used -> jump to ok gen.Emit(OpCodes.Br, jumpOnOk); gen.MarkLabel(exceptionLabel); } // exception thrown if not ok gen.Emit(OpCodes.Ldc_I4, exceptionMinorCode); gen.Emit(OpCodes.Ldc_I4, (int)CompletionStatus.Completed_MayBe); gen.Emit(OpCodes.Newobj, exceptionToThrowConstr); gen.Emit(OpCodes.Throw); }
public virtual SwitchCase VisitSwitchCase(SwitchCase switchCase, Class scope, TrivialHashtable targetFor, IdentifierList labelList){ if (switchCase == null) return null; this.VisitBlock(switchCase.Body, scope, targetFor, labelList); return switchCase; }
public void Visit(SwitchCase node) { // invalid! ignore IsValid = false; }
public override void Visit(SwitchCase sc, JavaScriptExpressionCheckerState state) { RegisterWriter(sc.Evaluator.GetType(), typeof(ISwitchConditionEvaluator), state); base.Visit(sc, state); }
public override void Visit(SwitchCase sc, object state) { sc.Evaluator = _dialect.GetSwitchConditionEvaluator(sc.Condition, _manager); base.Visit(sc, null); }
private static SwitchCase VisitSwitchCase(SwitchCase node) { throw new NotImplementedException(); }
/// <inheritdoc /> protected override LambdaExpression GenerateMaterializationCondition(IEntityType entityType, bool nullable) { LambdaExpression baseCondition; if (entityType.FindDiscriminatorProperty() == null && entityType.GetDirectlyDerivedTypes().Any()) { // TPT var valueBufferParameter = Parameter(typeof(ValueBuffer)); var discriminatorValueVariable = Variable(typeof(string), "discriminator"); var expressions = new List <Expression> { Assign( discriminatorValueVariable, valueBufferParameter.CreateValueBufferReadValueExpression(typeof(string), 0, null)) }; var derivedConcreteEntityTypes = entityType.GetDerivedTypes().Where(dt => !dt.IsAbstract()).ToArray(); var switchCases = new SwitchCase[derivedConcreteEntityTypes.Length]; for (var i = 0; i < derivedConcreteEntityTypes.Length; i++) { var discriminatorValue = Constant(derivedConcreteEntityTypes[i].ShortName(), typeof(string)); switchCases[i] = SwitchCase(Constant(derivedConcreteEntityTypes[i], typeof(IEntityType)), discriminatorValue); } var defaultBlock = entityType.IsAbstract() ? CreateUnableToDiscriminateExceptionExpression(entityType, discriminatorValueVariable) : Constant(entityType, typeof(IEntityType)); expressions.Add(Switch(discriminatorValueVariable, defaultBlock, switchCases)); baseCondition = Lambda(Block(new[] { discriminatorValueVariable }, expressions), valueBufferParameter); } else { baseCondition = base.GenerateMaterializationCondition(entityType, nullable); } if (entityType.FindPrimaryKey() != null) { var table = entityType.GetViewOrTableMappings().FirstOrDefault()?.Table; if (table != null && table.IsOptional(entityType)) { // Optional dependent var body = baseCondition.Body; var valueBufferParameter = baseCondition.Parameters[0]; Expression?condition = null; var requiredNonPkProperties = entityType.GetProperties().Where(p => !p.IsNullable && !p.IsPrimaryKey()).ToList(); if (requiredNonPkProperties.Count > 0) { condition = requiredNonPkProperties .Select( p => NotEqual( valueBufferParameter.CreateValueBufferReadValueExpression(typeof(object), p.GetIndex(), p), Constant(null))) .Aggregate((a, b) => AndAlso(a, b)); } var allNonPrincipalSharedNonPkProperties = entityType.GetNonPrincipalSharedNonPkProperties(table); // We don't need condition for nullable property if there exist at least one required property which is non shared. if (allNonPrincipalSharedNonPkProperties.Count != 0 && allNonPrincipalSharedNonPkProperties.All(p => p.IsNullable)) { var atLeastOneNonNullValueInNullablePropertyCondition = allNonPrincipalSharedNonPkProperties .Select( p => NotEqual( valueBufferParameter.CreateValueBufferReadValueExpression(typeof(object), p.GetIndex(), p), Constant(null))) .Aggregate((a, b) => OrElse(a, b)); condition = condition == null ? atLeastOneNonNullValueInNullablePropertyCondition : AndAlso(condition, atLeastOneNonNullValueInNullablePropertyCondition); } if (condition != null) { body = Condition(condition, body, Default(typeof(IEntityType))); } return(Lambda(body, valueBufferParameter)); } } return(baseCondition); }
public void SwitchCaseUpdateNullTestsToSame() { SwitchCase sc = Expression.SwitchCase(Expression.Constant(0), Expression.Constant(1)); AssertExtensions.Throws<ArgumentException>("testValues", () => sc.Update(null, sc.Body)); AssertExtensions.Throws<ArgumentNullException>("body", () => sc.Update(sc.TestValues, null)); }
// SwitchStatement private Result RewriteSwitchExpression(Expression expr, Stack stack) { SwitchExpression node = (SwitchExpression)expr; // The switch statement test is emitted on the stack in current state Result switchValue = RewriteExpressionFreeTemps(node.SwitchValue, stack); RewriteAction action = switchValue.Action; ReadOnlyCollection <SwitchCase> cases = node.Cases; SwitchCase[] clone = null; for (int i = 0; i < cases.Count; i++) { SwitchCase @case = cases[i]; Expression[] cloneTests = null; ReadOnlyCollection <Expression> testValues = @case.TestValues; for (int j = 0; j < testValues.Count; j++) { // All tests execute at the same stack state as the switch. // This is guarenteed by the compiler (to simplify spilling) Result test = RewriteExpression(testValues[j], stack); action |= test.Action; if (cloneTests == null && test.Action != RewriteAction.None) { cloneTests = Clone(testValues, j); } if (cloneTests != null) { cloneTests[j] = test.Node; } } // And all the cases also run on the same stack level. Result body = RewriteExpression(@case.Body, stack); action |= body.Action; if (body.Action != RewriteAction.None || cloneTests != null) { if (cloneTests != null) { testValues = new ReadOnlyCollection <Expression>(cloneTests); } @case = CreateSwitchCase(body.Node, testValues); if (clone == null) { clone = Clone(cases, i); } } if (clone != null) { clone[i] = @case; } } // default body also runs on initial stack Result defaultBody = RewriteExpression(node.DefaultBody, stack); action |= defaultBody.Action; if (action != RewriteAction.None) { if (clone != null) { // okay to wrap because we aren't modifying the array cases = new ReadOnlyCollection <SwitchCase>(clone); } expr = CreateSwitchExpression(node.Type, switchValue.Node, defaultBody.Node, node.Comparison, cases); } return(new Result(action, expr)); }
/// <summary> /// Visits the children of the <see cref="T:System.Linq.Expressions.SwitchCase"/>. /// </summary> /// <returns> /// The modified expression, if it or any sub-Expression was modified; otherwise, returns the original /// Expression. /// </returns> /// <param name="node"> /// The expression to visit. /// </param> protected override SwitchCase VisitSwitchCase(SwitchCase node) { return(this.visitSwitchCase?.Invoke(node) ?? base.VisitSwitchCase(node)); }
public static Statement Switch(Expression cond, SwitchCase [] cases) { throw new NotImplementedException (); }
protected virtual SwitchCase VisitSwitchCase(SwitchCase node, Type expectedType) => node.Update(Visit(node.TestValues, null), Visit(node.Body, expectedType));
public virtual void PostWalk(SwitchCase node) { }
protected sealed override SwitchCase VisitSwitchCase(SwitchCase node) => VisitSwitchCase(node, CurrentExpectedType);
public virtual SwitchCase VisitSwitchCase(SwitchCase switchCase1, SwitchCase switchCase2) { if (switchCase1 == null) return null; if (switchCase2 == null) { switchCase1.Label = this.VisitExpression(switchCase1.Label, null); switchCase1.Body = this.VisitBlock(switchCase1.Body, null); } else { switchCase1.Label = this.VisitExpression(switchCase1.Label, switchCase2.Label); switchCase1.Body = this.VisitBlock(switchCase1.Body, switchCase2.Body); } return switchCase1; }
public void Visit(SwitchCase switchCase, object[] args) { }
public virtual void VisitSwitchCase(SwitchCase switchCase) { if (switchCase == null) return; this.VisitExpression(switchCase.Label); this.VisitBlock(switchCase.Body); }
protected abstract void WriteSwitchCase(SwitchCase switchCase);
public void GenerateCaseAction(ILGenerator gen, SwitchCase forCase, bool isDefaultCase) { m_ugh.GenerateAddFieldToObjectData(forCase.ElemField, gen, m_addValueMethod, m_getTypeFromH); }
protected override SwitchCase VisitSwitchCase(SwitchCase node) { throw new NotSupportedException(); }
private void GenerateModifierMethod(SwitchCase switchCase) { ParameterSpec[] parameters; ParameterSpec valArg = new ParameterSpec("val", switchCase.ElemType, ParameterSpec.ParameterDirection.s_in); if (switchCase.HasMoreThanOneDiscrValue()) { // need an additional parameter ParameterSpec discrArg = new ParameterSpec("discrVal", DiscriminatorType, ParameterSpec.ParameterDirection.s_in); parameters = new ParameterSpec[] { valArg, discrArg}; } else { // don't need an additional parameter parameters = new ParameterSpec[] { valArg }; } MethodBuilder modifier = m_ilEmitHelper.AddMethod(m_builder, "Set" + switchCase.ElemName, parameters, new TypeContainer(ReflectionHelper.VoidType), MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator gen = modifier.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stfld, m_initalizedField); // store initalizedfield gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Stfld, switchCase.ElemField); // store value field gen.Emit(OpCodes.Ldarg_0); if (switchCase.HasMoreThanOneDiscrValue()) { gen.Emit(OpCodes.Ldarg_2); } else { PushDiscriminatorValueToStack(gen, switchCase.DiscriminatorValues[0]); } gen.Emit(OpCodes.Stfld, m_discrField); // store discriminator field if (switchCase.HasMoreThanOneDiscrValue()) { // check, if discrvalue assigned is ok Label endMethodLabel = gen.DefineLabel(); GenerateDiscrValueOkTest(gen, switchCase, endMethodLabel, s_BadParamConstr, 34); gen.MarkLabel(endMethodLabel); } gen.Emit(OpCodes.Ret); }
// Tries to emit switch as a jmp table private bool TryEmitJumpTable(SwitchExpression node, Label[] labels, Label defaultTarget) { if (node.SwitchCases.Count > MaxJumpTableSize) { return(false); } int min = Int32.MaxValue; int max = Int32.MinValue; // Find the min and max of the values for (int i = 0; i < node.SwitchCases.Count; ++i) { // Not the default case. if (!node.SwitchCases[i].IsDefault) { int val = node.SwitchCases[i].Value; if (min > val) { min = val; } if (max < val) { max = val; } } } long delta = (long)max - (long)min; if (delta > MaxJumpTableSize) { return(false); } // Value distribution is too sparse, don't emit jump table. if (delta > node.SwitchCases.Count + MaxJumpTableSparsity) { return(false); } // The actual jmp table of switch int len = (int)delta + 1; Label[] jmpLabels = new Label[len]; // Initialize all labels to the default for (int i = 0; i < len; i++) { jmpLabels[i] = defaultTarget; } // Replace with the actual label target for all cases for (int i = 0; i < node.SwitchCases.Count; i++) { SwitchCase sc = node.SwitchCases[i]; if (!sc.IsDefault) { jmpLabels[sc.Value - min] = labels[i]; } } // Emit the normalized index and then switch based on that if (min != 0) { _ilg.EmitInt(min); _ilg.Emit(OpCodes.Sub); } _ilg.Emit(OpCodes.Switch, jmpLabels); return(true); }
public virtual SwitchCase GetClosestMatch(SwitchCase/*!*/ nd1, SwitchCaseList/*!*/ list1, SwitchCaseList list2, int list1pos, ref int list2start, TrivialHashtable/*!*/ matchedNodes, out Differences closestDifferences, out int list2pos) { closestDifferences = null; list2pos = -1; if (list2 == null) return null; if (nd1 == null || list1 == null || matchedNodes == null || list1pos < 0 || list1pos >= list1.Count || list2start < 0 || list2start >= list2.Count) { Debug.Assert(false); return null; } SwitchCase closest = null; Differences winnerSoFar = null; for (int j = list2start, m = list2.Count; j < m; j++){ SwitchCase nd2 = list2[j]; if (list2start == j) list2start++; if (nd2 == null) continue; if (matchedNodes[nd2.UniqueKey] != null) continue; Differences diff = this.GetDifferences(nd1, nd2); if (diff == null){Debug.Assert(false); continue;} if (diff.Similarity <= 0.5){ //Not a good enough match if (list2start == j+1) list2start--; //The next call to GetClosestMatch will start looking at list2start, so this node will be considered then continue; //ignore it for the rest of this call } if (winnerSoFar != null && winnerSoFar.Similarity >= diff.Similarity) continue; winnerSoFar = closestDifferences = diff; closest = nd2; list2pos = j; if (diff.NumberOfDifferences == 0) return closest; //Perfect match, no need to look for other matches } if (closest != null){ //^ assert winnerSoFar != null; //closest is closer to nd1 than any other node in list2, but this is no good if some other node in list1 has a better claim on closest for (int i = list1pos+1, n = list1.Count; i < n; i++){ SwitchCase nd1alt = list1[i]; if (nd1alt == null) continue; if (matchedNodes[nd1alt.UniqueKey] != null) continue; Differences diff = this.GetDifferences(nd1alt, closest); if (diff == null){Debug.Assert(false); continue;} if (diff.Similarity <= winnerSoFar.Similarity) continue; //nd1alt has a better claim on closest. See if it wants closest. Differences diff2; int j, k = list2start; SwitchCase nd2alt = this.GetClosestMatch(nd1alt, list1, list2, i, ref k, matchedNodes, out diff2, out j); if (nd2alt != closest){ Debug.Assert(nd2alt != null && diff2 != null && diff2.Similarity >= diff.Similarity); continue; //nd1alt prefers nd2alt to closest, so closest is still available } //nd1alt wants closest, take it out of the running matchedNodes[closest.UniqueKey] = nd1alt; //Now that closest is out of the running, try again k = list2start; SwitchCase newClosest = this.GetClosestMatch(nd1, list1, list2, i, ref k, matchedNodes, out winnerSoFar, out list2pos); //put closest back in the running so that the next call to this routine will pick it up matchedNodes[closest.UniqueKey] = closest; closest = newClosest; break; } } closestDifferences = winnerSoFar; return closest; }
public virtual bool VisitSwitchCase(SwitchCase stmt) { throw new NotImplementedException(); }
public virtual SwitchCase VisitSwitchCase(SwitchCase switchCase, SwitchCase changes, SwitchCase deletions, SwitchCase insertions){ this.UpdateSourceContext(switchCase, changes); if (switchCase == null) return changes; if (changes != null){ if (deletions == null || insertions == null) Debug.Assert(false); else{ } }else if (deletions != null) return null; return switchCase; }
public virtual bool Walk(SwitchCase node) { return(true); }
public void Visit(SwitchCase node) { if (node != null) { if (node.CaseValue != null) { node.CaseValue.Accept(this); } if (node.Statements != null) { node.Statements.Accept(this); } } }
public virtual bool Walk(SwitchCase node) { return true; }
private GotoStatement CreateCaseGoto(GotoStatement node, SwitchCase targetedCase) { return(new CaseGotoStatement(node, (SwitchCase)targetedCase.CloneStatementOnly())); }
Switch ParseSwitch() { //PRE: !EOF && _current == '#' var sw = new Switch(); MoveNext(); //Take '#' var lparen = LookAheadFor(StoppersTemplatedSwitchName); if (lparen == '(') { //The first stopper was a '('. Read the switch's template name sw.SwitchTemplateName = ReadText(StoppersParameterNameTemplatedSwitch); MoveNext(); // Take '(' sw.ParameterName = ReadText(StoppersParameterNameTemplatedSwitch); if (_current == ':') { MoveNext(); //Take ':' sw.ParameterFormat = ReadText(StoppersParameterFormatTemplatedSwitch); } if (_current != ')') { ExpectedToken("TemplatedSwitch", ")"); } MoveNext(); // Take ')' } else { sw.ParameterName = ReadParameterName(); if (_current == ':') { MoveNext(); //Take ':' sw.ParameterFormat = ReadParameterFormat(); } } if (_current != '{') ExpectedToken("Switch", "{"); MoveNext(); // Take '{' while (_current != '}') { if (_current == '?') { MoveNext(); // Take '?' TakeWhitespace(); sw.NullExpression = ParseExpression(); } else { TakeWhitespace(); var switchCase = new SwitchCase(); var stopper = LookAheadFor(StoppersSwitchCase); if (stopper == ':') { switchCase.Condition = Expression.Text(ReadText(":")); MoveNext(); //Take ':' } switchCase.Expression = ParseExpression(); sw.Cases.Add(switchCase); } if (_current == '|') { MoveNext(); //Take '|' } else if (_current != '}') { UnexpectedSwitchToken(sw.ParameterName, "" + _current); } } MoveNext(); // Take '}' return sw; }
internal Expression Reduce(bool shouldInterpret, bool emitDebugSymbols, int compilationThreshold, IList <ParameterExpression> parameters, Func <Expression <Func <MutableTuple, object> >, Expression <Func <MutableTuple, object> > > bodyConverter) { _state = LiftVariable(Expression.Parameter(typeof(int), "state")); _current = LiftVariable(Expression.Parameter(typeof(object), "current")); // lift the parameters into the tuple foreach (ParameterExpression pe in parameters) { LiftVariable(pe); } DelayedTupleExpression liftedGen = LiftVariable(_generatorParam); // Visit body Expression body = Visit(_body); Debug.Assert(_returnLabels.Count == 1); // Add the switch statement to the body int count = _yields.Count; var cases = new SwitchCase[count + 1]; for (int i = 0; i < count; i++) { cases[i] = Expression.SwitchCase(Expression.Goto(_yields[i].Label), AstUtils.Constant(_yields[i].State)); } cases[count] = Expression.SwitchCase(Expression.Goto(_returnLabels.Peek()), AstUtils.Constant(Finished)); // Create the lambda for the PythonGeneratorNext, hoisting variables // into a tuple outside the lambda Expression[] tupleExprs = new Expression[_vars.Count]; foreach (var variable in _orderedVars) { // first 2 are our state & out var if (variable.Value.Index >= 2 && variable.Value.Index < (parameters.Count + 2)) { tupleExprs[variable.Value.Index] = parameters[variable.Value.Index - 2]; } else { tupleExprs[variable.Value.Index] = Expression.Default(variable.Key.Type); } } Expression newTuple = MutableTuple.Create(tupleExprs); Type tupleType = _tupleType.Value = newTuple.Type; ParameterExpression tupleExpr = _tupleExpr.Value = Expression.Parameter(tupleType, "tuple"); ParameterExpression tupleArg = Expression.Parameter(typeof(MutableTuple), "tupleArg"); _temps.Add(_gotoRouter); _temps.Add(tupleExpr); // temps for the outer lambda ParameterExpression tupleTmp = Expression.Parameter(tupleType, "tuple"); ParameterExpression ret = Expression.Parameter(typeof(PythonGenerator), "ret"); var innerLambda = Expression.Lambda <Func <MutableTuple, object> >( Expression.Block( _temps.ToArray(), Expression.Assign( tupleExpr, Expression.Convert( tupleArg, tupleType ) ), Expression.Switch(Expression.Assign(_gotoRouter, _state), cases), body, MakeAssign(_state, AstUtils.Constant(Finished)), Expression.Label(_returnLabels.Peek()), _current ), _name, new ParameterExpression[] { tupleArg } ); // Generate a call to PythonOps.MakeGeneratorClosure(Tuple data, object generatorCode) return(Expression.Block( new[] { tupleTmp, ret }, Expression.Assign( ret, Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeGenerator)), parameters[0], Expression.Assign(tupleTmp, newTuple), emitDebugSymbols ? (Expression)bodyConverter(innerLambda) : (Expression)Expression.Constant( new LazyCode <Func <MutableTuple, object> >( bodyConverter(innerLambda), shouldInterpret, compilationThreshold ), typeof(object) ) ) ), new DelayedTupleAssign( new DelayedTupleExpression(liftedGen.Index, new StrongBox <ParameterExpression>(tupleTmp), _tupleType, typeof(PythonGenerator)), ret ), ret )); }
public virtual void Visit(SwitchCase node) { if (node != null) { AcceptChildren(node); } }
public void Visit(SwitchCase node) { ReportError(node); }
public override SwitchCase VisitSwitchCase(SwitchCase switchCase) { if (switchCase == null) return null; return base.VisitSwitchCase((SwitchCase)switchCase.Clone()); }
private bool CompareSwitchCase(SwitchCase a, SwitchCase b) => Compare(a.Body, b.Body) && CompareExpressionList(a.TestValues, b.TestValues);
public override SwitchCase VisitSwitchCase(SwitchCase switchCase) { throw new ApplicationException("unimplemented"); }
protected override SwitchCase VisitSwitchCase(SwitchCase node) { return(GiveUp(node)); }
public override SwitchCase VisitSwitchCase(SwitchCase switchCase) { SwitchCase retSwitchCase = base.VisitSwitchCase(switchCase); if (retSwitchCase == null || retSwitchCase.Label == null) return retSwitchCase; TypeNode t = null; Identifier id = retSwitchCase.Label as Identifier; if (this.currentSwitch != null && this.currentSwitch.Expression != null) t = this.currentSwitch.Expression.Type; if (id == null || id.Type != null || t == null) return retSwitchCase; if (t.IsAssignableTo(SystemTypes.Enum)) id.Type = t; return retSwitchCase; }
public void GenerateCaseAction(ILGenerator gen, SwitchCase forCase, bool isDefaultCase) { m_ugh.GenerateGetFieldOfUnionType(gen, forCase.ElemField); }
public void SwitchCaseUpdateDoesntRepeatEnumeration() { SwitchCase sc = Expression.SwitchCase(Expression.Constant(1), Expression.Constant(0), Expression.Constant(2)); Assert.NotSame(sc, sc.Update(new RunOnceEnumerable <Expression>(new[] { Expression.Constant(0), Expression.Constant(2) }), sc.Body)); }
public void GenerateSwitchCase(TypeContainer elemType, string elemDeclIdent, object[] discriminatorValues) { // generate val-field for this switch-case FieldBuilder elemField = m_ilEmitHelper.AddFieldWithCustomAttrs(m_builder, "m_" + elemDeclIdent, elemType, FieldAttributes.Private); SwitchCase switchCase = new SwitchCase(elemType, elemDeclIdent, discriminatorValues, elemField); // AMELIORATION possiblity: check range conflict with existing cases, before adding case m_switchCases.Add(switchCase); // generate accessor and modifier methods GenerateAccessorMethod(switchCase); GenerateModifierMethod(switchCase); }
public void SingleTestCaseToString() { SwitchCase sc = Expression.SwitchCase(Expression.Constant(1), Expression.Constant(0)); Assert.Equal("case (0): ...", sc.ToString()); }
private void GenerateAccessorMethod(SwitchCase switchCase) { MethodBuilder accessor = m_ilEmitHelper.AddMethod(m_builder, "Get" + switchCase.ElemName, new ParameterSpec[0], switchCase.ElemType, MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator gen = accessor.GetILGenerator(); Label checkInitOk = gen.DefineLabel(); Label checkDiscrValOk = gen.DefineLabel(); // check if initalized GenerateIsInitalized(gen, checkInitOk); gen.MarkLabel(checkInitOk); GenerateDiscrValueOkTest(gen, switchCase, checkDiscrValOk, s_BadOperationConstr, 34); gen.MarkLabel(checkDiscrValOk); // load value and return gen.Emit(OpCodes.Ldarg_0); // load union this reference gen.Emit(OpCodes.Ldfld, switchCase.ElemField); //load the value of the union for this switch-case gen.Emit(OpCodes.Ret); }
public void MultipleTestCaseToString() { SwitchCase sc = Expression.SwitchCase(Expression.Constant(1), Expression.Constant(0), Expression.Constant("A")); Assert.Equal("case (0, \"A\"): ...", sc.ToString()); }
private void AddOwnDefaultCaseDiscriminatorSetter() { // discr val paramter ParameterSpec discrArg = new ParameterSpec("discrVal", DiscriminatorType, ParameterSpec.ParameterDirection.s_in); ParameterSpec[] parameters = new ParameterSpec[] { discrArg }; MethodBuilder modifier = m_ilEmitHelper.AddMethod(m_builder, "SetDefault", parameters, new TypeContainer(ReflectionHelper.VoidType), MethodAttributes.Public | MethodAttributes.HideBySig); ILGenerator gen = modifier.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4_1); gen.Emit(OpCodes.Stfld, m_initalizedField); // store initalizedfield gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Stfld, m_discrField); // store discriminator field // check, if discrvalue assigned is ok Label endMethodLabel = gen.DefineLabel(); SwitchCase ownDefault = new SwitchCase(null, null, new object[] { s_defaultCaseDiscriminator }, null); GenerateDiscrValueOkTest(gen, ownDefault, endMethodLabel, s_BadParamConstr, 34); gen.MarkLabel(endMethodLabel); gen.Emit(OpCodes.Ret); }
public void TestConditions() { PacketSegmentStructure spellAttributes, chatType, someNumber; SwitchPacketSegmentStructure swtch; SwitchCase cond, cond2, cond3, cond4; var def = new PacketDefinition(RealmServerOpCode.CMSG_SET_FACTION_INACTIVE, PacketSender.Client, spellAttributes = new PacketSegmentStructure(SimpleType.UInt, "SpellAttributes", typeof(SpellAttributes)), chatType = new PacketSegmentStructure(SimpleType.UInt, "ChatType", typeof(ChatMsgType)), someNumber = new PacketSegmentStructure(SimpleType.Int, "SomeNumber"), swtch = new SwitchPacketSegmentStructure("some switch", chatType, cond = new SwitchCase(ComparisonType.Equal, ChatMsgType.Say, new PacketSegmentStructure(SimpleType.CString, "Message") ) ), new SwitchPacketSegmentStructure("Mathmatical comparisons", someNumber, cond2 = new SwitchCase(ComparisonType.GreaterOrEqual, 300, new PacketSegmentStructure(SimpleType.CString, "Message") )), new SwitchPacketSegmentStructure("Flag Switch", spellAttributes, cond3 = new SwitchCase(ComparisonType.And, "Passive | Ranged", new PacketSegmentStructure(SimpleType.CString, "Something Else") ), cond4 = new SwitchCase(ComparisonType.AndNot, "OnNextMelee", new PacketSegmentStructure(SimpleType.CString, "Meleestuff") ) ) ); // basic structure Assert.AreEqual(6, ((ComplexPacketSegmentStructure)def.Structure).Segments.Count); Assert.AreEqual(1, swtch.Cases.Count); Assert.AreEqual(cond, swtch.Cases[0]); def.Init(); // conditions Assert.IsFalse(cond.Matches((ChatMsgType)123)); Assert.AreEqual(cond.Value, ChatMsgType.Say); Assert.IsTrue(cond.Matches(ChatMsgType.Say)); Assert.IsFalse(cond2.Matches(123)); Assert.IsTrue(cond2.Matches(300)); Assert.IsTrue(cond2.Matches(3000)); Assert.IsTrue(cond3.Matches(SpellAttributes.Passive | SpellAttributes.Ranged | SpellAttributes.CannotBeCastInCombat)); Assert.IsFalse(cond3.Matches(SpellAttributes.StartCooldownAfterEffectFade)); Assert.IsTrue(cond4.Matches(SpellAttributes.Passive)); Assert.IsFalse(cond4.Matches(SpellAttributes.Passive | SpellAttributes.OnNextMelee)); Assert.IsFalse(cond4.Matches(SpellAttributes.OnNextMelee)); }
public virtual Differences VisitSwitchCase(SwitchCase switchCase1, SwitchCase switchCase2){ Differences differences = new Differences(switchCase1, switchCase2); if (switchCase1 == null || switchCase2 == null){ if (switchCase1 != switchCase2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; return differences; } SwitchCase changes = (SwitchCase)switchCase2.Clone(); SwitchCase deletions = (SwitchCase)switchCase2.Clone(); SwitchCase insertions = (SwitchCase)switchCase2.Clone(); Differences diff = this.VisitBlock(switchCase1.Body, switchCase2.Body); if (diff == null){Debug.Assert(false); return differences;} changes.Body = diff.Changes as Block; deletions.Body = diff.Deletions as Block; insertions.Body = diff.Insertions as Block; Debug.Assert(diff.Changes == changes.Body && diff.Deletions == deletions.Body && diff.Insertions == insertions.Body); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; diff = this.VisitExpression(switchCase1.Label, switchCase2.Label); if (diff == null){Debug.Assert(false); return differences;} changes.Label = diff.Changes as Expression; deletions.Label = diff.Deletions as Expression; insertions.Label = diff.Insertions as Expression; Debug.Assert(diff.Changes == changes.Label && diff.Deletions == deletions.Label && diff.Insertions == insertions.Label); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if (differences.NumberOfDifferences == 0){ differences.Changes = null; differences.Deletions = null; differences.Insertions = null; }else{ differences.Changes = changes; differences.Deletions = deletions; differences.Insertions = insertions; } return differences; }
public void SwitchCaseDifferentBodyToDifferent() { SwitchCase sc = Expression.SwitchCase(Expression.Constant(1), Expression.Constant(0), Expression.Constant(2)); Assert.NotSame(sc, sc.Update(sc.TestValues, Expression.Constant(1))); }
public SwitchCaseProxy(SwitchCase node) { _node = node; }
public void SwitchCaseDifferentTestsToDifferent() { SwitchCase sc = Expression.SwitchCase(Expression.Constant(1), Expression.Constant(0), Expression.Constant(2)); Assert.NotSame(sc, sc.Update(new[] { Expression.Constant(0), Expression.Constant(2) }, sc.Body)); }
protected internal virtual void PostWalk(SwitchCase node) { }
public void Visit(SwitchCase node) { Debug.Fail("shouldn't get here"); }
/// <summary> /// Creates the label for this case. /// Optimization: if the body is just a goto, and we can branch /// to it, put the goto target directly in the jump table. /// </summary> private void DefineSwitchCaseLabel(SwitchCase @case, out Label label, out bool isGoto) { var jump = @case.Body as GotoExpression; // if it's a goto with no value if (jump != null && jump.Value == null) { // Reference the label from the switch. This will cause us to // analyze the jump target and determine if it is safe. LabelInfo jumpInfo = ReferenceLabel(jump.Target); // If we have are allowed to emit the "branch" opcode, then we // can jump directly there from the switch's jump table. // (Otherwise, we need to emit the goto later as a "leave".) if (jumpInfo.CanBranch) { label = jumpInfo.Label; isGoto = true; return; } } // otherwise, just define a new label label = _ilg.DefineLabel(); isGoto = false; }
private static Expression GenerateGlobalKeyFormat(Type type, ParameterExpression newModel, LabelTarget tailOfMethod) { return(Expression.Block( /* * var afterFormatKey = handler.option.GlobalKeyFormat.Invoke(reader.ReadString(),type) */ Expression.Assign(ExpressionMembers.AfterFormatKey, Expression.Call(ExpressionMembers.GlobalKeyFormat, JsonDeserializeOption._GlobalKeyFormatInvoke, Expression.Call(ExpressionMembers.Reader, JsonReader._ReadString), Expression.Constant(type, typeof(Type)))), /* * if(IsIgnoreExtraKeysInJSON){ * if(!modelKeys.Contains(afterFormatKey)) * { * reader.ReadColon(); * Reader.ReadObject(); * goto zuihou; * } * if(IsOpenIgnoreKey) * if(IgnoreKey.Contains(key)) * { * reader.ReadColon(); * Reader.ReadObject(); * goto zuihou; * } */ IfIsIgnoreExtraKeysInJsonThenSkipObject(ExpressionMembers.AfterFormatKey, type, tailOfMethod), IfIgnoreJsonKeysHasValueThenSkipObject(ExpressionMembers.AfterFormatKey, tailOfMethod), /* * reader.ReadColon() */ Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon), /* * Switch(afterFormatKey) * case 'Name': * ReadValue().... */ Expression.Switch( typeof(void), ExpressionMembers.AfterFormatKey, null, null, ReturnFunc(() => { var members = type.GetModelMembers(); SwitchCase[] switchCases = new SwitchCase[members.Count]; for (int i = 0; i < members.Count; i++) { var item = members[i]; switchCases[i] = Expression.SwitchCase(GenerateKeyValueObjectReadValue(item.Value, newModel), Expression.Constant(item.Key)); } return switchCases; }) ), /* * isArrive=true; */ ExpressionMembers.IsArriveAssignTrue )); }