// 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 Expression ExplicitLiteralCoercion(Literal lit, TypeNode sourceType, TypeNode targetType, TypeViewer typeViewer) { if (sourceType == targetType && (sourceType == SystemTypes.Double || sourceType == SystemTypes.Single)) return lit; TypeNode originalTargetType = targetType; EnumNode sourceEnum = sourceType as EnumNode; if (sourceEnum != null) sourceType = sourceEnum.UnderlyingType; bool needsRuntimeCoercion = this.suppressOverflowCheck; if (!sourceType.IsPrimitiveInteger || sourceType == SystemTypes.IntPtr || sourceType == SystemTypes.UIntPtr) needsRuntimeCoercion = true; else if (!targetType.IsPrimitiveInteger || targetType == SystemTypes.IntPtr || targetType == SystemTypes.UIntPtr) needsRuntimeCoercion = true; if (needsRuntimeCoercion){ if (lit != null && lit.Value != null) targetType = TypeNode.StripModifier(targetType, SystemTypes.NonNullType); return this.ExplicitCoercion(lit, targetType, typeViewer); }else return this.LiteralCoercion(lit, sourceType, targetType, true, originalTargetType, null, false); }
public override bool ImplicitLiteralCoercionFromTo(Literal lit, TypeNode sourceType, TypeNode targetType){ if (lit == null) return false; if (sourceType == targetType) return true; object val = lit.Value; if (targetType is EnumNode){ if (val is int && ((int)val) == 0) return true; return false; } if (targetType.TypeCode == TypeCode.Boolean) return false; if (val == null && lit.Type == SystemTypes.Object){ //null literal if (targetType != null && !this.IsCompatibleWithNull(targetType)) return false; return true; } if (targetType.TypeCode == TypeCode.String) return false; if (targetType.TypeCode == TypeCode.Object) return false; if (targetType.TypeCode == TypeCode.Char || sourceType.TypeCode == TypeCode.Boolean || sourceType.TypeCode == TypeCode.Decimal) return false; switch (sourceType.TypeCode){ case TypeCode.Char: case TypeCode.Double: return false; case TypeCode.Single: switch (targetType.TypeCode){ case TypeCode.Double: return true; default: return false; } case TypeCode.Int64: switch (targetType.TypeCode) { case TypeCode.Int64: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Decimal: case TypeCode.Single: case TypeCode.Double: break; default: return false; } break; case TypeCode.UInt64: switch (targetType.TypeCode){ case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Decimal: case TypeCode.Single: case TypeCode.Double: break; default: return false; } break; } try{ if (val == null){ if (targetType.IsValueType) return false; }else val = System.Convert.ChangeType(val, targetType.TypeCode); return true; }catch(InvalidCastException){ }catch(OverflowException){ }catch(FormatException){} return false; }
public override Expression VisitLiteral(Literal literal) { if (literal == null) return null; TypeNode t = literal.Value as TypeNode; if (t != null) return new Literal(this.VisitTypeReference(t), literal.Type, literal.SourceContext); ArrayType at = literal.Type as ArrayType; if (at != null && at.ElementType is TypeNode) { TypeNode cloneType = this.VisitTypeReference(literal.Type); TypeNode[] val = literal.Value as TypeNode[]; int len = val == null ? 0 : val.Length; TypeNode[] newVal = val == null ? null : new TypeNode[len]; for (int i = 0; i < len; i++) { newVal[i] = this.VisitTypeReference(val[i]); } return new Literal(newVal, cloneType); } return (Literal)literal.Clone(); }
private Literal ParseRealLiteral(){ Debug.Assert(this.currentToken == Token.RealLiteral); string tokStr = this.scanner.GetTokenSource(); SourceContext ctx = this.scanner.CurrentSourceContext; TypeCode tc = this.scanner.ScanNumberSuffix(); ctx.EndPos = this.scanner.endPos; Literal result; string typeName = null; try{ switch(tc){ case TypeCode.Single: typeName = "float"; float fVal = Single.Parse(tokStr, NumberStyles.Any, CultureInfo.InvariantCulture); if (fVal == 0f && tokStr.IndexOfAny(nonZeroDigits) >= 0) this.HandleError(ctx, Error.FloatOverflow, typeName); result = new Literal(fVal); break; case TypeCode.Empty: case TypeCode.Double: typeName = "double"; double dVal = Double.Parse(tokStr, NumberStyles.Any, CultureInfo.InvariantCulture); if (dVal == 0d && tokStr.IndexOfAny(nonZeroDigits) >= 0) this.HandleError(ctx, Error.FloatOverflow, typeName); result = new Literal(dVal); break; case TypeCode.Decimal: typeName = "decimal"; decimal decVal = Decimal.Parse(tokStr, NumberStyles.Any, CultureInfo.InvariantCulture); result = new Literal(decVal); break; default: //TODO: give an error message goto case TypeCode.Empty; } }catch(OverflowException){ this.HandleError(ctx, Error.FloatOverflow, typeName); result = new Literal(0); } result.SourceContext = ctx; result.TypeWasExplicitlySpecifiedInSource = tc != TypeCode.Empty; this.GetNextToken(); return result; }
private Literal ParseIntegerLiteral(){ Debug.Assert(this.currentToken == Token.IntegerLiteral); string tokStr = this.scanner.GetTokenSource(); SourceContext ctx = this.scanner.CurrentSourceContext; TypeCode tc = this.scanner.ScanNumberSuffix(); ctx.EndPos = this.scanner.endPos; Literal result; try{ switch(tc){ case TypeCode.Single: result = new Literal(Single.Parse(tokStr, null)); break; case TypeCode.Double: result = new Literal(Double.Parse(tokStr, null)); break; case TypeCode.Decimal: result = new Literal(Decimal.Parse(tokStr, null)); break; default: ulong ul = UInt64.Parse(tokStr, null); if (ul <= int.MaxValue && tc == TypeCode.Empty) result = new Literal((int)ul); else if (ul <= uint.MaxValue && (tc == TypeCode.Empty || tc == TypeCode.UInt32)) result = new Literal((uint)ul); else if (ul <= long.MaxValue && (tc == TypeCode.Empty || tc == TypeCode.Int64)) result = new Literal((long)ul); else result = new Literal(ul); break; } }catch(OverflowException){ this.HandleError(ctx, Error.IntOverflow); result = new Literal(0); }catch(ExecutionEngineException){ this.HandleError(ctx, Error.IntOverflow); result = new Literal(0); } result.SourceContext = ctx; result.TypeWasExplicitlySpecifiedInSource = tc != TypeCode.Empty; this.GetNextToken(); return result; }
private void WriteLiteral(Literal literal, bool showType) { TypeNode type = literal.Type; Object value = literal.Value; if (showType) WriteTypeReference(type); if (value == null) { writer.WriteElementString("nullValue", String.Empty); } else { if (type.NodeType == NodeType.EnumNode) { EnumNode enumeration = (EnumNode)type; FieldList fields = GetAppliedFields(enumeration, Convert.ToInt64(value)); writer.WriteStartElement("enumValue"); for (int i = 0; i < fields.Count; i++) { writer.WriteStartElement("field"); writer.WriteAttributeString("name", fields[i].Name.Name); writer.WriteEndElement(); } writer.WriteEndElement(); } else if (type.FullName == "System.Type") { writer.WriteStartElement("typeValue"); WriteTypeReference((TypeNode)value); writer.WriteEndElement(); } else { string text = value.ToString(); if (!IsValidXmlText(text)) text = String.Empty; writer.WriteElementString("value", text); } } }
protected override object VisitLoadConstant(Variable dest, Literal source, Statement stat, object arg) { ExposureState estate=(ExposureState)arg; if (source == Literal.False){ estate.SetToFalse(dest); } return arg; }
private Literal LiteralCoercion(Literal/*!*/ lit, TypeNode sourceType, TypeNode targetType, bool explicitCoercion, TypeNode originalTargetType, TypeViewer typeViewer, bool forLabel) { if (sourceType == targetType){ if (sourceType == lit.Type) return lit; return new Literal(Convert.ChangeType(lit.Value, sourceType.TypeCode), sourceType, lit.SourceContext); } object val = lit.Value; EnumNode eN = targetType as EnumNode; if (eN != null){ if (sourceType.IsPrimitiveInteger && val is IConvertible && ((IConvertible)val).ToDouble(null) == 0.0){ if (eN.UnderlyingType == SystemTypes.Int64 || eN.UnderlyingType == SystemTypes.UInt64) val = 0L; else val = 0; return new Literal(val, eN, lit.SourceContext); } goto error; } if (targetType.TypeCode == TypeCode.Boolean){ this.HandleError(lit, Error.ConstOutOfRange, lit.SourceContext.SourceText, "bool"); lit.SourceContext.Document = null; return null; } if (targetType.TypeCode == TypeCode.String){ if (val != null || lit.Type != SystemTypes.Object){ this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType)); lit.SourceContext.Document = null; return null; } return lit; } if (targetType.TypeCode == TypeCode.Object){ if (val == null && sourceType == SystemTypes.Object && (explicitCoercion || !this.IsNonNullType(targetType))) return lit; if (val is string && this.IsNonNullType(targetType) && TypeNode.StripModifiers(targetType) == SystemTypes.String) return lit; Method coercion = null; if (explicitCoercion) coercion = this.UserDefinedExplicitCoercionMethod(lit, sourceType, targetType, true, originalTargetType, typeViewer); else coercion = this.UserDefinedImplicitCoercionMethod(lit, sourceType, targetType, true, typeViewer); if (coercion != null) return null; this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType)); lit.SourceContext.Document = null; return null; } if ((targetType.TypeCode == TypeCode.Char || sourceType.TypeCode == TypeCode.Boolean || sourceType.TypeCode == TypeCode.Decimal) && !forLabel) goto error; switch (sourceType.TypeCode){ case TypeCode.Double: switch (targetType.TypeCode){ case TypeCode.Single: this.HandleError(lit, Error.LiteralDoubleCast, "float", "F"); return lit; case TypeCode.Decimal: this.HandleError(lit, Error.LiteralDoubleCast, "decimal", "M"); return lit; default: this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType)); lit.SourceContext.Document = null; return null; } case TypeCode.Single: switch (targetType.TypeCode){ case TypeCode.Double: break; default: this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType)); lit.SourceContext.Document = null; return null; } break; case TypeCode.Int64: case TypeCode.UInt64: switch (targetType.TypeCode){ case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Decimal: case TypeCode.Single: case TypeCode.Double: break; default: if (explicitCoercion || !lit.TypeWasExplicitlySpecifiedInSource) break; this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType)); lit.SourceContext.Document = null; return null; } break; } try{ if (val == null){ if (targetType.IsValueType) goto error; }else val = System.Convert.ChangeType(val, targetType.TypeCode); return new Literal(val, targetType, lit.SourceContext); }catch(InvalidCastException){ }catch(OverflowException){ }catch(FormatException){} error: if (sourceType.IsPrimitiveNumeric && lit.SourceContext.Document != null){ Error e = Error.ConstOutOfRange; if (explicitCoercion) e = Error.ConstOutOfRangeChecked; this.HandleError(lit, e, lit.SourceContext.SourceText, this.GetTypeName(targetType)); }else this.HandleError(lit, Error.NoImplicitConversion, this.GetTypeName(sourceType), this.GetTypeName(targetType)); if (this.ErrorHandler != null) lit.SourceContext.Document = null; return null; }
private Parameter ParseParameter(TokenSet followers, bool allowRefParameters, bool namesAreOptional, bool typesAreOptional){ Parameter p = new Parameter(); p.SourceContext = this.scanner.CurrentSourceContext; Token tok = this.currentToken; p.Attributes = this.ParseAttributes(null, followers|Parser.ParameterTypeStart); p.Flags = ParameterFlags.None; bool byRef = false; switch(this.currentToken){ case Token.Out: //TODO: error if !allowRefParameters && typesAreOptional p.Flags = ParameterFlags.Out; goto case Token.Ref; case Token.Ref: //TODO: error if !allowRefParameters && typesAreOptional if (!allowRefParameters) this.HandleError(Error.IndexerWithRefParam); byRef = true; this.GetNextToken(); if (this.currentToken == Token.Params){ this.HandleError(Error.ParamsCantBeRefOut); this.GetNextToken(); } break; case Token.Params: //TODO: error if !allowRefParameters && typesAreOptional Literal lit = new Literal(TypeExpressionFor("System", "ParamArrayAttribute"), null, this.scanner.CurrentSourceContext); AttributeNode paramsAttribute = new AttributeNode(lit, null); if (p.Attributes == null) p.Attributes = new AttributeList(1); p.Attributes.Add(paramsAttribute); this.GetNextToken(); if (this.currentToken == Token.Out || this.currentToken == Token.Ref){ this.HandleError(Error.ParamsCantBeRefOut); if (this.currentToken == Token.Out) goto case Token.Out; goto case Token.Ref; } break; } bool voidParam = false; if (this.currentToken == Token.Void){ if (this.inUnsafeCode){ TypeNode voidT = this.TypeExpressionFor(Token.Void); SourceContext sctx = this.scanner.CurrentSourceContext; this.GetNextToken(); sctx.EndPos = this.scanner.endPos; this.Skip(Token.Multiply); p.Type = p.TypeExpression = new PointerTypeExpression(voidT, sctx); }else{ this.HandleError(Error.NoVoidParameter); p.Type = this.TypeExpressionFor(Token.Object); p.TypeExpression = new TypeExpression(this.scanner.GetIdentifier(), this.scanner.CurrentSourceContext); this.GetNextToken(); voidParam = true; } }else if (this.currentToken == Token.Delegate) p.Type = p.TypeExpression = this.ParseDelegateDeclaration(null, null, null, TypeFlags.None, p.SourceContext, followers); else if (p.Type == null){ p.Type = p.TypeExpression = this.ParseTypeExpression(null, followers|Parser.IdentifierOrNonReservedKeyword); } if (byRef) p.Type = p.TypeExpression = new ReferenceTypeExpression(p.Type); if ((this.currentToken == Token.Comma || this.currentToken == Token.RightParenthesis) && p.TypeExpression is TypeExpression && ((TypeExpression)p.TypeExpression).Expression is Identifier && typesAreOptional) { p.Name = (Identifier)((TypeExpression)p.TypeExpression).Expression; p.Type = p.TypeExpression = null; }else{ p.Name = this.scanner.GetIdentifier(); } p.SourceContext.EndPos = this.scanner.endPos; if (!voidParam || Parser.IdentifierOrNonReservedKeyword[this.currentToken]){ if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) this.GetNextToken(); else{ if (namesAreOptional) p.Name = Identifier.Empty; else this.SkipIdentifierOrNonReservedKeyword(); } } if (this.currentToken == Token.LeftBracket){ this.HandleError(Error.BadArraySyntax); int endPos = this.scanner.endPos; int rank = this.ParseRankSpecifier(true, followers|Token.LeftBracket); if (rank > 0) p.Type = p.TypeExpression = this.ParseArrayType(rank, p.Type, followers); else{ this.currentToken = Token.LeftBracket; this.scanner.endPos = endPos; this.GetNextToken(); while (!this.scanner.TokenIsFirstAfterLineBreak && this.currentToken != Token.RightBracket && this.currentToken != Token.Comma && this.currentToken != Token.RightParenthesis) this.GetNextToken(); if (this.currentToken == Token.RightBracket) this.GetNextToken(); } }else if (this.currentToken == Token.Assign){ this.HandleError(Error.NoDefaultArgs); this.GetNextToken(); if (Parser.UnaryStart[this.currentToken]){ this.ParseExpression(followers); return p; } } this.SkipTo(followers); return p; }
/// <summary> /// Returns the invariant condition or null if statement is not invariant method call /// </summary> /// <param name="name">Optional string of invariant</param> public Expression IsInvariant(Statement s, out Literal name, out Literal sourceText) { name = null; sourceText = null; if (s == null) return null; ExpressionStatement es = s as ExpressionStatement; if (es == null) return null; MethodCall mc = es.Expression as MethodCall; if (mc == null) return null; MemberBinding mb = mc.Callee as MemberBinding; if (mb == null) return null; Method m = mb.BoundMember as Method; if (m == null) return null; if (this.IsInvariantMethod(m)) { if (mc.Operands.Count > 1) { name = mc.Operands[1] as Literal; } if (mc.Operands.Count > 2) { sourceText = mc.Operands[2] as Literal; } return mc.Operands[0]; } return null; }
//HS D private BlockHole ParseBlockHole(TokenSet followers){ Debug.Assert(this.currentToken == Token.Hole); Hashtable templateParams = new Hashtable(); this.GetNextToken(); this.Skip(Token.LeftBrace); if (this.currentToken != Token.RightBrace){ string templateParam = this.scanner.GetTokenSource(); this.GetNextToken(); this.Skip(Token.Colon); Expression templateParamVal = this.currentToken == Token.IntegerLiteral ? this.ParseIntegerLiteral() : (this.currentToken == Token.RealLiteral ? this.ParseRealLiteral() : this.ParseCommaSeparetedIdentifierSet()); templateParams[templateParam] = templateParamVal; while (this.currentToken == Token.Comma){ this.GetNextToken(); templateParam = this.scanner.GetTokenSource(); this.GetNextToken(); this.Skip(Token.Colon); templateParamVal = this.currentToken == Token.IntegerLiteral ? this.ParseIntegerLiteral() : (this.currentToken == Token.RealLiteral ? this.ParseRealLiteral() : this.ParseCommaSeparetedIdentifierSet()); templateParams[templateParam] = templateParamVal; } } this.Skip(Token.RightBrace); Literal one = new Literal(1); ConstructArray empty = new ConstructArray(); Literal repeat = templateParams.ContainsKey("repeat") ? (Literal) templateParams["repeat"] : one; Literal ifbranches = templateParams.ContainsKey("ifbranches") ? (Literal) templateParams["ifbranches"] : one; Literal branchops = templateParams.ContainsKey("branchops") ? (Literal) templateParams["branchops"] : one; Literal conjunctions = templateParams.ContainsKey("conjunctions") ? (Literal) templateParams["conjunctions"] : one; ConstructArray ops = templateParams.ContainsKey("ops") ? (ConstructArray) templateParams["ops"] : empty; ConstructArray condvars = templateParams.ContainsKey("condvars") ? (ConstructArray) templateParams["condvars"] : empty; ConstructArray argvars = templateParams.ContainsKey("argvars") ? (ConstructArray) templateParams["argvars"] : empty; SourceContext sctx = this.scanner.CurrentSourceContext; BlockHole result = new BlockHole(sctx, repeat, ifbranches, branchops, conjunctions, ops, condvars, argvars); //, this.currMethod, opMethods); result.SourceContext = sctx; //HS D: HACK FIXME DefineBlockHoleMethod(this.currentTypeNode); return result; }
public ValidationState CheckExpression(Expression litExpr, TypeNode ceType, System.Compiler.TypeSystem typeSystem, Hashtable schemaElementDeclCache) { TypeNode litType = litExpr.Type; Error e = Error.None; if (typeSystem.ImplicitCoercionFromTo(litExpr, litType, schemaType)) { context.HasMatched = true; return context; } if (validator != null ){ if (litType.IsPrimitive || litType is ArrayType || validator is AllElementsContentValidator) { Member schElemMember = null; TypeNode schElemType = null; TerminalNode node = null; // See if any of the expected elements can be coerced // into the given type and pick the first match. // Throw an error if there's multiple fields that match. ArrayList list = (validator != null) ? validator.ExpectedElements(context, false, false) : null; TerminalNode bestNode = null; if (list != null) { foreach (TerminalNode n in list) { Member mem = n.Member; TypeNode memType = n.TypeNode; if (memType is TypeUnion) { memType = ((Method)mem).ReturnType; } if (memType != null) { // Special case for string to char conversion. if (memType == SystemTypes.Char && litExpr is Literal) { Literal lit = (Literal)litExpr; if (lit.Type == SystemTypes.String) { string value = (string)lit.Value; if (value.Length == 1) { litExpr = new Literal(value[0], SystemTypes.Char, litExpr.SourceContext); litType = SystemTypes.Char; } } } if ((mem is Method && // we are assigning to a collection typeSystem.ImplicitCoercionFromTo(litExpr, ceType, memType)) || typeSystem.ImplicitCoercionFromTo(litExpr, litType, memType)) { if (bestNode != null) { if (typeSystem.IsBetterMatch(memType, bestNode.TypeNode, ceType) || typeSystem.IsBetterMatch(memType, bestNode.TypeNode, litType)) { bestNode = n; e = Error.None; // cancel any prior errors. } else { e = Error.AmbiguousLiteralExpression; } } else { bestNode = n; } } } } } if (e == Error.None && bestNode != null) { node = bestNode; schElemMember = node.Member; schElemType = node.TypeNode; } if (node != null) { // This will assign the CurrentNode Identifier name = (node is NamedNode) ? ((NamedNode)node).Name : ((schElemMember != null && !(schElemMember is Method)) ? schElemMember.Name : schElemType.Name); validator.ValidateElement(name, context); } else if (e == Error.None) { if (list == null) { e = Error.InvalidElementContentNone; } else { e = Error.InvalidContentExpecting; } } } else { SchemaElementDecl sd = SchemaElementDecl.Compile(this.targetModule, litType, ceType, this.context.ErrorHandler, schemaElementDeclCache); SchemaValidator v = sd.CreateValidator(this.context.ErrorHandler); if (this.validator.ValidateExpression(this.context, v.validator) < 0) { e = Error.InvalidContentExpecting; } } } if (e != Error.None) { string currentElement = null; if (context.Name != null) { currentElement = context.Name.ToString(); } else { TypeNode current = (this.context.CurrentNode == null) ? this.validator.RootType : this.context.CurrentNode.TypeNode; if (current == null) current = this.schemaType; currentElement = ErrorHandler.GetTypeNameFor(current); } ArrayList list = validator.ExpectedElements(this.context, false, false); string arg = (list != null) ? validator.GetExpectedElements(list) : null; context.HandleError(this.RootNode, litExpr, e, currentElement, ErrorHandler.GetTypeNameFor(litType), arg); } return context; }
public override bool Matches(ContentNode other) { // This recurrsive search figures out whether something like (A|(B|C)) matches (B|(A|C)) // by visiting all the members of the right hand side, then searching to see if the // left hand side "contains" that choice. So it will also return true if "this" has // more choices than "other", which is what we want. So (A|B) matches (A|B|C). if (other is TerminalNode) { return Contains(this.LeftChild, other as TerminalNode) || Contains(this.RightChild, other as TerminalNode); } else if (other is NopNode) { return this.Matches(((NopNode)other).Child); } if (other is ChoiceNode) { ChoiceNode choice = other as ChoiceNode; Literal e = new Literal("", choice.TypeNode); ErrorHandler eh = new ErrorHandler(new ErrorNodeList()); TypeSystem ts = new TypeSystem(eh); return (ts.ExplicitCoercion(e, this.TypeNode) != null); //return this.Matches(choice.LeftChild) && this.Matches(choice.RightChild); } return false; }
public Continue(Literal level) : base(NodeType.Continue) { this.Level = level; }
public override Literal ImplicitLiteralCoercion(Literal lit, TypeNode sourceType, TypeNode targetType, TypeViewer typeViewer) { return this.LiteralCoercion(lit, sourceType, targetType, false, targetType, typeViewer, false); }
private Expression ParseConditional(Expression condition, TokenSet followers){ Debug.Assert(this.currentToken == Token.Conditional); this.GetNextToken(); Expression trueExpr = this.ParseExpression(followers|Token.Colon); if (trueExpr == null) //Supply a dummy trueExpr = new Literal(null, null, this.scanner.CurrentSourceContext); Expression falseExpr; if (this.currentToken == Token.Colon){ this.GetNextToken(); falseExpr = this.ParseExpression(followers); }else{ this.Skip(Token.Colon); //gives appropriate error message if (!followers[this.currentToken]) //Assume that only the : is missing. Go ahead as if it were specified. falseExpr = this.ParseExpression(followers); else falseExpr = null; } if (falseExpr == null) //Supply a dummy falseExpr = new Literal(null, null, this.scanner.CurrentSourceContext); TernaryExpression result = new TernaryExpression(condition, trueExpr, falseExpr, NodeType.Conditional, null); result.SourceContext = condition.SourceContext; result.SourceContext.EndPos = falseExpr.SourceContext.EndPos; this.SkipTo(followers); return result; }
protected override object VisitLoadNull(Variable dest, Literal source, Statement stat, object arg) { ExposureState estate=(ExposureState)arg; return arg; }
private Expression ParsePrimaryExpression(TokenSet followers){ Expression expression = null; SourceContext sctx = this.scanner.CurrentSourceContext; switch(this.currentToken){ case Token.ArgList: this.GetNextToken(); expression = new ArglistExpression(sctx); break; case Token.Delegate:{ this.GetNextToken(); ParameterList parameters = null; if (this.currentToken == Token.LeftParenthesis) parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace); Block block = null; if (this.currentToken == Token.LeftBrace) block = this.ParseBlock(this.scanner.CurrentSourceContext, followers); else this.SkipTo(followers, Error.ExpectedLeftBrace); sctx.EndPos = this.scanner.endPos; return new AnonymousNestedDelegate(parameters, block, sctx);} case Token.New: expression = this.ParseNew(followers|Token.Dot|Token.LeftBracket|Token.Arrow); break; case Token.Identifier: expression = this.scanner.GetIdentifier(); if (this.sink != null) { this.sink.StartName((Identifier)expression); } this.GetNextToken(); if (this.currentToken == Token.DoubleColon){ this.GetNextToken(); Identifier id = this.scanner.GetIdentifier(); id.Prefix = (Identifier)expression; id.SourceContext.StartPos = expression.SourceContext.StartPos; expression = id; if (this.currentToken != Token.EndOfFile) this.GetNextToken(); }else if (this.currentToken == Token.Lambda){ Parameter par = new Parameter((Identifier)expression, null); par.SourceContext = expression.SourceContext; return this.ParseLambdaExpression(par.SourceContext, new ParameterList(par), followers); } break; case Token.Null: expression = new Literal(null, null, sctx); this.GetNextToken(); break; case Token.True: expression = new Literal(true, null, sctx); this.GetNextToken(); break; case Token.False: expression = new Literal(false, null, sctx); this.GetNextToken(); break; case Token.CharLiteral: expression = new Literal(this.scanner.charLiteralValue, null, sctx); this.GetNextToken(); break; case Token.HexLiteral: expression = this.ParseHexLiteral(); break; case Token.IntegerLiteral: expression = this.ParseIntegerLiteral(); break; case Token.RealLiteral: expression = this.ParseRealLiteral(); break; case Token.StringLiteral: expression = this.scanner.GetStringLiteral(); this.GetNextToken(); break; case Token.This: expression = new This(sctx, false); if (this.sink != null) { this.sink.StartName(expression); } this.GetNextToken(); if (this.currentToken == Token.LeftParenthesis && (this.inInstanceConstructor==BaseOrThisCallKind.None || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyThisSeen)){ QualifiedIdentifier thisCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall thisConstructorCall = new MethodCall(thisCons, null, NodeType.Call); thisConstructorCall.SourceContext = sctx; SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); thisConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out thisConstructorCall.SourceContext.EndPos); expression = thisConstructorCall; this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyThisSeen; goto done; } break; case Token.Base: Base ba = new Base(sctx, false); expression = ba; if (this.sink != null) { this.sink.StartName(expression); } this.GetNextToken(); if (this.currentToken == Token.Semicolon && (this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen || this.inInstanceConstructor == BaseOrThisCallKind.None)) { // When there are non-null fields, then the base ctor call can happen only after they are // initialized. // In Spec#, we allow a base ctor call in the body of the ctor. But if someone is using // the C# comment convention, then they cannot do that. // So allow "base;" as a marker to indicate where the base ctor call should happen. // There may be an explicit "colon base call" or it may be implicit. // // Just leave expression as a bare "Base" node; later pipeline stages will all have // to ignore it. Mark the current ctor as having (at least) one of these bad boys // in it. ba.UsedAsMarker = true; this.currentCtor.ContainsBaseMarkerBecauseOfNonNullFields = true; goto done; } if (this.currentToken == Token.LeftParenthesis && (this.inInstanceConstructor==BaseOrThisCallKind.None || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyBaseSeen)){ QualifiedIdentifier supCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call); superConstructorCall.SourceContext = sctx; SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out superConstructorCall.SourceContext.EndPos); expression = superConstructorCall; this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyBaseSeen; goto done; } break; case Token.Typeof: case Token.Sizeof: case Token.Default:{ //if (this.currentToken == Token.Sizeof && !this.inUnsafeCode) //this.HandleError(Error.SizeofUnsafe); UnaryExpression uex = new UnaryExpression(null, this.currentToken == Token.Typeof ? NodeType.Typeof : this.currentToken == Token.Sizeof ? NodeType.Sizeof : NodeType.DefaultValue); uex.SourceContext = sctx; this.GetNextToken(); this.Skip(Token.LeftParenthesis); TypeNode t = null; if (this.currentToken == Token.Void && uex.NodeType == NodeType.Typeof){ t = this.TypeExpressionFor(Token.Void); this.GetNextToken(); }else t = this.ParseTypeExpression(null, followers|Token.RightParenthesis, false, false, uex.NodeType == NodeType.Typeof); if (t == null){this.SkipTo(followers); return null;} uex.Operand = new MemberBinding(null, t, t.SourceContext, null); uex.Operand.SourceContext = t.SourceContext; uex.SourceContext.EndPos = this.scanner.endPos; this.Skip(Token.RightParenthesis); expression = uex; break;} case Token.Stackalloc:{ this.GetNextToken(); TypeNode elementType = this.ParseBaseTypeExpression(null, followers|Token.LeftBracket, false, false); if (elementType == null){this.SkipTo(followers); return null;} Token openingDelimiter = this.currentToken; if (this.currentToken != Token.LeftBracket){ this.HandleError(Error.BadStackAllocExpr); if (this.currentToken == Token.LeftParenthesis) this.GetNextToken(); }else this.GetNextToken(); Expression numElements = this.ParseExpression(followers|Token.RightBracket|Token.RightParenthesis); sctx.EndPos = this.scanner.endPos; if (this.currentToken == Token.RightParenthesis && openingDelimiter == Token.LeftParenthesis) this.GetNextToken(); else this.Skip(Token.RightBracket); this.SkipTo(followers); return new StackAlloc(elementType, numElements, sctx);} case Token.Checked: case Token.Unchecked: //TODO: use NodeType.SkipCheck and NodeType.EnforceCheck Block b = new Block(new StatementList(1), this.currentToken == Token.Checked, this.currentToken == Token.Unchecked, this.inUnsafeCode); b.SourceContext = sctx; this.GetNextToken(); this.Skip(Token.LeftParenthesis); b.Statements.Add(new ExpressionStatement(this.ParseExpression(followers|Token.RightParenthesis))); this.Skip(Token.RightParenthesis); expression = new BlockExpression(b); expression.SourceContext = b.SourceContext; break; case Token.RefType:{ this.GetNextToken(); this.Skip(Token.LeftParenthesis); Expression e = this.ParseExpression(followers|Token.RightParenthesis); this.Skip(Token.RightParenthesis); expression = new RefTypeExpression(e, sctx); break; } case Token.RefValue:{ this.GetNextToken(); this.Skip(Token.LeftParenthesis); Expression e = this.ParseExpression(followers|Token.Comma); this.Skip(Token.Comma); TypeNode te = this.ParseTypeOrFunctionTypeExpression(followers|Token.RightParenthesis, false, true); Expression operand2 = new MemberBinding(null, te); if (te is TypeExpression) operand2.SourceContext = te.SourceContext; else operand2.SourceContext = sctx; this.Skip(Token.RightParenthesis); expression = new RefValueExpression(e, operand2, sctx); break; } case Token.Bool: case Token.Decimal: case Token.Sbyte: case Token.Byte: case Token.Short: case Token.Ushort: case Token.Int: case Token.Uint: case Token.Long: case Token.Ulong: case Token.Char: case Token.Float: case Token.Double: case Token.Object: case Token.String: MemberBinding mb = new MemberBinding(null, this.TypeExpressionFor(this.currentToken), sctx); this.GetNextToken(); expression = this.ParseIndexerCallOrSelector(mb, followers); goto done; case Token.LeftParenthesis: expression = this.ParseParenthesizedExpression(followers|Token.Dot|Token.LeftBracket|Token.Arrow, true); break; default: if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier; if (Parser.InfixOperators[this.currentToken]){ this.HandleError(Error.InvalidExprTerm, this.scanner.GetTokenSource()); this.GetNextToken(); }else this.SkipTo(followers|Parser.PrimaryStart, Error.InvalidExprTerm, this.scanner.GetTokenSource()); if (Parser.PrimaryStart[this.currentToken]) return this.ParsePrimaryExpression(followers); goto done; } if (expression is Base && this.currentToken != Token.Dot && this.currentToken != Token.LeftBracket){ this.HandleError(expression.SourceContext, Error.BaseIllegal); expression = null; } expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); for(;;){ switch(this.currentToken){ case Token.AddOne: case Token.SubtractOne: SourceContext ctx = expression.SourceContext; ctx.EndPos = this.scanner.endPos; PostfixExpression pex = new PostfixExpression(expression, Parser.ConvertToBinaryNodeType(this.currentToken), ctx); this.GetNextToken(); expression = pex; break; case Token.Dot: expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); break; default: goto done; } } done: this.SkipTo(followers); return expression; }
private void WriteLiteral(Literal literal) { WriteLiteral(literal, true); }
private Literal ParseHexLiteral(){ Debug.Assert(this.currentToken == Token.HexLiteral); string tokStr = this.scanner.GetTokenSource(); SourceContext ctx = this.scanner.CurrentSourceContext; TypeCode tc = this.scanner.ScanNumberSuffix(); Literal result; try{ switch(tc){ case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: this.HandleError(Error.ExpectedSemicolon); goto default; default: ulong ul = UInt64.Parse(tokStr.Substring(2), System.Globalization.NumberStyles.HexNumber, null); if (ul <= int.MaxValue && tc == TypeCode.Empty) result = new Literal((int)ul); else if (ul <= uint.MaxValue && (tc == TypeCode.Empty || tc == TypeCode.UInt32)) result = new Literal((uint)ul); else if (ul <= long.MaxValue && (tc == TypeCode.Empty || tc == TypeCode.Int64)) result = new Literal((long)ul); else result = new Literal(ul); break; } }catch(OverflowException){ this.HandleError(ctx, Error.IntOverflow); result = new Literal(0); } ctx.EndPos = this.scanner.endPos; result.SourceContext = ctx; result.TypeWasExplicitlySpecifiedInSource = tc != TypeCode.Empty; this.GetNextToken(); return result; }
public override Expression VisitLiteral(Literal literal) { // TODO: probably need special cases here for the various integer & real types. // Also need to investigate quoting behavior in string literals. if (literal.Value == null) Write("null"); else if (literal.Value is string) Write("@\"{0}\"", literal.Value.ToString().Replace("\"", "\"\"")); else if (literal.Value is bool) Write(((bool)literal.Value) ? "true" : "false"); else if (literal.Value is char) Write("'\\x{0:X4}'", ((ushort)(char)literal.Value)); else if (literal.Value is TypeNode) this.VisitTypeReference((TypeNode)literal.Value); else if (literal.Type == SystemTypes.UInt64) Write("{0}ul", literal.Value); else Write("{0}", literal.Value); return literal; }
public Exit(Literal level) : base(NodeType.Exit) { this.Level = level; }
void AddWriteElement(StatementList statements, TypeNode referringType, Identifier writer, Identifier name, Expression src, TypeNode mt, bool emptyElementOnNull) { if (mt.Template == SystemTypes.GenericBoxed) { statements = AddCheckForNull(statements, Duplicate(src, referringType), mt); mt = Checker.GetCollectionElementType(mt); // check for null and unbox src = CastTo(src, mt); //unbox it } Literal nameLit = new Literal(name.ToString(), SystemTypes.String); Literal nsLit = (name.Prefix != null) ? new Literal(name.Prefix.Name, SystemTypes.String) : Literal.Null; if (!emptyElementOnNull) { statements = AddCheckForNull(statements, Duplicate(src, referringType), mt); } if (!AddWriteSimpleType(mt, statements, referringType, writer, src, nameLit, nsLit)) { AddCallSerializer(mt, statements, src, writer, nameLit, nsLit); } }
void GetNameAndNamespace(TypeNode type, out Expression name, out Expression ns) { name = Literal.Null; ns = Literal.Null; if (!IsStructuralType(type)) { Identifier id = Checker.GetDefaultElementName(type); name = new Literal(id.Name, SystemTypes.String); if (id.Prefix != null) { ns = new Literal(id.Prefix.Name, SystemTypes.String); } } }
bool AddWriteSimpleType(TypeNode simpleType, StatementList statements, TypeNode referringType, Identifier writer, Expression src, Expression name, Expression ns) { Identifier method = null; TypeNode type = Unwrap(simpleType); ExpressionList args = new ExpressionList(src); if (type == SystemTypes.String) { method = Identifier.For("WriteString"); } else if( type == SystemTypes.Boolean) { method = Identifier.For("WriteBoolean"); } else if( type == SystemTypes.Int8) { method = Identifier.For("WriteSByte"); } else if( type == SystemTypes.Char) { method = Identifier.For("WriteChar"); } else if( type == SystemTypes.DateTime) { method = Identifier.For("WriteDateTime"); } else if( type == SystemTypes.Decimal) { method = Identifier.For("WriteDecimal"); } else if( type == SystemTypes.Double) { method = Identifier.For("WriteDouble"); } else if( type == SystemTypes.Guid) { method = Identifier.For("WriteGuid"); } else if( type == SystemTypes.Int16) { method = Identifier.For("WriteInt16"); } else if( type == SystemTypes.Int32) { method = Identifier.For("WriteInt32"); } else if( type == SystemTypes.Int64) { method = Identifier.For("WriteInt64"); } else if( type == SystemTypes.UInt8) { method = Identifier.For("WriteByte"); } else if( type == SystemTypes.Single) { method = Identifier.For("WriteSingle"); } else if( type == SystemTypes.TimeSpan) { method = Identifier.For("WriteTimeSpan"); } else if( type == SystemTypes.UInt16 ) { method = Identifier.For("WriteUInt16"); } else if( type == SystemTypes.UInt32) { method = Identifier.For("WriteUInt32"); } else if( type == SystemTypes.UInt64) { method = Identifier.For("WriteUInt64"); } else { Expression conversion = GetConvertToString(type, src, false); if (conversion != null) { statements = AddCheckForNull(statements, Duplicate(src, referringType), type); method = Identifier.For("WriteString"); args = new ExpressionList(conversion); } else { return false; } } if (name != null) { Identifier id = Checker.GetDefaultElementName(type); string defaultName = id.Name; string defaultNamespace = (id.Prefix != null) ? id.Prefix.Name : null; Expression localName = new Local(SystemTypes.String); Expression localNamespace = new Local(SystemTypes.String); Expression safeName = name; if (name is Literal) { if (name == Literal.Null) { localName = new Literal(defaultName, SystemTypes.String); localNamespace = new Literal(defaultNamespace, SystemTypes.String); } else { localName = name; localNamespace = ns; } } else { If nameNull = new If(new BinaryExpression(name, Literal.Null, NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); nameNull.TrueBlock.Statements.Add(new AssignmentStatement(localName, new Literal(defaultName, SystemTypes.String))); nameNull.TrueBlock.Statements.Add(new AssignmentStatement(localNamespace, new Literal(defaultNamespace, SystemTypes.String))); nameNull.FalseBlock.Statements.Add(new AssignmentStatement(localName, name)); nameNull.FalseBlock.Statements.Add(new AssignmentStatement(localNamespace, ns)); statements.Add(nameNull); } MethodCall call = new MethodCall(); call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteStartElement")); call.Operands = new ExpressionList(); call.Operands.Add(localName); call.Operands.Add(localNamespace); statements.Add( new ExpressionStatement( call ) ); } StatementList notNull = statements; if (!type.IsValueType) { notNull = AddCheckForNull(statements, Duplicate(src, referringType), type); } notNull.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, method), args))); if (name != null) { MethodCall call = new MethodCall(); call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteEndElement")); call.Operands = new ExpressionList(); statements.Add( new ExpressionStatement( call ) ); } return true; }
public override Expression VisitLiteral(Literal literal) { // All nulls get translated to our equivalent (zero) if (literal.Value == null) literal = new Literal(0, SystemTypes.UInt32); if (literal.Type != null && literal.Type is EnumNode) { // Enum field references get turned into constants by the resolver. // When they're referenced, we need to emit a suitable cast to make // them compatible with their intended usage. // int EnumTypeRestoration = ((_enumType) _enumValue); Expression enumTypeRestore = Templates.GetExpressionTemplate("EnumTypeRestoration"); Replacer.Replace(enumTypeRestore, "_enumType", literal.Type.Name); Replacer.Replace(enumTypeRestore, "_enumValue", literal); return enumTypeRestore; } return literal; }
public override Expression VisitMethodCall(MethodCall call) { var result = base.VisitMethodCall(call); call = result as MethodCall; if (call == null) return result; var mb = call.Callee as MemberBinding; if (IsInvariantCall(mb)) { if (1 < call.Operands.Count) { Member dummy; this.userMessage = SanitizeUserMessageInternal(this.autoProp.Getter, call.Operands[1], out dummy); } if (2 < call.Operands.Count) { this.conditionString = call.Operands[2] as Literal; } return call.Operands[0]; } if (call.Operands.Count != 0) return call; // only nullary properties. if (IsAutoPropGetterCall(mb)) { if (makeRequires) { return this.autoProp.Setter.Parameters[0]; } return new ReturnValue(autoProp.Type); } return result; }
public virtual Expression VisitLiteral(Literal literal) { return literal; }
public override Invariant VisitInvariant(Invariant @invariant) { if (@invariant == null) return null; SourceContext sctx = @invariant.SourceContext; if (invariant.SourceConditionText != null) { this.sourceTextOfInvariant = invariant.SourceConditionText; } else if (sctx.IsValid && sctx.Document.Text != null && sctx.Document.Text.Source != null) { this.sourceTextOfInvariant = new Literal(sctx.Document.Text.Source, SystemTypes.String); } else { this.sourceTextOfInvariant = Literal.Null; //this.sourceTextOfInvariant = new Literal("No other information available", SystemTypes.String); } return base.VisitInvariant(@invariant); }