public ExpressionStatement this[ExpressionStatement key] { get { ExpressionStatement result; this.orig2New.TryGetValue(key, out result); return result; } }
// Requires: // statement.Expression is MethodCall // statement.Expression.Callee is MemberBinding // statement.Expression.Callee.BoundMember is Method // statement.Expression.Callee.BoundMember == "Requires" or "Ensures" // // inline <==> replacementMethod == null // replacementMethod != null // ==> replacementMethod.ReturnType == methodToReplace.ReturnType // && replacementMethod.Parameters.Count == 1 // && methodToReplace.Parameters.Count == 1 // && replacementMethod.Parameters[0].Type == methodToReplace.Parameters[0].Type // private static Statement RewriteContractCall( ExpressionStatement statement, Method /*!*/ methodToReplace, Method /*?*/ replacementMethod, Literal /*?*/ sourceTextToUseAsSecondArg) { Contract.Requires(statement != null); MethodCall call = statement.Expression as MethodCall; if (call == null || call.Callee == null) { return statement; } MemberBinding mb = call.Callee as MemberBinding; if (mb == null) { return statement; } Method m = mb.BoundMember as Method; if (m == null) { return statement; } if (m != methodToReplace) { return statement; } mb.BoundMember = replacementMethod; if (call.Operands.Count == 3) { // then the invariant was found in a reference assembly // it already has all of its arguments return statement; } if (call.Operands.Count == 1) { call.Operands.Add(Literal.Null); } Literal extraArg = sourceTextToUseAsSecondArg; if (extraArg == null) { extraArg = Literal.Null; //extraArg = new Literal("No other information available", SystemTypes.String); } call.Operands.Add(extraArg); return statement; }
public override void VisitExpressionStatement(ExpressionStatement statement) { Method methodCall = HelperMethods.IsMethodCall(statement); if (methodCall == this.contractNodes.AssertMethod || methodCall == this.contractNodes.AssertWithMsgMethod || methodCall == this.contractNodes.AssumeMethod || methodCall == this.contractNodes.AssumeWithMsgMethod) { this.BadStuffFound = true; } base.VisitExpressionStatement(statement); }
public override Statement VisitExpressionStatement(ExpressionStatement statement) { Method contractMethod = Rewriter.ExtractCallFromStatement(statement); if (contractMethod == null) { return base.VisitExpressionStatement(statement); } if (this.rcm.ContractNodes.IsInvariantMethod(contractMethod)) { Statement s = RewriteInvariant.RewriteContractCall( statement, contractMethod, this.rcm.InvariantMethod, this.sourceTextOfInvariant ); return s; } else { return base.VisitExpressionStatement(statement); } }
public override void VisitExpressionStatement(ExpressionStatement statement) { if (statement == null) return; if (IsLiteral0Or1(statement.Expression)) { // assume this is from an && or || shortcut evaluation. A single block // whack out its source context so code coverage handles it as covered statement.SourceContext = new SourceContext(HiddenDocument.Document); } base.VisitExpressionStatement(statement); }
public override InstanceInitializer InjectDefaultConstructor(TypeNode typeNode) { if (this.DontInjectDefaultConstructors || typeNode.IsNormalized) return null; Class Class = typeNode as Class; if (Class != null && Class.Name != null && !(Class is ClassParameter) && ClassHasNoExplicitConstructors(typeNode)) { if (Class.IsAbstractSealedContainerForStatics) return null; if (Class.PartiallyDefines != null){ this.InjectDefaultConstructor(Class.PartiallyDefines); InstanceInitializer defCons = Class.PartiallyDefines.GetConstructor(); if (defCons != null && !defCons.HasCompilerGeneratedSignature) defCons = null; //Not an orphan if (defCons != null){ //This is an injected default constructor that is an orphan, adopt it defCons.HasCompilerGeneratedSignature = false; //abuse this flag to stop other partial types from adopting it Class.Members.Add(defCons); Class.BaseClass = ((Class)Class.PartiallyDefines).BaseClass; } return defCons; //Ok if defCons null, this type should not show up in inheritance chains }else{ //Inject a default constructor This thisParameter = new This(Class); Class baseClass = Class.BaseClass; StatementList statements = new StatementList(2); statements.Add(new FieldInitializerBlock(typeNode, false)); if (baseClass != null) { MethodCall mcall = new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor, typeNode.Name.SourceContext), null); mcall.SourceContext = typeNode.Name.SourceContext; ExpressionStatement callSupCons = new ExpressionStatement(mcall); callSupCons.SourceContext = typeNode.Name.SourceContext; statements.Add(callSupCons); } InstanceInitializer defCons = new InstanceInitializer(typeNode, null, null, new Block(statements)); defCons.Name = new Identifier(".ctor", typeNode.Name.SourceContext); defCons.SourceContext = typeNode.Name.SourceContext; defCons.ThisParameter = thisParameter; if (typeNode.IsAbstract) defCons.Flags |= MethodFlags.Family|MethodFlags.HideBySig; else defCons.Flags |= MethodFlags.Public|MethodFlags.HideBySig; defCons.CallingConvention = CallingConventionFlags.HasThis; defCons.IsCompilerGenerated = true; typeNode.Members.Add(defCons); return defCons; } } return null; }
internal void RecordNecessaryCheck(ExpressionStatement es) { if (es == null || !eliminateCheck.ContainsKey(es)) return; eliminateCheck.Remove(es); }
/// <summary> /// Method replaces Requires to Assume in the MoveNext method of the async or iterator state machine. /// </summary> private void ReplaceRequiresWithAssumeInMoveNext(RequiresList origPreconditions, AssumeBlock originalContractPosition) { Contract.Assert(origPreconditions != null); if (originalContractPosition != null && originalContractPosition.Statements != null /*&& origPreconditions != null */&& origPreconditions.Count > 0) { var origStatements = originalContractPosition.Statements; foreach (var pre in origPreconditions) { if (pre == null) continue; var assume = new MethodCall( new MemberBinding(null, this.contractNodes.AssumeMethod), new ExpressionList(pre.Condition), NodeType.Call); assume.SourceContext = pre.SourceContext; var assumeStmt = new ExpressionStatement(assume); assumeStmt.SourceContext = pre.SourceContext; origStatements.Add(assumeStmt); } } }
public override Statement VisitExpressionStatement(ExpressionStatement statement) { // Check for statements that require special handling AssignmentExpression assignmentExpr = statement.Expression as AssignmentExpression; AssignmentStatement assignmentStatement = null; MethodCall methodCall = statement.Expression as MethodCall; UnaryExpression choose = null; if (assignmentExpr != null) { assignmentStatement = assignmentExpr.AssignmentStatement as AssignmentStatement; if (assignmentStatement != null && assignmentStatement.Source is MethodCall) methodCall = (MethodCall)assignmentStatement.Source; if (assignmentStatement != null && assignmentStatement.Source is UnaryExpression && assignmentStatement.Source.NodeType == (NodeType)ZingNodeType.Choose) choose = (UnaryExpression)assignmentStatement.Source; } if (methodCall != null) { Block stmtBlock = new Block(); stmtBlock.Statements = new StatementList(); // The following if statement (and the if-branch) added by Jiri Adamek // Reason: the NativeZOM method calls are generated differntly from // common Zing method calls // The original code is in the else-branch if (((MemberBinding)methodCall.Callee).BoundMember.DeclaringType is NativeZOM) { GenerateNativeZOMCall(stmtBlock, methodCall, statement is AsyncMethodCall, assignmentStatement); } else { if (this.secondOfTwo) GenerateMethodReturn(stmtBlock, assignmentStatement, methodCall); else GenerateMethodCall(stmtBlock, methodCall, statement is AsyncMethodCall); } return stmtBlock; } else if (choose != null) { Statement chooseStmt; if (this.secondOfTwo) { // Finishing a "choose" is always the same... chooseStmt = Templates.GetStatementTemplate("FinishChoose"); TypeNode tn = choose.Type; if (tn is Set || tn is ZArray || tn is Class || tn is Chan) Replacer.Replace(chooseStmt, "_targetType", new Identifier("Pointer")); else Replacer.Replace(chooseStmt, "_targetType", this.VisitExpression(choose.Type.Name)); Replacer.Replace(chooseStmt, "_target", this.VisitExpression(assignmentStatement.Target)); } else { // Starting a "choose" is different for the static and dynamic cases if (choose.Operand.Type.FullName == "Boolean") { chooseStmt = Templates.GetStatementTemplate("StartChooseByBoolType"); } else if (choose.Operand.Type == SystemTypes.Type) { // static Literal lit = choose.Operand as Literal; Debug.Assert(lit != null); TypeNode tn = lit.Value as TypeNode; Debug.Assert(tn != null); chooseStmt = Templates.GetStatementTemplate("StartChooseByType"); Replacer.Replace(chooseStmt, "_typeExpr", new QualifiedIdentifier(new Identifier("Application"), tn.Name)); } else { // dynamic chooseStmt = Templates.GetStatementTemplate("StartChooseByValue"); Replacer.Replace(chooseStmt, "_ptrExpr", this.VisitExpression(choose.Operand)); } } return chooseStmt; } else if (assignmentStatement != null && assignmentStatement.Target.Type is Set && assignmentStatement.Source is BinaryExpression) { BinaryExpression binaryExpression = (BinaryExpression)assignmentStatement.Source; Statement setOpStmt; if (binaryExpression.Operand1.Type == binaryExpression.Operand2.Type) { if (binaryExpression.NodeType == NodeType.Add) setOpStmt = Templates.GetStatementTemplate("SetAddSet"); else setOpStmt = Templates.GetStatementTemplate("SetRemoveSet"); } else { if (binaryExpression.NodeType == NodeType.Add) setOpStmt = Templates.GetStatementTemplate("SetAddItem"); else setOpStmt = Templates.GetStatementTemplate("SetRemoveItem"); } Replacer.Replace(setOpStmt, "_ptrExpr", this.VisitExpression(binaryExpression.Operand1)); Replacer.Replace(setOpStmt, "_itemExpr", this.VisitExpression(binaryExpression.Operand2)); return setOpStmt; } else { // The default scenario... inExpressionStatement = true; Expression newExpr = this.VisitExpression(statement.Expression); inExpressionStatement = false; // // In some scenarios, a simple assignment becomes something much more // complicated. We have to detect when such a case has occurred and // return the more complex statement directly rather than leaving it // embedded within an ExpressionStatement. // AssignmentExpression newAssignmentExpr = newExpr as AssignmentExpression; if (newAssignmentExpr != null && !(newAssignmentExpr.AssignmentStatement is AssignmentStatement)) return newAssignmentExpr.AssignmentStatement; Statement result = new ExpressionStatement(newExpr, statement.SourceContext); return result; } }
public override Expression VisitOldExpression(OldExpression oldExpression) { if (this.topLevelClosureClass != null) { #region In Closure ==> Create a field // Since we're within a closure, we can't create a local to hold the value of the old expression // but instead have to create a field for it. That field can be a member of the top-level // closure class since nothing mentioned in the old expression (except possibly for the // bound variables of enclosing quantifications) should be anything captured from // an inner anonymous delegate. // BUT, first we have to know if the old expression depends on any of the bound // variables of the closures in which it is located. If not, then we can implement // it as a scalar and just generate the assignment "closure_class.field := e" for // "Old(e)" to take a snapshot of e's value in the prestate. If it does depend on // any of the bound variables, then we need to generate a set of for-loops that // compute the indices and values of e for each tuple of indices so it can be retrieved // (given the indices) in the post-state. CollectBoundVariables cbv = new CollectBoundVariables(this.stackOfBoundVariables); cbv.VisitExpression(oldExpression.expression); SubstituteClosureClassWithinOldExpressions subst = new SubstituteClosureClassWithinOldExpressions(this.closureLocals); Expression e = subst.VisitExpression(oldExpression.expression); if (cbv.FoundVariables.Count == 0) { #region Use a scalar for the old variable Local closureLocal; if (!this.closureLocals.TryGetValue(this.topLevelClosureClass, out closureLocal)) { Contract.Assume(false, "can't find closure local!"); } #region Define a scalar var clTemplate = HelperMethods.Unspecialize(this.topLevelClosureClass); Field f = new Field(clTemplate, null, FieldFlags.CompilerControlled | FieldFlags.Public, Identifier.For("_old" + oldExpression.expression.UniqueKey.ToString()), // unique name for this old expr. oldExpression.Type, null); clTemplate.Members.Add(f); // now produce properly instantiated field f = (Field)Rewriter.GetMemberInstanceReference(f, this.topLevelClosureClass); #endregion #region Generate code to store value in prestate this.prestateValuesOfOldExpressions.Statements.Add(new AssignmentStatement(new MemberBinding(closureLocal, f), e)); #endregion #region Return expression to be used in poststate // Return an expression that will evaluate in the poststate to the value of the old // expression in the prestate. This will be this.up.f where "up" is the field C# // generated to point to the instance of the top-level closure class. if (this.PointerToTopLevelClosureClass == null) { // then the old expression occurs in the top-level closure class. Just return "this.f" // where "this" refers to the top-level closure class. return new MemberBinding(new This(this.currentClosureClass), f); } else { return new MemberBinding( new MemberBinding(new This(this.currentClosureClass), this.PointerToTopLevelClosureClass), f); } #endregion #endregion } else { // the Old expression *does* depend upon at least one of the bound variable // in a ForAll or Exists expression #region Use an indexed variable for the old variable TypeNode oldVariableTypeDomain; #region Decide if domain is one-dimensional or not bool oneDimensional = cbv.FoundVariables.Count == 1 && cbv.FoundVariables[0].Type.IsValueType; if (oneDimensional) { // a one-dimensional old-expression can use the index variable directly oldVariableTypeDomain = cbv.FoundVariables[0].Type; } else { oldVariableTypeDomain = SystemTypes.GenericList.GetTemplateInstance(this.module, SystemTypes.Int32); } #endregion TypeNode oldVariableTypeRange = oldExpression.Type; TypeNode oldVariableType = SystemTypes.GenericDictionary.GetTemplateInstance(this.module, oldVariableTypeDomain, oldVariableTypeRange); Local closureLocal; if (!this.closureLocals.TryGetValue(this.topLevelClosureClass, out closureLocal)) { Contract.Assume(false, "can't find closure local"); } #region Define an indexed variable var clTemplate = HelperMethods.Unspecialize(this.topLevelClosureClass); Field f = new Field(clTemplate, null, FieldFlags.CompilerControlled | FieldFlags.Assembly, // can't be private or protected because it needs to be accessed from inner (closure) classes that don't inherit from the class this field is added to. Identifier.For("_old" + oldExpression.expression.UniqueKey.ToString()), // unique name for this old expr. oldVariableType, null); clTemplate.Members.Add(f); // instantiate f f = (Field)Rewriter.GetMemberInstanceReference(f, closureLocal.Type); #endregion #region Generate code to initialize the indexed variable Statement init = new AssignmentStatement( new MemberBinding(closureLocal, f), new Construct(new MemberBinding(null, oldVariableType.GetConstructor()), null)); this.prestateValuesOfOldExpressions.Statements.Add(init); #endregion #region Generate code to store values in prestate #region Create assignment: this.closure.f[i,j,k,...] = e; Method setItem = oldVariableType.GetMethod(Identifier.For("set_Item"), oldVariableTypeDomain, oldVariableTypeRange); Expression index; if (oneDimensional) { index = cbv.FoundVariables[0]; } else { //InstanceInitializer ctor = // ContractNodes.TupleClass.GetConstructor(SystemTypes.Int32.GetArrayType(1)); //Expression index = new Construct(new MemberBinding(null,ctor),new ExpressionList( index = Literal.Null; } MethodCall mc = new MethodCall(new MemberBinding(new MemberBinding(closureLocal, f), setItem), new ExpressionList(index, e)); Statement stat = new ExpressionStatement(mc); #endregion List<Local> locals = new List<Local>(this.stackOfBoundVariables.Count); TrivialHashtable paramMap = new TrivialHashtable(); #region Generate a local for each bound variable to use in for-loop foreach (Variable v in this.stackOfBoundVariables) { Local l = new Local(Identifier.Empty, v.Type); paramMap[v.UniqueKey] = l; locals.Add(l); } #endregion #region Substitute locals for bound variables in old expression *AND* in inner loop bounds SubstituteParameters sps = new SubstituteParameters(paramMap, this.stackOfBoundVariables); sps.Visit(stat); #endregion #region Create nested for-loops around assignment // keep track of when the first variable is used (from innermost to outermost) // as soon as the first one is needed because the old expression depends on it, // then keep all enclosing loops. It would be possible to keep only those where // the necessary loops have loop bounds that depend on an enclosing loop, but I // haven't calculated that, so just keep them all. For instance, if the old expression // depends on j and the loops are "for i,0,n" and inside that "for j,0,i", then need // both loops. If the inner loop bounds were 0 and n, then wouldn't need the outer // loop. bool usedAVariable = false; for (int i = this.stackOfBoundVariables.Count - 1; 0 <= i; i--) { if (!usedAVariable && !cbv.FoundVariables.Contains(this.stackOfBoundVariables[i])) continue; usedAVariable = true; Expression lowerBound = new Duplicator(this.module, this.currentClosureClass).VisitExpression( this.stackOfMethods[i].Operands[0]); lowerBound = subst.VisitExpression(lowerBound); lowerBound = sps.VisitExpression(lowerBound); Expression upperBound = new Duplicator(this.module, this.currentClosureClass).VisitExpression( this.stackOfMethods[i].Operands[1]); upperBound = subst.VisitExpression(upperBound); upperBound = sps.VisitExpression(upperBound); stat = RewriteHelper.GenerateForLoop(locals[i], lowerBound, upperBound, stat); } #endregion this.prestateValuesOfOldExpressions.Statements.Add(stat); #endregion #region Return expression to be used in poststate Method getItem = oldVariableType.GetMethod(Identifier.For("get_Item"), oldVariableTypeDomain); if (oneDimensional) { index = cbv.FoundReferences[0]; } else { //InstanceInitializer ctor = // ContractNodes.TupleClass.GetConstructor(SystemTypes.Int32.GetArrayType(1)); //Expression index = new Construct(new MemberBinding(null,ctor),new ExpressionList( index = Literal.Null; } // Return an expression that will evaluate in the poststate to the value of the old // expression in the prestate. This will be this.up.f[i,j,k,...] where "up" is the field C# // generated to point to the instance of the top-level closure class. MemberBinding thisDotF; if (this.PointerToTopLevelClosureClass == null) { // then the old expression occurs in the top-level closure class. Just return "this.f" // where "this" refers to the top-level closure class. Contract.Assume(f != null); thisDotF = new MemberBinding(new This(clTemplate), HelperMethods.Unspecialize(f)); } else { thisDotF = new MemberBinding( new MemberBinding(new This(clTemplate), this.PointerToTopLevelClosureClass), f); } return new MethodCall(new MemberBinding(thisDotF, getItem), new ExpressionList(index)); #endregion #endregion } #endregion } else { #region Not in closure ==> Create a local variable Local l = GetLocalForOldExpression(oldExpression); #region Make sure local can be seen in the debugger (for the entire method, unfortunately) if (currentMethod.LocalList == null) { currentMethod.LocalList = new LocalList(); } currentMethod.LocalList.Add(l); currentMethod.Body.HasLocals = true; #endregion this.prestateValuesOfOldExpressions.Statements.Add( new AssignmentStatement(l, oldExpression.expression)); // Return an expression that will evaluate in the poststate to the value of the old // expression in the prestate. When we're not in a closure, this is just the local // itself. return l; #endregion } }
public virtual Statement VisitExpressionStatement(ExpressionStatement statement) { if (statement == null) return null; statement.Expression = this.VisitExpression(statement.Expression); return statement; }
public override Statement VisitExpressionStatement(ExpressionStatement statement) { if (statement == null) return null; Expression e = statement.Expression = this.VisitExpression(statement.Expression); if (e == null || e.Type == CoreSystemTypes.Void) return statement; if (e.NodeType == NodeType.Dup) return this.localsStack.Dup(); return this.localsStack.Push(e); }
// Requires: // statement.Expression is MethodCall // statement.Expression.Callee is MemberBinding // statement.Expression.Callee.BoundMember is Method // statement.Expression.Callee.BoundMember == "Assert" or "Assume" // // replacementMethod.ReturnType == methodToReplace.ReturnType // && replacementMethod.Parameters.Count == 1 // && methodToReplace.Parameters.Count == 1 // && replacementMethod.Parameters[0].Type == methodToReplace.Parameters[0].Type // private static Statement RewriteContractCall( MethodCall call, ExpressionStatement statement, Method/*!*/ methodToReplace, Method/*?*/ replacementMethod ) { Contract.Requires(call != null); Debug.Assert(call == statement.Expression as MethodCall); MemberBinding mb = (MemberBinding)call.Callee; Debug.Assert(mb.BoundMember == methodToReplace); mb.BoundMember = replacementMethod; if (call.Operands.Count == 1) { call.Operands.Add(Literal.Null); } #if false SourceContext sctx = statement.SourceContext; if (sctx.IsValid && sctx.Document.Text != null && sctx.Document.Text.Source != null) { call.Operands.Add(new Literal(sctx.Document.Text.Source, SystemTypes.String)); } #else ContractAssumeAssertStatement casas = statement as ContractAssumeAssertStatement; if (casas != null) { call.Operands.Add(new Literal(casas.SourceText, SystemTypes.String)); } #endif else { call.Operands.Add(Literal.Null); //call.Operands.Add(new Literal("No other information available", SystemTypes.String)); } return statement; }
/// <summary> /// </summary> /// <param name="expr_stat">Cloned</param> /// <returns></returns> public override Statement VisitExpressionStatement(ExpressionStatement expr_stat) { // The AST may have shared nodes. if (this.orig2Copy.ContainsKey(expr_stat)) { return this.orig2Copy[expr_stat]; } Expression newexpr = this.VisitExpression(expr_stat.Expression); if (newexpr == null) { // turn into nop statement return new Statement(NodeType.Nop); } // check for special case where we now have a PopExpression as the expression. // this corresponds to a push(pop), which is a noop and we need to represent it that way. if (newexpr.NodeType == NodeType.Pop && !(newexpr is UnaryExpression)) { return new Statement(NodeType.Nop); } ExpressionStatement copy = (ExpressionStatement)expr_stat.Clone(); copy.Expression = newexpr; copy.SourceContext = this.current_source_context; this.orig2Copy.Add(expr_stat, copy); return copy; }
/// <summary> /// </summary> /// <param name="cons">Cloned</param> /// <returns></returns> public override Expression VisitConstruct(Construct cons) { ExpressionList operands = this.VisitExpressionList(cons.Operands); MemberBinding mb = this.VisitExpression(cons.Constructor) as MemberBinding; if (mb == null) return null; Debug.Assert(mb.TargetObject == null, "constructor target not null!"); if ( this.expandAllocations ) { // Now split the expression into 3: // allocTemp = new T; // allocTemp..ctor(args...); // allocTemp // For value types, the construction is even more involved: // valTemp = new VT; // allocTemp = &valTemp; // allocTemp..ctor(args...); // valTemp if (mb.BoundMember != null && mb.BoundMember.DeclaringType != null && mb.BoundMember.DeclaringType.IsValueType) { Variable valTemp = StackVariable.NEWValueTemp(mb.BoundMember.DeclaringType); Construct newcons = new Construct(new MemberBinding(null, mb.BoundMember), new ExpressionList(0), mb.BoundMember.DeclaringType); AssignmentStatement new_stat = new AssignmentStatement(valTemp, newcons); new_stat.SourceContext = this.current_source_context; new_stats.Add(new_stat); Variable allocTemp = StackVariable.NEWTemp(mb.BoundMember.DeclaringType); new_stats.Add(new AssignmentStatement(allocTemp, new UnaryExpression(valTemp, NodeType.AddressOf, mb.BoundMember.DeclaringType.GetReferenceType()), NodeType.Nop)); mb.TargetObject = allocTemp; ExpressionStatement call_stat = new ExpressionStatement(new MethodCall(mb, operands, NodeType.Call, Cci.SystemTypes.Void)); call_stat.SourceContext = this.current_source_context; new_stats.Add(call_stat); return valTemp; } else { Variable vtemp = StackVariable.NEWTemp(mb.BoundMember.DeclaringType); Construct newcons = new Construct(new MemberBinding(null, mb.BoundMember), new ExpressionList(0), mb.BoundMember.DeclaringType); AssignmentStatement new_stat = new AssignmentStatement(vtemp, newcons); new_stat.SourceContext = this.current_source_context; new_stats.Add(new_stat); mb.TargetObject = vtemp; ExpressionStatement call_stat = new ExpressionStatement(new MethodCall(mb, operands, NodeType.Call, Cci.SystemTypes.Void)); call_stat.SourceContext = this.current_source_context; new_stats.Add(call_stat); return vtemp; } } else { Construct newcons = new Construct(mb, operands, mb.BoundMember.DeclaringType); newcons.SourceContext = this.current_source_context; return newcons; } }
private Expression pushPop(Expression expression) { SourceContext ctxt = expression.SourceContext.Document != null? expression.SourceContext:this.current_source_context; ExpressionStatement new_stat = new ExpressionStatement(expression, ctxt); Debug.Assert(new_stats != null, "must have been initialized by now."); new_stats.Add(new_stat); return Pop(expression.Type, ctxt); }
private void WarnIfExplicit(ExpressionStatement es) { if (es == null) return; MethodCall mcall = es.Expression as MethodCall; if (mcall == null) return; MemberBinding mb = mcall.Callee as MemberBinding; if (mb == null) return; if (checker.IsAssertNotNullMethod(mb.BoundMember as Method)) { checker.HandleError(es, mcall, Error.UnnecessaryNonNullCoercion); } }
public override Statement VisitExpressionStatement(ExpressionStatement statement) { // skip VisitExpression because these could be of a form that do not produce a value, in which case we don't want to introduce a BlockExpression statement.Expression = (Expression)this.Visit(statement.Expression); return statement; }
public override Statement VisitExpressionStatement(ExpressionStatement statement) { MethodCall call; Method contractMethod = Rewriter.ExtractCallFromStatement(statement, out call); if (contractMethod == null) { return base.VisitExpressionStatement(statement); } Method keyToLookUp = contractMethod; if (this.methodTable.ContainsKey(keyToLookUp)) { var isAssert = keyToLookUp.Name.Name == "Assert"; Method repMethod; if (isAssert) { repMethod = this.runtimeContracts.AssertMethod; } else { // assume it is Assume repMethod = this.runtimeContracts.AssumeMethod; } if (repMethod == null) { return base.VisitExpressionStatement(statement); } if (isAssert && (!this.emitFlags.Emit(RuntimeContractEmitFlags.Asserts) || this.runtimeContracts.PublicSurfaceOnly)) { var pops = CountPopExpressions.Count(call); if (pops > 0) { var block = new Block(new StatementList(pops)); while (pops-- > 0) { // emit a pop block.Statements.Add(new ExpressionStatement(new UnaryExpression(null, NodeType.Pop))); } return block; } return null; } if (!isAssert && (!this.emitFlags.Emit(RuntimeContractEmitFlags.Assumes) || this.runtimeContracts.PublicSurfaceOnly)) { var pops = CountPopExpressions.Count(call); if (pops > 0) { var block = new Block(new StatementList(pops)); while (pops-- > 0) { // emit a pop block.Statements.Add(new ExpressionStatement(new UnaryExpression(null, NodeType.Pop))); } return block; } return null; } var result = RewriteAssertAssumeAndCallSiteRequires.RewriteContractCall( call, statement, contractMethod, repMethod ); return result; } else { return base.VisitExpressionStatement(statement); } }
private StatementList ParseForIncrementer(TokenSet followers){ StatementList statements = new StatementList(); if (this.currentToken == Token.RightParenthesis) return statements; TokenSet followerOrComma = followers|Token.Comma; for(;;){ Expression e = this.ParseExpression(followerOrComma); if (e == null) return statements; if (!(e is AssignmentExpression || e is MethodCall || e is PostfixExpression || e is PrefixExpression || e is Construct)) this.HandleError(e.SourceContext, Error.IllegalStatement); Statement s = new ExpressionStatement(e); s.SourceContext = e.SourceContext; statements.Add(s); if (this.currentToken != Token.Comma) break; this.GetNextToken(); } this.SkipTo(followers); return statements; }
private Statement ParseNewStatement(TokenSet followers, bool preferExpressionToDeclaration){ Debug.Assert(this.currentToken == Token.New); Expression e = this.ParseExpression(followers); Statement s = new ExpressionStatement(e); s.SourceContext = e.SourceContext; if (this.currentToken == Token.Semicolon || !preferExpressionToDeclaration) this.SkipSemiColon(followers); this.SkipTo(followers); return s; }
private Statement ParseObjectLiteralStatement(TokenSet followers, bool preferExpressionToDeclaration){ Expression e = this.ParseObjectLiteral(followers|Token.Semicolon); ExpressionStatement es = new ExpressionStatement(e); es.SourceContext = e.SourceContext; if (this.currentToken == Token.Semicolon || !preferExpressionToDeclaration) this.SkipSemiColon(followers); this.SkipTo(followers); return es; }
public override void VisitExpressionStatement(ExpressionStatement estmt) { Expression source = estmt.Expression; Construct sourceConstruct = source as Construct; if (sourceConstruct != null) { if (sourceConstruct.Type != null && sourceConstruct.Type.Name.Name.StartsWith(this.closureTag)) { if (sourceConstruct.Type.Template != null) { TypeNode template = sourceConstruct.Type.Template; while (template.Template != null) { template = template.Template; } this.closureClass = (Class) template; } else { this.closureClass = (Class) sourceConstruct.Type; } } } }
private Statement ParseExpressionStatementOrDeclaration(bool acceptComma, TokenSet followers, bool preferExpressionToDeclaration, bool skipSemicolon){ SourceContext startingContext = this.scanner.CurrentSourceContext; ScannerState ss = this.scanner.state; Token tok = this.currentToken; TypeNode t = this.ParseTypeOrFunctionTypeExpression(followers|Parser.IdentifierOrNonReservedKeyword, true, false); if (t is PointerTypeExpression && !this.inUnsafeCode) this.HandleError(t.SourceContext, Error.UnsafeNeeded); if (t == null || (!Parser.IdentifierOrNonReservedKeyword[this.currentToken] && (this.sink == null || this.currentToken == Token.LeftParenthesis || (this.currentToken == Token.EndOfFile && (t.TemplateArguments == null || t.TemplateArguments.Count == 0))))){ //Tried to parse a type expression and failed, or clearly not dealing with a declaration. //Restore prior state and reparse as expression this.scanner.state = ss; this.scanner.endPos = startingContext.StartPos; this.currentToken = Token.None; this.GetNextToken(); TokenSet followersOrCommaOrColon = followers|Token.Comma|Token.Colon; Expression e = this.ParseExpression(followersOrCommaOrColon); ExpressionStatement eStat = new ExpressionStatement(e, startingContext); if (e != null) eStat.SourceContext = e.SourceContext; Identifier id = null; if (this.currentToken == Token.Colon && !acceptComma && (id = e as Identifier) != null) return this.ParseLabeledStatement(id, followers); if (!acceptComma || this.currentToken != Token.Comma){ if (!preferExpressionToDeclaration){ if (!(e == null || e is AssignmentExpression || e is QueryExpression || e is MethodCall || e is PostfixExpression || e is PrefixExpression || e is Construct || followers[Token.RightParenthesis] || (e is Base && this.currentCtor != null && this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen) ) ) this.HandleError(e.SourceContext, Error.IllegalStatement); if (this.currentToken == Token.Semicolon) this.GetNextToken(); else if (skipSemicolon) this.SkipSemiColon(followers); }else if (skipSemicolon && (this.currentToken != Token.RightBrace || !followers[Token.RightBrace])){ if (this.currentToken == Token.Semicolon && followers[Token.RightBrace]){ //Dealing with an expression block. this.GetNextToken(); if (this.currentToken != Token.RightBrace){ //Not the last expression in the block. Complain if it is not a valid expression statement. if (!(e == null || e is AssignmentExpression || e is MethodCall || e is PostfixExpression || e is PrefixExpression || e is Construct || followers[Token.RightParenthesis])) this.HandleError(e.SourceContext, Error.IllegalStatement); } }else{ if (this.currentToken == Token.Comma && this.arrayInitializerOpeningContext != null){ startingContext = (SourceContext)this.arrayInitializerOpeningContext; this.scanner.endPos = startingContext.StartPos; this.scanner.state = ss; this.currentToken = Token.None; this.GetNextToken(); this.HandleError(Error.ArrayInitToNonArrayType); this.ParseArrayInitializer(1, this.TypeExpressionFor(Token.Object), followers, true); return null; } if (this.currentToken == Token.Comma){ this.HandleError(Error.ExpectedSemicolon); this.GetNextToken(); }else this.SkipSemiColon(followers); } } this.SkipTo(followers); } return eStat; } return this.ParseLocalDeclarations(t, startingContext, false, false, preferExpressionToDeclaration, skipSemicolon, followers|Parser.UnaryStart); }
public override Statement VisitAssignmentStatement(AssignmentStatement assignment) { if (assignment.Source == null || assignment.Target == null) return null; Expression normalizedSource = this.VisitExpression(assignment.Source); Expression normalizedTarget = this.VisitExpression(assignment.Target); assignment.Source = normalizedSource; assignment.Target = normalizedTarget; if (inExpressionStatement) return assignment; else { // This form shows up in initialized local variables. We have to wrap the // assignment back up to get the decompiler to generate appropriate code. ExpressionStatement exprStmt = new ExpressionStatement(new AssignmentExpression(assignment)); exprStmt.SourceContext = assignment.SourceContext; return exprStmt; } }
private Statement ParseLocalDeclarations(TypeNode t, SourceContext ctx, bool constant, bool initOnly, bool preferExpressionToDeclaration, bool skipSemicolon, TokenSet followers){ TypeNode firstT = t; LocalDeclarationsStatement result = new LocalDeclarationsStatement(); result.SourceContext = ctx; result.Constant = constant; result.InitOnly = initOnly; ScannerState oss = this.scanner.state; LocalDeclarationList locList = result.Declarations = new LocalDeclarationList(); result.Type = result.TypeExpression = t; for(;;){ LocalDeclaration loc = new LocalDeclaration(); loc.SourceContext = this.scanner.CurrentSourceContext; locList.Add(loc); loc.Name = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); if (this.currentToken == Token.LeftBracket){ this.HandleError(Error.CStyleArray); int endPos = this.scanner.endPos; int rank = this.ParseRankSpecifier(true, followers|Token.RightBracket|Parser.IdentifierOrNonReservedKeyword|Token.Assign|Token.Semicolon|Token.Comma); if (rank > 0) t = result.Type = result.TypeExpression = this.ParseArrayType(rank, t, followers|Token.RightBracket|Parser.IdentifierOrNonReservedKeyword|Token.Assign|Token.Semicolon|Token.Comma); else{ this.currentToken = Token.LeftBracket; this.scanner.endPos = endPos; this.GetNextToken(); while (!this.scanner.TokenIsFirstAfterLineBreak && this.currentToken != Token.RightBracket && this.currentToken != Token.Assign && this.currentToken != Token.Semicolon) this.GetNextToken(); if (this.currentToken == Token.RightBracket) this.GetNextToken(); } } if (this.currentToken == Token.LeftParenthesis){ this.HandleError(Error.BadVarDecl); int dummy; SourceContext lpCtx = this.scanner.CurrentSourceContext; this.GetNextToken(); this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon|Token.Comma, lpCtx, out dummy); }else if (this.currentToken == Token.Assign || constant){ this.Skip(Token.Assign); if (this.currentToken == Token.LeftBrace) loc.InitialValue = this.ParseArrayInitializer(t, followers|Token.Semicolon|Token.Comma); else loc.InitialValue = this.ParseExpression(followers|Token.Semicolon|Token.Comma); } if (loc.InitialValue != null) loc.SourceContext.EndPos = loc.InitialValue.SourceContext.EndPos; else loc.SourceContext.EndPos = this.scanner.endPos; if (this.currentToken != Token.Comma) break; this.GetNextToken(); SourceContext sctx = this.scanner.CurrentSourceContext; ScannerState ss = this.scanner.state; TypeNode ty = this.ParseTypeExpression(null, followers|Token.Identifier|Token.Comma|Token.Semicolon, true); if (ty == null || this.currentToken != Token.Identifier){ this.scanner.endPos = sctx.StartPos; this.scanner.state = ss; this.currentToken = Token.None; this.GetNextToken(); }else this.HandleError(sctx, Error.MultiTypeInDeclaration); } if (Parser.IsVoidType(firstT)){ this.HandleError(ctx, Error.NoVoidHere); result.Type = this.TypeExpressionFor(Token.Object); result.Type.SourceContext = firstT.SourceContext; } if (preferExpressionToDeclaration && this.currentToken != Token.Semicolon && locList.Count == 1 && locList[0].InitialValue == null){ //The parse as a declaration is going to fail. Since an expression is preferred, restore the state and reparse as an expression this.scanner.endPos = ctx.StartPos; this.scanner.state = oss; this.currentToken = Token.None; this.GetNextToken(); ExpressionStatement eStat = new ExpressionStatement(this.ParseExpression(followers)); if (eStat.Expression != null) eStat.SourceContext = eStat.Expression.SourceContext; return eStat; } if (skipSemicolon) this.SkipSemiColon(followers); this.SkipTo(followers); return result; }
// The method added by Jiri Adamek // It generates NAtiveZOM calls private void GenerateNativeZOMCall(Block block, MethodCall call, bool callIsAsync, AssignmentStatement assignmentStatement) { ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember; // Eventually, this will be checked by an earlier phase. Debug.Assert(method.Parameters.Count == call.Operands.Count); // Asynchronous calls Debug.Assert(!callIsAsync, "async not supporrted for NativeZOM calls"); // Debugging - parameters for (int i = 0, n = call.Operands.Count; i < n; i++) { Parameter param = method.Parameters[i]; Debug.Assert(param != null); // In fact, call.operands[i] MAY BE null due to the error recovery (if the type of the // expression does not match the type in the method definition) // // Debug.Assert(call.Operands[i] != null); Debug.Assert((param.Flags & ParameterFlags.Out) == 0, "out parameters not supported for NativeZOM calls"); } Expression typename = new QualifiedIdentifier(new Identifier("Microsoft.Zing"), method.DeclaringType.Name); Expression callee; if (!method.IsStatic) { callee = Templates.GetExpressionTemplate("NativeZOMCallee"); Replacer.Replace(callee, "_TypeName", typename); Expression pointer = this.VisitExpression(((MemberBinding)call.Callee).TargetObject); Replacer.Replace(callee, "_Pointer", pointer); Replacer.Replace(callee, "_MethodName", method.Name); } else { callee = Templates.GetExpressionTemplate("NativeZOMStaticCall"); Replacer.Replace(callee, "_ClassName", typename); Replacer.Replace(callee, "_MethodName", method.Name); } ExpressionList argumentList = new ExpressionList(); argumentList.Add(Templates.GetExpressionTemplate("NativeZOMCallFirstArgument")); foreach (Expression operand in call.Operands) argumentList.Add(this.VisitExpression(operand)); MethodCall nativeCall = new MethodCall(callee, argumentList); Statement newStatement; if (assignmentStatement != null) { newStatement = Templates.GetStatementTemplate("NativeZOMCallWithAssignment"); Replacer.Replace(newStatement, "_Dest", this.VisitExpression(assignmentStatement.Target)); Replacer.Replace(newStatement, "_Source", nativeCall); } else { newStatement = new ExpressionStatement(nativeCall); } block.Statements.Add(newStatement); }
public override Statement VisitExpressionStatement(ExpressionStatement statement) { if (statement == null) return null; return base.VisitExpressionStatement((ExpressionStatement)statement.Clone()); }
public override Statement VisitExpressionStatement(ExpressionStatement statement) { WriteStart(string.Empty); int len = this.SourceLength; base.VisitExpressionStatement(statement); if (len != this.SourceLength) Write(";"); WriteFinish(string.Empty); return statement; }
internal void RecordUnnecessaryCheck(ExpressionStatement es) { if (es == null) return; eliminateCheck[es] = true; }