internal static Block CreateTryFinallyBlock(Method method, Block tryBody, Block finallyBody) { Contract.Requires(method != null); Contract.Requires(tryBody != null); Contract.Requires(finallyBody != null); if (method.ExceptionHandlers == null) method.ExceptionHandlers = new ExceptionHandlerList(); Block result = new Block(new StatementList()); Block afterFinally = new Block(new StatementList()); tryBody.Statements.Add(new Branch(null, afterFinally, false, true, true)); finallyBody.Statements.Add(new EndFinally()); result.Statements.Add(tryBody); result.Statements.Add(finallyBody); result.Statements.Add(afterFinally); ExceptionHandler fb = new ExceptionHandler(); fb.TryStartBlock = tryBody; fb.BlockAfterTryEnd = finallyBody; fb.HandlerStartBlock = finallyBody; fb.BlockAfterHandlerEnd = afterFinally; fb.HandlerType = NodeType.Finally; method.ExceptionHandlers.Add(fb); return result; }
public override Block VisitBlock(Block block) { if (block == null) return null; LocalsStack stackLocalsAtEntry = (LocalsStack)this.StackLocalsAtEntry[block.UniqueKey]; if (stackLocalsAtEntry == null) { //Unreachable code, or the very first block stackLocalsAtEntry = new LocalsStack(); } this.localsStack = stackLocalsAtEntry.Clone(); base.VisitBlock(block); Block successor = (Block)this.SucessorBlock[block.UniqueKey]; if (successor != null) { //Dropping off into successor. LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[successor.UniqueKey]; if (targetStack != null && targetStack.top >= 0) { //Another predecessor block has already decided what the stack for the successor block is going to look like. //Reconcile the stack from this block with the stack expected by the successor block. this.localsStack.Transfer(targetStack, block.Statements); } else { this.StackLocalsAtEntry[successor.UniqueKey] = this.localsStack; } } return block; }
public CollectOldExpressions(Module module, Method method, ContractNodes contractNodes, Dictionary<TypeNode, Local> closureLocals, int localCounterStart) { this.contractNodes = contractNodes; this.prestateValuesOfOldExpressions = new Block(new StatementList()); this.closureLocals = closureLocals; this.stackOfMethods = new List<MethodCall>(); this.stackOfBoundVariables = new List<Parameter>(); this.module = module; this.currentMethod = method; this.counter = localCounterStart; }
public override Block VisitBlock(Block block){ if (block == null) return null; StatementList savedStatementList = this.CurrentStatementList; try{ StatementList oldStatements = block.Statements; int n = oldStatements == null ? 0 : oldStatements.Length; StatementList newStatements = this.CurrentStatementList = block.Statements = new StatementList(n); for (int i = 0; i < n; i++) newStatements.Add((Statement)this.Visit(oldStatements[i])); return block; }finally{ this.CurrentStatementList = savedStatementList; } }
internal static Statement GenerateForLoop(Variable loopVariable, Expression lowerBound, Expression upperBound, Statement body) { Block bodyAsBlock = body as Block ?? new Block(new StatementList(body)); Block init = new Block(new StatementList(2)); Block increment = new Block(new StatementList(1)); Block test = new Block(new StatementList(new Branch( new BinaryExpression(loopVariable, upperBound, NodeType.Lt), bodyAsBlock))); //, false, true, false))); init.Statements.Add(new AssignmentStatement(loopVariable, lowerBound)); init.Statements.Add(new Branch(null, test)); increment.Statements.Add(new AssignmentStatement(loopVariable, new BinaryExpression(loopVariable, Literal.Int32One, NodeType.Add))); Block forLoop = new Block(new StatementList(4)); forLoop.Statements.Add(init); forLoop.Statements.Add(bodyAsBlock); forLoop.Statements.Add(increment); forLoop.Statements.Add(test); return forLoop; }
BinaryExpression IsStartOf(Block block, TypeNode type, StatementList statements, Expression nameLocal, Expression nsLocal, StringBuilder expecting) { BinaryExpression result = null; if (IsStructuralType(type)) { SchemaElementDecl sd = SchemaElementDecl.Compile(this.module, type, Checker.GetCollectionElementType(type), this.errorHandler, schemaElementDeclCache); SchemaValidator validator = validator = sd.CreateValidator(this.errorHandler); ValidationState context = new ValidationState(); context.ErrorHandler = this.errorHandler; validator.validator.InitValidation(context); ArrayList members = validator.validator.ExpectedElements(context, false, false); foreach (TerminalNode node in members) { if (node is NamedNode) { NamedNode n = node as NamedNode; Identifier name = n.Name; if (expecting.Length>0) expecting.Append(" | "); expecting.Append(name.Name); BinaryExpression isName = new BinaryExpression(nameLocal, new Literal(name.Name, SystemTypes.String), NodeType.Eq); if (name.Prefix != null) { isName = new BinaryExpression(isName, new BinaryExpression(nsLocal, new Literal(name.Prefix.Name, SystemTypes.String), NodeType.Eq), NodeType.And); } if (result == null) result = isName; else result = new BinaryExpression(result, isName, NodeType.Or); } else if (node is WildcardNode) { // todo:??? } } } else { Identifier name = Checker.GetDefaultElementName(type); if (expecting.Length>0) expecting.Append(" | "); expecting.Append(name.Name); result = new BinaryExpression(nameLocal, new Literal(name.Name, SystemTypes.String), NodeType.Eq); if (name.Prefix != null) { result = new BinaryExpression(result, new BinaryExpression(nsLocal, new Literal(name.Prefix.Name, SystemTypes.String), NodeType.Eq), NodeType.And); } } return result; }
void AddReadStream(Block block, TypeNode type, StatementList statements, Identifier reader, Expression target, Expression result){ // Read next element and figure out if it matches the stream element type, if so read it and add it to the list // If not, then return (throw an error if there are no items and the list is the non-empty type). // flexArray = new flexarray(); // while (reader.Read() && read.NodeType != XmlNodeType.EndElement) { // if (reader.NodeType == XmlNodeType.Element) { // readchild(flexarray); // } // } // target = flexArray; Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String, block); Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String, block); Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType, block); Local optional = new Local(Identifier.Empty, SystemTypes.Boolean, block); Local foundChild = new Local(Identifier.Empty, SystemTypes.Boolean, block); statements.Add(new AssignmentStatement(optional, Literal.False)); TypeNode eType = Checker.GetCollectionElementType(type); Local local = new Local(Identifier.Empty, eType, block); Method addMethod = null; Local localArray = null; if (type.Template == SystemTypes.GenericBoxed) { addMethod = null; // only needs one! } else if (Checker.IsGenericList(type)) { //TODO: this call is invalid if the eType is not public TypeNode flexArrayType = SystemTypes.GenericList.GetTemplateInstance(this.module, eType); localArray = new Local(Identifier.For("stream"+streamCount++), flexArrayType, block); statements.Add(new AssignmentStatement(localArray, new Construct(new MemberBinding(null, flexArrayType), new ExpressionList(), flexArrayType))); addMethod = flexArrayType.GetMethod(Identifier.For("Add"), eType); } else { TypeNode arrayType = SystemTypes.ArrayList; localArray = new Local(Identifier.Empty, arrayType, block); statements.Add(new AssignmentStatement(localArray, new Construct(new MemberBinding(null, arrayType), new ExpressionList(), arrayType))); addMethod = arrayType.GetMethod(Identifier.For("Add"), SystemTypes.Object); } Block whileBody = new Block(new StatementList()); MethodCall moveToContent = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList()); BinaryExpression notAtEnd = new BinaryExpression(moveToContent, new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Ne); BinaryExpression notEOF = new BinaryExpression( new QualifiedIdentifier(reader, Identifier.For("EOF")), Literal.True, NodeType.Ne); While w = new While(new BinaryExpression(notAtEnd, notEOF, NodeType.And), whileBody); statements.Add(w); whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); whileBody.Statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType")))); StatementList trueStatements = whileBody.Statements; if (type.Template == SystemTypes.GenericBoxed){ type = Checker.GetCollectionElementType(type); } trueStatements.Add(new AssignmentStatement(foundChild, Literal.False)); if (eType is TupleType || eType is TypeUnion || IsStream(eType)) { AddCallDeserializer(eType, trueStatements, reader, local, optional, foundChild); } else { AddReadChild(whileBody, trueStatements, Checker.GetDefaultElementName(eType), eType, local, reader, foundChild, true, false); } If ifFound = new If(new BinaryExpression(foundChild, Literal.True, NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); ifFound.TrueBlock.Statements.Add(new AssignmentStatement(result, Literal.True)); // set our result to true then. ifFound.FalseBlock.Statements.Add(new Exit()); // break out of loop then. trueStatements.Add(ifFound); if (addMethod == null) { trueStatements.Add(new AssignmentStatement(target, CastTo(local, type))); // box the result. trueStatements.Add(new Exit()); // break out of loop we have it! } else { MemberBinding addCall = new MemberBinding(localArray, addMethod); trueStatements.Add(new ExpressionStatement(new MethodCall(addCall, new ExpressionList(new Expression[1] {local})))); } // clear out the local, it is a struct of some sort. if (local.Type.IsValueType && ! local.Type.IsPrimitive) { trueStatements.Add(new AssignmentStatement(local, new Construct(new MemberBinding(null,local.Type), new ExpressionList(), local.Type))); } // end while // assign resulting array to the target object (if we have anything to assign). If ifResult = new If(new BinaryExpression(result, Literal.True, NodeType.Eq), new Block(new StatementList()), null); statements.Add(ifResult); statements = ifResult.TrueBlock.Statements; if (addMethod != null) { if (type is ArrayType) { // target = (type)localArray.ToArray(etype); Method toArray = SystemTypes.ArrayList.GetMethod(Identifier.For("ToArray"), SystemTypes.Type); ExpressionList args = new ExpressionList(); args.Add(new UnaryExpression(new Literal(eType, SystemTypes.Type), NodeType.Typeof, SystemTypes.Type)); statements.Add(new AssignmentStatement(target, CastTo(new MethodCall(new MemberBinding(localArray, toArray), args, NodeType.Callvirt, SystemTypes.Array), type))); } else if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) { // Explicit coercion of IEnumerable to NonEmptyIEnumerable requires constructing // the NonEmptyIEnumerable object passing in the IEnumerable as an argument. TypeNode ienumtype = Checker.GetIEnumerableTypeFromNonEmptyIEnumerableStruct(this.module, type); Debug.Assert(ienumtype!=null); //TODO: this call is invalid if the eType is not public TypeNode nonEmptyIEnum = SystemTypes.GenericNonEmptyIEnumerable.GetTemplateInstance(this.module, eType); InstanceInitializer ii = nonEmptyIEnum.GetConstructor(ienumtype); Construct c = new Construct(new MemberBinding(null, ii), new ExpressionList(localArray), nonEmptyIEnum); statements.Add(new AssignmentStatement(target, c)); } else { statements.Add(new AssignmentStatement(target, localArray)); } } }
void AddReadRequiredChild(Block scope, StatementList statements, Identifier name, TypeNode type, Expression target, Identifier reader, Expression result, Expression required, bool unwrapChild, bool ignoreNamespace) { Block elseBlock = AddReadChild(scope, statements, name, type, target, reader, result, unwrapChild, ignoreNamespace).FalseBlock; If notFoundButRequired = new If(new BinaryExpression(required,Literal.True,NodeType.Eq), new Block(new StatementList()), null); InvalidContent(notFoundButRequired.TrueBlock.Statements, reader, name.Name.ToString()); elseBlock.Statements.Add(notFoundButRequired); }
void AddReadChoice(Block block, TypeUnion tu, StatementList statements, Identifier reader, Expression target, Expression required, Expression result){ // Read next element and figure out which of the choices in the type union it is then read the matching Type. Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String,block); Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String,block); Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType,block); statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType")))); Local localRequired = new Local(Identifier.Empty,SystemTypes.Boolean,block); statements.Add(new AssignmentStatement(localRequired, Literal.True)); Expression readString = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadString")), null, NodeType.Callvirt, SystemTypes.String); If ifIsElement = new If(new BinaryExpression(nodeType, new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); statements.Add(ifIsElement); StatementList elseList = ifIsElement.TrueBlock.Statements; StringBuilder expecting = new StringBuilder(); Expression bestCoercion = null; TypeNode bestChoice = null; TypeNode bestUnwrappedChoice = null; bool stringCoercionAmbiguous = false; for (int i = 0, n = tu.Types.Length; i < n; i++) { TypeNode choice = tu.Types[i]; if (choice == null) continue; // type resolution error. TypeNode unwrapped = UnwrapSingletonTuple(Unwrap(choice), false); if (unwrapped == null) unwrapped = choice; Expression coercion = GetConvertFromString(unwrapped, readString, false); if (coercion != null) { // Keep track of the best coercion to string and use this to handle text nodes below. if (bestChoice == null){ bestChoice = choice; bestUnwrappedChoice = unwrapped; bestCoercion = coercion; } else if (tempTypeSystem.IsBetterMatch(unwrapped, bestUnwrappedChoice, SystemTypes.String)) { bestChoice = choice; bestUnwrappedChoice = unwrapped; bestCoercion = coercion; } else { stringCoercionAmbiguous = true; } } BinaryExpression be = IsStartOf(block, choice, statements, nameLocal, nsLocal, expecting); StatementList trueStatements = new StatementList(); If ifIsStartOf = new If(be, new Block(trueStatements), new Block(new StatementList())); elseList.Add(ifIsStartOf); Local choiceTarget = new Local(Identifier.Empty, choice, block); if (choice.Template == SystemTypes.GenericBoxed){ choice = Checker.GetCollectionElementType(choice); } if (!AddReadSimpleType(choice, trueStatements, reader, choiceTarget, result, false)) { AddCallDeserializer(choice, trueStatements, reader, choiceTarget, localRequired, result); } trueStatements.Add(new AssignmentStatement(target, CastTo(choiceTarget, target.Type))); elseList = ifIsStartOf.FalseBlock.Statements; } if (bestCoercion != null && !stringCoercionAmbiguous) { // Then we can also accept text nodes StatementList ifTextStatements = new StatementList(); If ifIsText = new If(IsTextNode(nodeType), new Block(ifTextStatements), null); ifIsElement.FalseBlock.Statements.Add(ifIsText); // then we can also handle text nodes in this choice. ifTextStatements.Add(new AssignmentStatement(target, CastTo(CastTo(bestCoercion, bestChoice), tu))); ifTextStatements.Add(new AssignmentStatement(result, Literal.True)); } // If this was a required element, then throw an error. If isRequired = new If(new BinaryExpression(required, Literal.True, NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); elseList.Add(isRequired); InvalidContent(isRequired.TrueBlock.Statements, reader, expecting.ToString()); isRequired.FalseBlock.Statements.Add(new AssignmentStatement(result, Literal.False)); }
//================= reader methods ========================================== void AddReadAttributes(TypeNode type, StatementList statements, Identifier reader, Expression target, SchemaValidator validator) { if (validator.Attributes != null) { Block whileBody = new Block(new StatementList()); Literal trueLit = Literal.True; MethodCall movenext = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToNextAttribute")), new ExpressionList()); BinaryExpression condition = new BinaryExpression(movenext, trueLit, NodeType.Eq); While w = new While(condition, whileBody); statements.Add(w); Block lastElseBlock = null; Local nameLocal = new Local(SystemTypes.String); whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); Local nsLocal = new Local(SystemTypes.String); whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); foreach (SchemaAttDef ad in validator.Attributes) { // todo: any way to do tokenized compares? BinaryExpression nameEqual = new BinaryExpression(nameLocal, new Literal(ad.Name.Name, SystemTypes.String), NodeType.Eq); BinaryExpression nsEqual = new BinaryExpression(nsLocal, new Literal(ad.Name.Prefix != null ? ad.Name.Prefix.Name : "", SystemTypes.String), NodeType.Eq); Block elseBlock = new Block(new StatementList()); If ifExpr = new If(new BinaryExpression(nameEqual, nsEqual, NodeType.And), new Block(new StatementList()), elseBlock); if (lastElseBlock != null) { lastElseBlock.Statements.Add(ifExpr); } else { whileBody.Statements.Add(ifExpr); } lastElseBlock = elseBlock; // body of if test, parse the attribute value as the specified type. Debug.Assert(ad.Member is Field || ad.Member is Property); AddReadSimpleType(Checker.GetMemberType(ad.Member), ifExpr.TrueBlock.Statements, reader, GetMemberBinding(target, ad.Member), null, true); } //todo: report unknown attributes? } }
private void GenerateMethodReturn(Block block, AssignmentStatement assignmentStatement, MethodCall call) { ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember; // Eventually, this will be checked by an earlier phase. Debug.Assert(method.Parameters.Count == call.Operands.Count); // process output parameters and the return value; for (int i = 0, n = call.Operands.Count; i < n; i++) { Parameter param = method.Parameters[i]; if ((param.Flags & ParameterFlags.Out) != 0 && call.Operands[i] != null && method.Parameters[i] != null) { Statement assignOutParam = Templates.GetStatementTemplate("FetchOutputParameter"); Replacer.Replace(assignOutParam, "_dest", this.VisitExpression(((UnaryExpression)call.Operands[i]).Operand)); Replacer.Replace(assignOutParam, "_paramName", new Identifier("_Lfc_" + method.Parameters[i].Name.Name)); Replacer.Replace(assignOutParam, "_Callee", method.Name); Replacer.Replace(assignOutParam, "_CalleeClass", method.DeclaringType.Name); block.Statements.Add(assignOutParam); } } if (assignmentStatement != null) { Statement assignReturnValue = Templates.GetStatementTemplate("FetchReturnValue"); Replacer.Replace(assignReturnValue, "_dest", this.VisitExpression(assignmentStatement.Target)); Replacer.Replace(assignReturnValue, "_CalleeClass", method.DeclaringType.Name); Replacer.Replace(assignReturnValue, "_Callee", method.Name); block.Statements.Add(assignReturnValue); } Statement stmt = Templates.GetStatementTemplate("InvalidateLastFunctionCompleted"); block.Statements.Add(stmt); }
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; } }
void AddWriteChoice(TypeUnion tu, StatementList statements, TypeNode referringType, Expression src, Identifier writer) { // generate the following code: // Type srcType = src.GetType(); // if (choiceType.IsAssignableFrom(srcType)){ // XxxxSerializer s = new XxxxSerializer(); // s.Serialize((runtimeType)src, writer); // } else if (...) { // // and so on. // } // What we cannot do here is by creating nested XmlSerializers // based on runtime type because this could cause infinite recurrsion. // So we cannot serialize a type union where one of the choices is "object". TypeNodeList choices = tu.Types; MethodCall call = new MethodCall(); call.Callee = new QualifiedIdentifier(src, Identifier.For("GetType")); call.Operands = new ExpressionList(); Local local = new Local(SystemTypes.Type); statements.Add(new AssignmentStatement(local, call)); for (int i = 0, n = choices.Length; i < n; i++) { TypeNode choiceType = choices[i]; if (choiceType == null) continue; // type resolution error. // if (choiceType.IsAssignableFrom(srcType)){ BinaryExpression condition = new BinaryExpression( new MethodCall( new QualifiedIdentifier(new UnaryExpression(new MemberBinding(null, choiceType), NodeType.Typeof), Identifier.For("IsAssignableFrom")), new ExpressionList(new Expression[] { local })), Literal.True, NodeType.Eq); Block block = new Block(); block.Statements = new StatementList(); BinaryExpression cast = CastTo(src, choiceType); Expression name = null, ns = null; GetNameAndNamespace(choiceType, out name, out ns); Expression simplename = name, simplens = ns; // Check for choice of type: [string] and match this with XmlTextNode. TypeNode unwrapped = UnwrapSingletonTuple(choiceType, true); if (unwrapped == null) unwrapped = choiceType; if (unwrapped != null && unwrapped.IsPrimitive) { simplename = simplens = null; choiceType = unwrapped; } if (!AddWriteSimpleType(choiceType, block.Statements, referringType, writer, cast, simplename, simplens)) { AddCallSerializer(choiceType, block.Statements, cast, writer, name, ns); } If ifStatement = new If(condition, block, null); statements.Add(ifStatement); } }
public override void ConstructMethodForNestedFunction(Node func, Method method, TypeNode returnType, ParameterList parList, Block body){ base.ConstructMethodForNestedFunction(func, method, returnType, parList, body); if (method != null && body != null) method.SourceContext.EndPos = body.SourceContext.EndPos+1; }
/// <summary> /// Scans the entire block to find 0 or more closure initializations. For each, it adds an entry to the dictionary /// mapping the closure type to the closure local. /// </summary> internal static void RecordClosureInitialization(Method containing, Block b, Dictionary<TypeNode, Local> closureLocalMap) { Contract.Requires(closureLocalMap != null); Local closureLocal = null; if (b == null || b.Statements == null || !(b.Statements.Count > 0)) { return; } for (int i = 0; i < b.Statements.Count; i++) { Statement s = b.Statements[i]; if (s == null || s.NodeType == NodeType.Nop) continue; if (HelperMethods.IsClosureCreation(containing, s, out closureLocal)) { if (closureLocal != null) { closureLocalMap.Add(closureLocal.Type, closureLocal); } } } }
public override Block VisitBlock(Block block){ if (block == null) return null; Block savedCurrentBlock = this.currentBlock; this.currentBlock = block; block = base.VisitBlock(block); if (block != null && block.Scope != null){ MemberList blockLocals = block.Scope.Members; for (int i = 0, n = blockLocals == null ? 0 : blockLocals.Count; i < n; i++){ Field f = blockLocals[i] as Field; if (f == null) continue; } } this.currentBlock = savedCurrentBlock; return block; }
private Statement VisitJoinStatement(JoinStatement joinstmt) { // // The first block of a join statement pair only tests the condition. // It needs no executable statements. // if (!this.secondOfTwo) return null; bool anyEvents = false; Block stmtBlock = new Block(); stmtBlock.Statements = new StatementList(); for (int i = 0, n = joinstmt.joinPatternList.Length; i < n; i++) { JoinPattern jp = joinstmt.joinPatternList[i]; ReceivePattern receivePattern = jp as ReceivePattern; WaitPattern waitPattern = jp as WaitPattern; EventPattern eventPattern = jp as EventPattern; if (receivePattern != null) { // Construct a statement to actually perform the receive. Statement receiveStmt = Templates.GetStatementTemplate("ReceivePattern"); Replacer.Replace(receiveStmt, "_chanExpr", this.VisitExpression(receivePattern.channel)); Replacer.Replace(receiveStmt, "_chanType", receivePattern.channel.Type.Name); Replacer.Replace(receiveStmt, "_target", this.VisitExpression(receivePattern.data)); Replacer.Replace(receiveStmt, "_context", splicer.SourceContextConstructor(jp.SourceContext)); Replacer.Replace(receiveStmt, "_contextAttr", splicer.ContextAttributeConstructor(this.attributes)); // // If the type is complex, we need to cast to Z.Pointer instead of the given type // TypeNode tn = receivePattern.data.Type; if (tn is Set || tn is ZArray || tn is Class || tn is Chan) Replacer.Replace(receiveStmt, "_targetType", new Identifier("Pointer")); else Replacer.Replace(receiveStmt, "_targetType", receivePattern.data.Type.Name); stmtBlock.Statements.Add(receiveStmt); ; } else if (eventPattern != null) { Statement eventStmt = Templates.GetStatementTemplate("Event"); Replacer.Replace(eventStmt, "_chanExpr", this.VisitExpression(eventPattern.channelNumber)); Replacer.Replace(eventStmt, "_msgExpr", this.VisitExpression(eventPattern.messageType)); Replacer.Replace(eventStmt, "_dirExpr", this.VisitExpression(eventPattern.direction)); Replacer.Replace(eventStmt, "_context", splicer.SourceContextConstructor(eventPattern.SourceContext)); Replacer.Replace(eventStmt, "_contextAttr", splicer.ContextAttributeConstructor(this.attributes)); stmtBlock.Statements.Add(eventStmt); anyEvents = true; } } if (joinstmt.visible && !anyEvents) { Statement eventStmt = Templates.GetStatementTemplate("TauEvent"); Replacer.Replace(eventStmt, "_context", splicer.SourceContextConstructor(joinstmt.SourceContext)); Replacer.Replace(eventStmt, "_contextAttr", splicer.ContextAttributeConstructor(this.attributes)); stmtBlock.Statements.Add(eventStmt); } return stmtBlock; }
// 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); }
void AddReadAlias( Block block, TypeAlias alias, StatementList statements, Identifier reader, Expression target, Expression required, Expression result) { Local local = new Local(Identifier.Empty, alias.AliasedType, block); AddReadRequiredChild(block, statements, alias.Name, alias.AliasedType, local, reader, result, required, true, true); statements.Add(new AssignmentStatement(target, this.tempChecker.typeSystem.ImplicitCoercion(local, target.Type))); }
void AddReadContentNode(ContentNode n, Block block, StatementList statements, Identifier reader, Expression target, Expression required, Expression result, SchemaValidator validator) { if (n.TypeNode == null) { Debug.Assert(n is SequenceNode); // In the class inheritance case we have two independent left and right children inside // a parent sequence that has no unified type or member. SequenceNode s = (SequenceNode)n; AddReadContentNode(s.LeftChild, block, statements, reader, target, required, result, validator); AddReadContentNode(s.RightChild, block, statements, reader, target, required, result, validator); return; } TypeNode ct = n.TypeNode; Debug.Assert(ct != null); if (n.Member != null && !(n.Member is Method)) { target = GetMemberBinding(target, n.Member); ct = target.Type; } // todo: might be content model AND mixed, in which case we have to pass the MixedMember // to AddReadTuple, AddReadChoice and AddReadStream. if (ct.Template == SystemTypes.GenericBoxed){ ct = Checker.GetCollectionElementType(ct); } if (ct is TupleType) { AddReadTuple(block, ct as TupleType, statements, reader, target, required, result); } else if (ct is TypeUnion) { AddReadChoice(block, ct as TypeUnion, statements, reader, target, required, result); } else if (IsStream(ct)) { AddReadStream(block, ct, statements, reader, target, result); } else if (ct is TypeAlias) { AddReadAlias(block, ct as TypeAlias, statements, reader, target, required, result); } else { Identifier name = Checker.GetDefaultElementName(ct); AddReadRequiredChild(block, statements, name, ct, target, reader, result, required, true, false); } }
If AddReadChild(Block scope, StatementList statements, Identifier name, TypeNode type, Expression target, Identifier reader, Expression result, bool unwrapChild, bool ignoreNamespace) { ExpressionList args = new ExpressionList(); args.Add(new Literal(name.Name, SystemTypes.String)); if (name.Prefix != null) args.Add(new Literal(name.Prefix.Name, SystemTypes.String)); // see if we're on a text node... Local nodeType = new Local(Identifier.For("nodeType"), Runtime.XmlNodeType, scope); statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType")))); StatementList ifTextStatements = new StatementList(); If ifIsText = new If( new BinaryExpression(IsTextNode(nodeType), new BinaryExpression(nodeType, new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Eq), NodeType.Or), new Block(ifTextStatements), new Block(new StatementList())); statements.Add(ifIsText); // then see if we can force the text into the desired type. TypeNode unwrapped = UnwrapSingletonTuple(Unwrap(type), false); if (unwrapped == null) unwrapped = type; Expression readString = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadString")), null, NodeType.Callvirt, SystemTypes.String); Expression coercion = GetConvertFromString(unwrapped, readString, false); if (coercion != null) { ifTextStatements = ifIsText.TrueBlock.Statements; ifTextStatements.Add(new AssignmentStatement(target, CastTo(CastTo(coercion, unwrapped),type))); ifTextStatements.Add(new AssignmentStatement(result, Literal.True)); } statements = ifIsText.FalseBlock.Statements; If ifFound = null; string method = ignoreNamespace ? "IsStartElementIgnoreNamespace" : "IsStartElement"; MethodCall isStartEle = new MethodCall(new QualifiedIdentifier(reader, Identifier.For(method)), args); ifFound = new If(isStartEle, new Block(new StatementList()), new Block(new StatementList())); statements.Add(ifFound); statements = ifFound.TrueBlock.Statements; statements.Add(new AssignmentStatement(result, Literal.True)); // body of if test, parse the child element as the specified type. MethodCall read = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList()); bool isStructuralType = this.IsStructuralType(type); if (isStructuralType && unwrapChild) { // consume member element wrapper. statements.Add(new ExpressionStatement(read)); } if (type.Template == SystemTypes.GenericBoxed){ type = Checker.GetCollectionElementType(type); } if (!AddReadSimpleType(type, statements, reader, target, result, false)) { AddCallDeserializer(type, statements, reader, target, result, result); } if (isStructuralType && unwrapChild) { // consume member element end tag wrapper. statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadEndTag")), new ExpressionList(new Literal(name.Name, SystemTypes.String))))); } return ifFound; }
public override Block VisitBlock(Block block) { // We special-case this because it's how a null statement is // represented. if (block.Statements == null) { WriteLine(";"); return block; } if (this.braceOnNewLine) { WriteFinish(string.Empty); WriteLine("{"); } else WriteFinish(" {"); In(); Block result = base.VisitBlock(block); Out(); WriteLine("}"); return result; }
void AddWriteStream(TypeNode type, StatementList statements, TypeNode referringType, Expression src, Identifier writer) { // Generate the following code: // XxxxSerializer s = new XxxxSerializer(); // foreach (Xxxx x in src) { // s.Serialize(x,writer); // } // Where Xxxx is the element type for the given stream type. if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) { type = Checker.GetIEnumerableTypeFromNonEmptyIEnumerableStruct(this.module, type); } else { statements = AddCheckForNull(statements, Duplicate(src, referringType), type); } TypeNode ceType = Checker.GetCollectionElementType(type); //todo: should check that type has an IEnumerator. Identifier loopVariable = Identifier.For("e"); loopVariable.Type = ceType; Block body = new Block(); body.Statements = new StatementList(); Expression name, ns; GetNameAndNamespace(ceType, out name, out ns); // call the Serialize method on it, passing the member we're serializing. if (!AddWriteSimpleType(ceType, body.Statements, referringType, writer, loopVariable, name, ns)) { AddCallSerializer(ceType, body.Statements, loopVariable, writer, name, ns); } ForEach fe = new ForEach(ceType, loopVariable, src, body); statements.Add(fe); }
internal static bool IsNonTrivial(Block block) { if (block == null) return false; if (block.Statements == null) return false; foreach (var s in block.Statements) { if (IsNonTrivial(s)) return true; } return false; }
void AddReadContent(Class serializer, Block block, TypeNode type, StatementList statements, Identifier reader, Expression target, Expression required, Expression result, SchemaValidator validator) { // position us in the content. statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList()))); Local elementName = new Local(Identifier.Empty,SystemTypes.String); statements.Add(new AssignmentStatement(elementName, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); // make sure the element is not empty. If isEmpty = AddEmptyElementCheck(statements, reader); // Read the contents. statements = isEmpty.FalseBlock.Statements; statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList()))); statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList()))); ValidationState context = new ValidationState(); context.ErrorHandler = this.errorHandler; validator.validator.InitValidation(context); ArrayList members = null; if (validator.validator is AllElementsContentValidator) { members = validator.validator.ExpectedElements(context, false, false); AddReadAllGroup(serializer, block, type, statements, reader, target, required, result, members, validator.validator.MixedMember); } else { // There should be one root level anonymous Item0 member. SequenceNode seq = (SequenceNode)validator.RootNode; // this is a wrapper node. if (seq == null) { // perhaps it is ContentType.Empty or Mixed. if (validator.validator.ContentType == XmlSchemaContentType.Mixed || validator.validator.ContentType == XmlSchemaContentType.TextOnly){ Debug.Assert(validator.validator.MixedMember != null); statements.Add(new AssignmentStatement(GetMemberBinding(target, validator.validator.MixedMember), new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadStringElement")), new ExpressionList()))); } return; } else { ContentNode n = seq.LeftChild; AddReadContentNode(n, block, statements, reader, target, required, result, validator); } } // consume final end tag statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadEndTag")), new ExpressionList(elementName)))); }
private void GenerateMethodCall(Block block, MethodCall call, bool callIsAsync) { ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember; // Eventually, this will be checked by an earlier phase. Debug.Assert(method.Parameters.Count == call.Operands.Count); Statement createCallFrame; if (method.DeclaringType is Interface) { createCallFrame = Templates.GetStatementTemplate("CreateCallFrameForInterface"); Replacer.Replace(createCallFrame, "_thisExpr", this.VisitExpression(((MemberBinding)call.Callee).TargetObject)); Replacer.Replace(createCallFrame, "_CreateMethod", new Identifier("Create" + method.Name.Name)); } else { createCallFrame = Templates.GetStatementTemplate("CreateCallFrame"); } Replacer.Replace(createCallFrame, "_calleeClass", new Identifier(method.DeclaringType.FullName)); Replacer.Replace(createCallFrame, "_Callee", method.Name); block.Statements.Add(createCallFrame); // process input parameters for (int i = 0, n = call.Operands.Count; i < n; i++) { Parameter param = method.Parameters[i]; if ((param.Flags & ParameterFlags.Out) == 0 && call.Operands[i] != null && method.Parameters[i] != null) { Statement assignInParam = Templates.GetStatementTemplate("SetInputParameter"); Replacer.Replace(assignInParam, "_src", this.VisitExpression(call.Operands[i])); Replacer.Replace(assignInParam, "_paramName", new Identifier("priv_" + method.Parameters[i].Name.Name)); block.Statements.Add(assignInParam); } } if (!method.IsStatic) { Statement setThis = Templates.GetStatementTemplate("SetThis"); Replacer.Replace(setThis, "_thisExpr", this.VisitExpression(((MemberBinding)call.Callee).TargetObject)); block.Statements.Add(setThis); } if (callIsAsync) { ExpressionStatement asyncInvoke = (ExpressionStatement)Templates.GetStatementTemplate("InvokeAsyncMethod"); Replacer.Replace(asyncInvoke, "_methodName", new Literal(method.DeclaringType.Name.Name + "." + method.Name.Name, SystemTypes.String)); Replacer.Replace(asyncInvoke, "_context", splicer.SourceContextConstructor(call.SourceContext)); Replacer.Replace(asyncInvoke, "_contextAttr", splicer.ContextAttributeConstructor(attributes)); block.Statements.Add(asyncInvoke); } else { block.Statements.Add(Templates.GetStatementTemplate("InvokeMethod")); block.Statements.Add(Templates.GetStatementTemplate("SetIsCall")); } }
void AddReadAllGroup(Class serializer, Block block, TypeNode type, StatementList statements, Identifier reader, Expression target, Expression required, Expression result, ArrayList members, Member mixedMember) { // todo: keep track of which members have been read and report error on duplicates MethodCall read = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList()); Local sb = new Local(SystemTypes.StringBuilder); bool isMixed = mixedMember != null; if (isMixed) { statements.Add(new AssignmentStatement(sb, new Construct(new MemberBinding(null, SystemTypes.StringBuilder), new ExpressionList(), SystemTypes.StringBuilder))); } Block whileBody = new Block(new StatementList()); BinaryExpression notEndTag = new BinaryExpression( new QualifiedIdentifier(reader, Identifier.For("NodeType")) , new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Ne); BinaryExpression notEOF = new BinaryExpression( new QualifiedIdentifier(reader, Identifier.For("EOF")), Literal.True, NodeType.Ne); While w = new While(new BinaryExpression(notEndTag, notEOF, NodeType.And), whileBody); statements.Add(w); Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String,block); Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String,block); Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType,block); whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); whileBody.Statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType")))); Block childBlock = whileBody; if (isMixed) { // Append the text node to the current StringBuilder contents. childBlock = new Block(new StatementList()); If ifText = new If(IsTextNode(nodeType), new Block(new StatementList()), childBlock); whileBody.Statements.Add(ifText); ExpressionList args = new ExpressionList(); args.Add(new QualifiedIdentifier(reader, Identifier.For("Value"))); ifText.TrueBlock.Statements.Add(new ExpressionStatement(new MethodCall( new QualifiedIdentifier(sb, Identifier.For("Append")), args))); ifText.TrueBlock.Statements.Add(new ExpressionStatement(read)); // advance to next node } If ifElement = new If(new BinaryExpression(nodeType, new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); childBlock.Statements.Add(ifElement); childBlock = ifElement.TrueBlock; //AddConsoleWrite(statements, new Literal("name=",SystemTypes.String)); //AddConsoleWriteLine(statements, nameLocal); //AddConsoleWrite(statements, new Literal("nodeType=",SystemTypes.String)); //AddConsoleWriteLine(statements, nodeType); foreach (NamedNode childNode in members) { if (!(childNode.Member is Field || childNode.Member is Property)) { AddError(statements, reader, RuntimeError.SerializationOfTypeNotSupported, new Literal(childNode.Member.GetType().FullName, SystemTypes.String)); } else { Expression mb = GetMemberBinding(target, childNode.Member); childBlock = AddReadChild(block, childBlock.Statements, childNode.Name, childNode.TypeNode, mb, reader, result, true, false).FalseBlock; // todo: throw error if child is required. (e.g. NonEmptyIEnumerable...) } } // if it isn't any of the expected elements then throw an error. AddError(childBlock.Statements, reader, RuntimeError.NoSuchMember, new Expression[2]{new Literal(tempChecker.GetTypeName(type),SystemTypes.String), nameLocal}); // If it's not an element then consume it anyway to keep the reader advancing. // Probably a comment or PI or something. ifElement.FalseBlock.Statements.Add(new ExpressionStatement(new MethodCall( new QualifiedIdentifier(reader, Identifier.For("Skip")), new ExpressionList()))); if (isMixed) { statements.Add(new AssignmentStatement(GetMemberBinding(target, mixedMember), new MethodCall(new QualifiedIdentifier(sb, Identifier.For("ToString")), new ExpressionList()))); } statements.Add(new AssignmentStatement(result, Literal.True)); }
void AddReadTuple(Block block, TupleType tuple, StatementList statements, Identifier reader, Expression target, Expression required, Expression result){ Local lt = new Local(Identifier.Empty, tuple, block); StatementList currentBlock = statements; for(int i = 0, n = tuple.Members.Length; i < n; i++) { Member mem = tuple.Members[i]; if (mem is Field) { Field f = (Field)mem; TypeNode mt = f.Type; if (mt == null) continue; // type resolution error. Expression mb = GetMemberBinding(target, f, mt); if (mt.Template == SystemTypes.GenericBoxed){ AddReadOptional(block, statements, f, mb, reader, result); } else if (mem.IsAnonymous) { if (mt is TupleType || mt is TypeUnion || IsStream(mt)) { AddCallDeserializer(mt, statements, reader, mb, required, result); } else { Identifier name = Checker.GetDefaultElementName(mt); AddReadRequiredChild(block, statements, name, mt, mb, reader, result, Literal.True, true, true); } } else { // could reduce a bit of code if we could assign currentName and pass the local to AddReadChild... AddReadRequiredChild(block, statements, mem.Name, mt, mb, reader, result, required, false, true); } } } }
private static void AddInterfaceImplementationWrapper(Class Class, Method intfMethod, Method baseMethod) { var d = new Duplicator(Class.DeclaringModule, Class); d.SkipBodies = true; var copy = d.VisitMethod(baseMethod); copy.Flags = MethodFlags.Private | MethodFlags.HideBySig | MethodFlags.Virtual | MethodFlags.NewSlot | MethodFlags.Final; copy.ImplementedInterfaceMethods = new MethodList(intfMethod); copy.Name = Identifier.For("InheritedInterfaceImplementationContractWrapper$" + intfMethod.Name.Name); copy.ClearBody(); copy.ThisParameter.Type = Class; var bodyBlock = new Block(new StatementList()); copy.Body = new Block(new StatementList(bodyBlock)); // add call to baseMethod var calledMethod = (baseMethod.TemplateParameters != null && baseMethod.TemplateParameters.Count > 0) ? baseMethod.GetTemplateInstance(Class, copy.TemplateParameters) : baseMethod; var argList = new ExpressionList(); for (int i = 0; i < copy.Parameters.Count; i++) { argList.Add(copy.Parameters[i]); } var callExpression = new MethodCall(new MemberBinding(copy.ThisParameter, calledMethod), argList); if (HelperMethods.IsVoidType(intfMethod.ReturnType)) { bodyBlock.Statements.Add(new ExpressionStatement(callExpression)); } else { bodyBlock.Statements.Add(new Return(callExpression)); } Class.Members.Add(copy); }
void AddReadOptional(Block block, StatementList statements, Member mem, Expression target, Identifier reader, Expression result) { TypeNode boxed = Checker.GetMemberType(mem); TypeNode type = Checker.GetCollectionElementType(boxed); statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList()))); Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String, block); Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String, block); statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); StringBuilder expecting = new StringBuilder(); Expression isFound = null; if (mem.IsAnonymous) { isFound = IsStartOf(block, type, statements, nameLocal, nsLocal, expecting); } else { ExpressionList args = new ExpressionList(); args.Add(new Literal(mem.Name.Name, SystemTypes.String)); isFound = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("IsStartElement")), args); } StatementList trueStatements = new StatementList(); If ifIsFound = new If(isFound, new Block(trueStatements), null); statements.Add(ifIsFound); if (!AddReadSimpleType(type, trueStatements, reader, target, result, false)) { Local localRequired = new Local(Identifier.Empty,SystemTypes.Boolean,block); statements.Add(new AssignmentStatement(localRequired, Literal.True)); AddCallDeserializer(type, trueStatements, reader, target, localRequired, result); } }