public virtual void VisitIsExpression(IsExpression isExpression) { if (this.ThrowException) { throw (System.Exception) this.CreateException(isExpression); } }
/// <summary> /// http://dlang.org/expression.html#IsExpression /// </summary> public ISemantic E(IsExpression isExpression) { if(!eval) return new PrimitiveType(DTokens.Bool); bool retTrue = false; if (isExpression.TestedType != null) { var typeToCheck = DResolver.StripMemberSymbols(TypeDeclarationResolver.ResolveSingle(isExpression.TestedType, ctxt)); if (typeToCheck != null) { // case 1, 4 if (isExpression.TypeSpecialization == null && isExpression.TypeSpecializationToken == 0) retTrue = true; // The probably most frequented usage of this expression else if (isExpression.TypeAliasIdentifierHash == 0) retTrue = evalIsExpression_NoAlias(isExpression, typeToCheck); else retTrue = evalIsExpression_WithAliases(isExpression, typeToCheck); } } return new PrimitiveValue(DTokens.Bool, retTrue?1:0, isExpression); }
public virtual void VisitIsExpression(IsExpression isExpression) { if (ThrowException) { throw (Exception)CreateException(isExpression); } }
public override object VisitIsExpression(IsExpression isExpression, CSharpAstResolver astResolver) { ResolveResult resolveResult = astResolver.Resolve(isExpression.Type); if (resolveResult != null) { Tree.Tree t = SourceImporter.SourceImporter.Tree; //1) target node ClassNode targetNode = new ClassNode(resolveResult.Type.FullName, resolveResult); targetNode = t.AddOrGetClassNode(resolveResult.Type.Namespace, targetNode);//override if already in tree with that node if (targetNode != null) { //2) caller node (can't be null) //find out class in which the invocation statement is found TypeDeclaration classDeclaration = isExpression.Ancestors.Where(a => a is TypeDeclaration).Cast <TypeDeclaration>().First(); //resolve the class declaration TypeResolveResult resolvedClass = astResolver.Resolve(classDeclaration) as TypeResolveResult; if (resolvedClass != null) { ClassNode callerNode = new ClassNode(resolvedClass.Type.FullName, resolvedClass); callerNode = t.AddOrGetClassNode(resolvedClass.Type.Namespace, callerNode); //override if already in tree with that node //3) edge (dependency) between caller and target callerNode.AddDependency(targetNode); } } } return(base.VisitIsExpression(isExpression, astResolver)); }
public override void VisitIsExpression(IsExpression isExpression) { base.VisitIsExpression(isExpression); var type = ctx.Resolve(isExpression.Expression).Type; var providedType = ctx.ResolveType(isExpression.Type); if (type.Kind == TypeKind.Unknown || providedType.Kind == TypeKind.Unknown) { return; } // var foundConversion = conversions.ImplicitConversion(type, providedType); if (!IsValidReferenceOrBoxingConversion(type, providedType)) { return; } var action = new CodeAction( ctx.TranslateString("Compare with 'null'"), script => script.Replace(isExpression, new BinaryOperatorExpression( isExpression.Expression.Clone(), BinaryOperatorType.InEquality, new PrimitiveExpression(null))), isExpression ); AddIssue(new CodeIssue(isExpression, ctx.TranslateString("Given expression is always of the provided type. Consider comparing with 'null' instead"), new [] { action })); }
/// <summary> /// http://dlang.org/expression.html#IsExpression /// </summary> public ISemantic E(IsExpression isExpression) { if (!eval) { return(new PrimitiveType(DTokens.Bool)); } bool retTrue = false; if (isExpression.TestedType != null) { var typeToCheck = DResolver.StripMemberSymbols(TypeDeclarationResolver.ResolveSingle(isExpression.TestedType, ctxt)); if (typeToCheck != null) { // case 1, 4 if (isExpression.TypeSpecialization == null && isExpression.TypeSpecializationToken == 0) { retTrue = true; } // The probably most frequented usage of this expression else if (isExpression.TypeAliasIdentifierHash == 0) { retTrue = evalIsExpression_NoAlias(isExpression, typeToCheck); } else { retTrue = evalIsExpression_WithAliases(isExpression, typeToCheck); } } } return(new PrimitiveValue(DTokens.Bool, retTrue?1:0, isExpression)); }
public override void VisitIsExpression (IsExpression isExpression) { base.VisitIsExpression (isExpression); // var conversions = CSharpConversions.Get(ctx.Compilation); var exprType = ctx.Resolve (isExpression.Expression).Type; var providedType = ctx.ResolveType (isExpression.Type); if (exprType.Kind == TypeKind.Unknown || providedType.Kind == TypeKind.Unknown) return; if (IsValidReferenceOrBoxingConversion(exprType, providedType)) return; var exprTP = exprType as ITypeParameter; var providedTP = providedType as ITypeParameter; if (exprTP != null) { if (IsValidReferenceOrBoxingConversion(exprTP.EffectiveBaseClass, providedType) && exprTP.EffectiveInterfaceSet.All(i => IsValidReferenceOrBoxingConversion(i, providedType))) return; } if (providedTP != null) { if (IsValidReferenceOrBoxingConversion(exprType, providedTP.EffectiveBaseClass)) return; } AddIssue (isExpression, ctx.TranslateString ("Given expression is never of the provided type")); }
/// <inheritdoc /> public IFilterableQuery <T> And ( Expression <Func <T, object> > property, IsExpression expression ) { return(Where(property, expression)); }
/// <inheritdoc /> public IFilterableQuery <T> And ( string property, IsExpression expression ) { return(Where(property, expression)); }
public static void SerializeIsExpression() { var v = new NumberLiteral(2); var a = new IsExpression(v, v); var b = SerializationUtil.Reserialize(a); Assert.AreEqual(a, b); }
/// <inheritdoc /> public virtual TQuery And ( string property, IsExpression expression ) { return(Where(property, expression)); }
/// <inheritdoc /> public virtual TQuery And ( Expression <Func <TSource, object> > property, IsExpression expression ) { return(Where(property, expression)); }
/// <inheritdoc /> public virtual TQuery Where ( Expression <Func <TSource, object> > property, IsExpression expression ) { return(Where(ExpressionHelper.GetPropertyName(property), expression)); }
public UnifiedElement VisitIsExpression(IsExpression expr, object data) { var op = UnifiedBinaryOperator.Create( "is", UnifiedBinaryOperatorKind.InstanceOf); var value = expr.Expression.TryAcceptForExpression(this); var type = LookupType(expr.Type); return(UnifiedBinaryExpression.Create(value, op, type)); }
public override object Visit(IsExpression node, object obj) { if (node.Location == ((AstNode)obj).Location || found) { found = true; return(this.table); } return(base.Visit(node, obj)); }
private bool evalIsExpression_WithAliases(IsExpression isExpression, AbstractType typeToCheck) { /* * Note: It's needed to let the abstract ast scanner also scan through IsExpressions etc. * in order to find aliases and/or specified template parameters! */ var expectedTemplateParams = new TemplateParameter[isExpression.TemplateParameterList.Length + 1]; expectedTemplateParams [0] = isExpression.ArtificialFirstSpecParam; if (expectedTemplateParams.Length > 1) { isExpression.TemplateParameterList.CopyTo(expectedTemplateParams, 1); } var tpl_params = new DeducedTypeDictionary(expectedTemplateParams); var tpd = new TemplateParameterDeduction(tpl_params, ctxt); bool retTrue = false; if (isExpression.EqualityTest) // 6. { // a) if (isExpression.TypeSpecialization != null) { tpd.EnforceTypeEqualityWhenDeducing = true; retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck); tpd.EnforceTypeEqualityWhenDeducing = false; } else // b) { var r = evalIsExpression_EvalSpecToken(isExpression, typeToCheck, true); retTrue = r.Item1; tpl_params[isExpression.TypeAliasIdentifierHash] = new TemplateParameterSymbol(null, r.Item2); } } else // 5. { retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck); } if (retTrue && isExpression.TemplateParameterList != null) { foreach (var p in isExpression.TemplateParameterList) { if (!tpd.Handle(p, tpl_params[p.NameHash] != null ? tpl_params[p.NameHash].Base : null)) { return(false); } } } //TODO: Put all tpl_params results into the resolver context or make a new scope or something! return(retTrue); }
public void NullableIsExpression() { IsExpression ce = ParseUtilCSharp.ParseExpression <IsExpression>("o is int?"); ComposedType type = (ComposedType)ce.Type; Assert.IsTrue(type.HasNullableSpecifier); Assert.AreEqual("int", ((PrimitiveType)type.BaseType).Keyword); Assert.IsTrue(ce.Expression is IdentifierExpression); }
public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) { base.VisitBinaryOperatorExpression(binaryOperatorExpression); var m = pattern.Match(binaryOperatorExpression); if (!m.Success) { return; } Expression identifier = null; AstType type = null; if (binaryOperatorExpression.Left is TypeOfExpression && binaryOperatorExpression.Right is InvocationExpression) { type = (binaryOperatorExpression.Left as TypeOfExpression).Type; var right = binaryOperatorExpression.Right as InvocationExpression; identifier = (right.Target as MemberReferenceExpression).Target; } else if (binaryOperatorExpression.Right is TypeOfExpression && binaryOperatorExpression.Left is InvocationExpression) { type = (binaryOperatorExpression.Right as TypeOfExpression).Type; var left = binaryOperatorExpression.Left as InvocationExpression; identifier = (left.Target as MemberReferenceExpression).Target; } else { return; } if (identifier == null || type == null) { return; } var typeResolved = ctx.Resolve(type) as TypeResolveResult; if (typeResolved.Type.Kind == TypeKind.Class) { if (!typeResolved.Type.GetDefinition().IsSealed) { return; } } AddIssue( binaryOperatorExpression, ctx.TranslateString("Operator 'is' can be used"), ctx.TranslateString("Replace with 'is' operator"), script => { var isExpr = new IsExpression(identifier.Clone(), type.Clone()); script.Replace(binaryOperatorExpression, isExpr); } ); }
/// <inheritdoc /> public IFilterableQuery <TSource> Where ( string property, IsExpression expression ) { _query.Where(property, expression); return(this); }
public override void Visit(IsExpression x) { if (x.TypeAliasIdentifierHash == searchHash && symbol is TemplateParameter.Node && (symbol as TemplateParameter.Node).TemplateParameter == x.ArtificialFirstSpecParam) { l.Add(x.ArtificialFirstSpecParam); } base.Visit(x); }
/// <inheritdoc /> public virtual TQuery Where ( string property, IsExpression expression ) { ICriterion criterion = expression.Compile(property); return(Where(criterion)); }
/// <inheritdoc /> public IFilterableQuery <TSource> Where ( Expression <Func <TSource, object> > property, IsExpression expression ) { _query.Where(property, expression); return(this); }
public override Object Visit(IsExpression node, Object obj) { IsExpression clonedIsExpression = new IsExpression((Expression)node.Expression.Accept(this, obj), node.TypeId, node.Location); if (node.TypeExpr != null) { clonedIsExpression.TypeExpr = node.TypeExpr.CloneType(typeVariableMappings, this.typeExpresionVariableMapping); } return(clonedIsExpression); }
public override Object Visit(IsExpression node, Object obj) { Object aux = null; node.Expression.LeftExpression = node.LeftExpression; if ((aux = node.Expression.Accept(this, false)) is SingleIdentifierExpression) { node.Expression = (SingleIdentifierExpression)aux; } return(null); }
public override Object Visit(IsExpression node, Object obj) { int indent = Convert.ToInt32(obj); this.printIndentation(indent); this.output.WriteLine("IsExpression Type: {0} [{1}:{2}]", printType(node.ExpressionType), node.Location.Line, node.Location.Column); node.Expression.Accept(this, indent + 1); this.printIndentation(indent + 1); this.output.WriteLine(printType(node.TypeExpr)); return(null); }
public override void VisitIsExpression (IsExpression isExpression) { base.VisitIsExpression (isExpression); var exprType = ctx.Resolve (isExpression.Expression).Type; var providedType = ctx.ResolveType (isExpression.Type); if (TypeCompatibilityHelper.CheckTypeCompatibility(exprType, providedType) == TypeCompatibilityHelper.TypeCompatiblity.NeverOfProvidedType) AddIssue (isExpression, ctx.TranslateString ("Given expression is never of the provided type")); }
/// <inheritdoc /> public IFilterableQuery <T> Where ( Expression <Func <T, object> > property, IsExpression expression ) { Expression <Func <TSource, object> > temp = _rebaser.RebaseTo <TSource, object>(property); _query.Where(temp, expression); return(this); }
public void NullableIsExpressionInBinaryOperatorExpression() { BinaryOperatorExpression boe; boe = ParseUtilCSharp.ParseExpression <BinaryOperatorExpression>("o is int? == true"); IsExpression ce = (IsExpression)boe.Left; ComposedType type = (ComposedType)ce.Type; Assert.IsTrue(type.HasNullableSpecifier); Assert.AreEqual("int", ((PrimitiveType)type.BaseType).Keyword); Assert.IsTrue(ce.Expression is IdentifierExpression); }
public override void VisitIsExpression(IsExpression isExpression) { base.VisitIsExpression(isExpression); var exprType = ctx.Resolve(isExpression.Expression).Type; var providedType = ctx.ResolveType(isExpression.Type); if (TypeCompatibilityHelper.CheckTypeCompatibility(exprType, providedType) == TypeCompatibilityHelper.TypeCompatiblity.NeverOfProvidedType) { AddIssue(isExpression, ctx.TranslateString("Given expression is never of the provided type")); } }
private bool evalIsExpression_NoAlias(IsExpression isExpression, AbstractType typeToCheck) { if (isExpression.TypeSpecialization != null) { var spec = DResolver.StripAliasSymbols(TypeDeclarationResolver.Resolve(isExpression.TypeSpecialization, ctxt)); return(spec != null && spec.Length != 0 && (isExpression.EqualityTest ? ResultComparer.IsEqual(typeToCheck, spec[0]) : ResultComparer.IsImplicitlyConvertible(typeToCheck, spec[0], ctxt))); } return(isExpression.EqualityTest && evalIsExpression_EvalSpecToken(isExpression, typeToCheck, false).Item1); }
public override void VisitIsExpression(IsExpression isExpression) { if (InsertParenthesesForReadability) { // few people know the precedence of 'is', so always put parentheses in nice-looking mode. ParenthesizeIfRequired(isExpression.Expression, NullableRewrap); } else { ParenthesizeIfRequired(isExpression.Expression, RelationalAndTypeTesting); } base.VisitIsExpression(isExpression); }
public override object VisitIsExpression(IsExpression isExpression, object data) { if (InsertParenthesesForReadability) { // few people know the precedence of 'is', so always put parentheses in nice-looking mode. ParenthesizeIfRequired(isExpression.Expression, Primary); } else { ParenthesizeIfRequired(isExpression.Expression, RelationalAndTypeTesting); } return(base.VisitIsExpression(isExpression, data)); }
private bool evalIsExpression_WithAliases(IsExpression isExpression, AbstractType typeToCheck) { /* * Note: It's needed to let the abstract ast scanner also scan through IsExpressions etc. * in order to find aliases and/or specified template parameters! */ var expectedTemplateParams = new TemplateParameter[isExpression.TemplateParameterList == null ? 1 : (isExpression.TemplateParameterList.Length + 1)]; expectedTemplateParams [0] = isExpression.ArtificialFirstSpecParam; if(expectedTemplateParams.Length > 1) isExpression.TemplateParameterList.CopyTo (expectedTemplateParams, 1); var tpl_params = new DeducedTypeDictionary(expectedTemplateParams); var tpd = new TemplateParameterDeduction(tpl_params, ctxt); bool retTrue = false; if (isExpression.EqualityTest) // 6. { // a) if (isExpression.TypeSpecialization != null) { tpd.EnforceTypeEqualityWhenDeducing = true; retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck); tpd.EnforceTypeEqualityWhenDeducing = false; } else // b) { var r = evalIsExpression_EvalSpecToken(isExpression, typeToCheck, true); retTrue = r.Item1; tpl_params[isExpression.ArtificialFirstSpecParam] = new TemplateParameterSymbol(isExpression.ArtificialFirstSpecParam, r.Item2); } } else // 5. retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck); if (retTrue && isExpression.TemplateParameterList != null) foreach (var p in isExpression.TemplateParameterList) if (!tpd.Handle(p, tpl_params[p] != null ? tpl_params[p].Base : null)) return false; if (retTrue) { foreach (var kv in tpl_params) ctxt.CurrentContext.DeducedTemplateParameters[kv.Key] = kv.Value; } return retTrue; }
/// <inheritdoc /> public IFilterableQuery <T> Where ( string property, IsExpression expression ) { if (!property.Contains(".")) { property = _alias + "." + property; } _query.Where(property, expression); return(this); }
public override void VisitIsExpression (IsExpression isExpression) { base.VisitIsExpression (isExpression); var type = ctx.Resolve (isExpression.Expression).Type; var providedType = ctx.ResolveType (isExpression.Type); if (type.GetAllBaseTypes ().All (t => !t.Equals (providedType))) return; var action = new CodeAction (ctx.TranslateString ("Compare with 'null'"), scrpit => scrpit.Replace (isExpression, new BinaryOperatorExpression ( isExpression.Expression.Clone (), BinaryOperatorType.InEquality, new PrimitiveExpression (null)))); AddIssue (isExpression, ctx.TranslateString ("Given expression is always of the provided type. " + "Consider comparing with 'null' instead"), new [] { action }); }
private bool evalIsExpression_WithAliases(IsExpression isExpression, AbstractType typeToCheck) { /* * Note: It's needed to let the abstract ast scanner also scan through IsExpressions etc. * in order to find aliases and/or specified template parameters! */ var expectedTemplateParams = new TemplateParameter[isExpression.TemplateParameterList.Length + 1]; expectedTemplateParams [0] = isExpression.ArtificialFirstSpecParam; if(expectedTemplateParams.Length > 1) isExpression.TemplateParameterList.CopyTo (expectedTemplateParams, 1); var tpl_params = new DeducedTypeDictionary(expectedTemplateParams); var tpd = new TemplateParameterDeduction(tpl_params, ctxt); bool retTrue = false; if (isExpression.EqualityTest) // 6. { // a) if (isExpression.TypeSpecialization != null) { tpd.EnforceTypeEqualityWhenDeducing = true; retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck); tpd.EnforceTypeEqualityWhenDeducing = false; } else // b) { var r = evalIsExpression_EvalSpecToken(isExpression, typeToCheck, true); retTrue = r.Item1; tpl_params[isExpression.TypeAliasIdentifierHash] = new TemplateParameterSymbol(null, r.Item2); } } else // 5. retTrue = tpd.Handle(isExpression.ArtificialFirstSpecParam, typeToCheck); if (retTrue && isExpression.TemplateParameterList != null) foreach (var p in isExpression.TemplateParameterList) if (!tpd.Handle(p, tpl_params[p.NameHash] != null ? tpl_params[p.NameHash].Base : null)) return false; //TODO: Put all tpl_params results into the resolver context or make a new scope or something! return retTrue; }
public override void VisitIsExpression (IsExpression isExpression) { base.VisitIsExpression (isExpression); var type = ctx.Resolve (isExpression.Expression).Type; var providedType = ctx.ResolveType (isExpression.Type); // var foundConversion = conversions.ImplicitConversion(type, providedType); if (!IsValidReferenceOrBoxingConversion(type, providedType)) return; var action = new CodeAction (ctx.TranslateString ("Compare with 'null'"), scrpit => scrpit.Replace (isExpression, new BinaryOperatorExpression ( isExpression.Expression.Clone (), BinaryOperatorType.InEquality, new PrimitiveExpression (null)))); AddIssue (isExpression, ctx.TranslateString ("Given expression is always of the provided type. " + "Consider comparing with 'null' instead"), new [] { action }); }
public virtual void VisitIsExpression(IsExpression isExpression) { if (this.ThrowException) { throw (Exception)this.CreateException(isExpression); } }
public override void VisitIsExpression(IsExpression isExpression) { if (InsertParenthesesForReadability) { // few people know the precedence of 'is', so always put parentheses in nice-looking mode. ParenthesizeIfRequired(isExpression.Expression, Primary); } else { ParenthesizeIfRequired(isExpression.Expression, RelationalAndTypeTesting); } base.VisitIsExpression(isExpression); }
List<MethodDeclaration> CreateEqualsOverrides(IType currentClass) { List<MethodDeclaration> methods = new List<MethodDeclaration>(); AstType boolReference = ConvertType(KnownTypeCode.Boolean); AstType objectReference = ConvertType(KnownTypeCode.Object); MethodDeclaration method = new MethodDeclaration { Name = "Equals", Modifiers = Modifiers.Public | Modifiers.Override, ReturnType = boolReference }; method.Parameters.Add(new ParameterDeclaration(objectReference, "obj")); method.Body = new BlockStatement(); AstType currentType = ConvertType(currentClass); Expression expr = null; if (currentClass.Kind == TypeKind.Struct) { // return obj is CurrentType && Equals((CurrentType)obj); expr = new IsExpression() { Expression = new IdentifierExpression("obj"), Type = currentType.Clone() }; expr = new ParenthesizedExpression(expr); expr = new BinaryOperatorExpression( expr, BinaryOperatorType.ConditionalAnd, new InvocationExpression( new IdentifierExpression("Equals"), new List<Expression> { new CastExpression(currentType.Clone(), new IdentifierExpression("obj")) })); method.Body.Add(new ReturnStatement(expr)); methods.Add(method); // IEquatable implementation: method = new MethodDeclaration { Name = "Equals", Modifiers = Modifiers.Public, ReturnType = boolReference.Clone() }; method.Parameters.Add(new ParameterDeclaration(currentType, "other")); method.Body = new BlockStatement(); } else { method.Body.Add(new VariableDeclarationStatement( currentType.Clone(), "other", new IdentifierExpression("obj").CastAs(currentType.Clone()))); method.Body.Add(new IfElseStatement( new BinaryOperatorExpression(new IdentifierExpression("other"), BinaryOperatorType.Equality, new PrimitiveExpression(null, "null")), new ReturnStatement(new PrimitiveExpression(false, "false")))); } expr = null; foreach (IField field in currentClass.GetFields()) { if (field.IsStatic) continue; if (expr == null) { expr = TestEquality("other", field); } else { expr = new BinaryOperatorExpression(expr, BinaryOperatorType.ConditionalAnd, TestEquality("other", field)); } } foreach (IProperty property in currentClass.GetProperties()) { if (property.IsStatic || !property.IsAutoImplemented()) continue; if (expr == null) { expr = TestEquality("other", property); } else { expr = new BinaryOperatorExpression(expr, BinaryOperatorType.ConditionalAnd, TestEquality("other", property)); } } method.Body.Add(new ReturnStatement(expr ?? new PrimitiveExpression(true, "true"))); methods.Add(method); return methods; }
public void Visit(IsExpression x) { }
private bool evalIsExpression_NoAlias(IsExpression isExpression, AbstractType typeToCheck) { if (isExpression.TypeSpecialization != null) { var spec = DResolver.StripAliasSymbols(TypeDeclarationResolver.Resolve(isExpression.TypeSpecialization, ctxt)); return spec != null && spec.Length != 0 && (isExpression.EqualityTest ? ResultComparer.IsEqual(typeToCheck, spec[0]) : ResultComparer.IsImplicitlyConvertible(typeToCheck, spec[0], ctxt)); } return isExpression.EqualityTest && evalIsExpression_EvalSpecToken(isExpression, typeToCheck, false).Item1; }
IExpression PrimaryExpression(IBlockNode Scope=null) { bool isModuleScoped = false; // For minimizing possible overhead, skip 'useless' tokens like an initial dot <<< TODO if (isModuleScoped= laKind == Dot) Step(); if (laKind == __FILE__ || laKind == __LINE__) { Step(); object id = null; if (t.Kind == __FILE__ && doc != null) id = doc.FileName; else if(t.Kind==__LINE__) id = t.line; return new IdentifierExpression(id) { Location=t.Location, EndLocation=t.EndLocation }; } // Dollar (== Array length expression) if (laKind == Dollar) { Step(); return new TokenExpression(laKind) { Location = t.Location, EndLocation = t.EndLocation }; } // TemplateInstance if (laKind == (Identifier) && Lexer.CurrentPeekToken.Kind == (Not) && (Peek().Kind != Is && Lexer.CurrentPeekToken.Kind != In) /* Very important: The 'template' could be a '!is'/'!in' expression - With two tokens each! */) return TemplateInstance(); // Identifier if (laKind == (Identifier)) { Step(); return new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation }; } // SpecialTokens (this,super,null,true,false,$) // $ has been handled before if (laKind == (This) || laKind == (Super) || laKind == (Null) || laKind == (True) || laKind == (False)) { Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; } #region Literal if (laKind == Literal) { Step(); var startLoc = t.Location; // Concatenate multiple string literals here if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { var a = t.LiteralValue as string; while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { Step(); a += t.LiteralValue as string; } return new IdentifierExpression(a, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation }; } //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation }; return new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation }; } #endregion #region ArrayLiteral | AssocArrayLiteral if (laKind == (OpenSquareBracket)) { Step(); var startLoc = t.Location; // Empty array literal if (laKind == CloseSquareBracket) { Step(); return new ArrayLiteralExpression() {Location=startLoc, EndLocation = t.EndLocation }; } var firstExpression = AssignExpression(); // Associtative array if (laKind == Colon) { Step(); var ae = new AssocArrayExpression() { Location=startLoc}; LastParsedObject = ae; var firstValueExpression = AssignExpression(); ae.KeyValuePairs.Add(firstExpression, firstValueExpression); while (laKind == Comma) { Step(); var keyExpr = AssignExpression(); Expect(Colon); var valueExpr = AssignExpression(); ae.KeyValuePairs.Add(keyExpr, valueExpr); } Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } else // Normal array literal { var ae = new ArrayLiteralExpression() { Location=startLoc}; LastParsedObject = ae; var expressions = new List<IExpression>(); expressions.Add(firstExpression); while (laKind == Comma) { Step(); if (laKind == CloseSquareBracket) // And again, empty expressions are allowed break; expressions.Add(AssignExpression()); } ae.Expressions = expressions; Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } } #endregion #region FunctionLiteral if (laKind == Delegate || laKind == Function || laKind == OpenCurlyBrace || (laKind == OpenParenthesis && IsFunctionLiteral())) { var fl = new FunctionLiteral() { Location=la.Location}; LastParsedObject = fl; fl.AnonymousMethod.StartLocation = la.Location; if (laKind == Delegate || laKind == Function) { Step(); fl.LiteralToken = t.Kind; } // file.d:1248 /* listdir (".", delegate bool (DirEntry * de) { auto s = std.string.format("%s : c %s, w %s, a %s", de.name, toUTCString (de.creationTime), toUTCString (de.lastWriteTime), toUTCString (de.lastAccessTime)); return true; } ); */ if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate { if (!MemberFunctionAttribute[laKind] && Lexer.CurrentPeekToken.Kind == OpenParenthesis) fl.AnonymousMethod.Type = BasicType(); else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace) fl.AnonymousMethod.Type = Type(); if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); } FunctionBody(fl.AnonymousMethod); fl.EndLocation = t.EndLocation; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; } #endregion #region AssertExpression if (laKind == (Assert)) { Step(); var startLoc = t.Location; Expect(OpenParenthesis); var ce = new AssertExpression() { Location=startLoc}; LastParsedObject = ce; var exprs = new List<IExpression>(); exprs.Add(AssignExpression()); if (laKind == (Comma)) { Step(); exprs.Add(AssignExpression()); } ce.AssignExpressions = exprs.ToArray(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion #region MixinExpression | ImportExpression if (laKind == Mixin) { Step(); var e = new MixinExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } if (laKind == Import) { Step(); var e = new ImportExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } #endregion if (laKind == (Typeof)) { var startLoc = la.Location; return new TypeDeclarationExpression(TypeOf()) {Location=startLoc,EndLocation=t.EndLocation}; } // TypeidExpression if (laKind == (Typeid)) { Step(); var ce = new TypeidExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); AllowWeakTypeParsing = true; ce.Type = Type(); AllowWeakTypeParsing = false; if (ce.Type==null) ce.Expression = AssignExpression(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #region IsExpression if (laKind == Is) { Step(); var ce = new IsExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); var LookAheadBackup = la; AllowWeakTypeParsing = true; ce.TestedType = Type(); AllowWeakTypeParsing = false; if (ce.TestedType!=null && laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal || Lexer.CurrentPeekToken.Kind == Colon)) { Step(); ce.TypeAliasIdentifier = strVal; } else // D Language specs mistake: In an IsExpression there also can be expressions! if(ce.TestedType==null || !(laKind==CloseParenthesis || laKind==Equal||laKind==Colon)) { // Reset lookahead token to prior position la = LookAheadBackup; // Reset wrongly parsed type declaration ce.TestedType = null; ce.TestedExpression = ConditionalExpression(); } if(ce.TestedExpression==null && ce.TestedType==null) SynErr(laKind,"In an IsExpression, either a type or an expression is required!"); if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } if (laKind == Colon || laKind == Equal) { Step(); ce.EqualityTest = t.Kind == Equal; } else if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } /* TypeSpecialization: Type struct union class interface enum function delegate super const immutable inout shared return */ if (ClassLike[laKind] || laKind==Typedef || // typedef is possible although it's not yet documented in the syntax docs laKind==Enum || laKind==Delegate || laKind==Function || laKind==Super || laKind==Return) { Step(); ce.TypeSpecializationToken = t.Kind; } else ce.TypeSpecialization = Type(); if (laKind == Comma) { Step(); ce.TemplateParameterList = TemplateParameterList(false); } Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion // ( Expression ) if (laKind == OpenParenthesis) { Step(); var ret = new SurroundingParenthesesExpression() {Location=t.Location }; LastParsedObject = ret; ret.Expression = Expression(); Expect(CloseParenthesis); ret.EndLocation = t.EndLocation; return ret; } // TraitsExpression if (laKind == (__traits)) return TraitsExpression(); #region BasicType . Identifier if (laKind == (Const) || laKind == (Immutable) || laKind == (Shared) || laKind == (InOut) || BasicTypes[laKind]) { Step(); var startLoc = t.Location; IExpression left = null; if (!BasicTypes[t.Kind]) { int tk = t.Kind; // Put an artificial parenthesis around the following type declaration if (laKind != OpenParenthesis) { var mttd = new MemberFunctionAttributeDecl(tk); LastParsedObject = mttd; mttd.InnerType = Type(); left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation }; } else { Expect(OpenParenthesis); var mttd = new MemberFunctionAttributeDecl(tk); LastParsedObject = mttd; mttd.InnerType = Type(); Expect(CloseParenthesis); left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation }; } } else left = new TokenExpression(t.Kind) {Location=startLoc,EndLocation=t.EndLocation }; if (laKind == (Dot) && Peek(1).Kind==Identifier) { Step(); Step(); var meaex = new PostfixExpression_Access() { PostfixForeExpression=left, TemplateOrIdentifier=new IdentifierDeclaration(t.Value),EndLocation=t.EndLocation }; return meaex; } return left; } #endregion // TODO? Expressions can of course be empty... //return null; SynErr(Identifier); Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; }
public override void VisitIsExpression(IsExpression isExpression) { new CastBlock(this, isExpression).Emit(); }
/// <summary> /// Reads an is expression. /// </summary> /// <param name="leftHandSide">The expression on the left hand side of the operator.</param> /// <param name="previousPrecedence">The precedence of the expression just before this one.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns>Returns the expression.</returns> private IsExpression GetIsExpression( Expression leftHandSide, ExpressionPrecedence previousPrecedence, bool unsafeCode) { Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.Ignore(previousPrecedence); Param.Ignore(unsafeCode); IsExpression expression = null; // Check the previous precedence to see if we are allowed to gather up the is expression. if (this.CheckPrecedence(previousPrecedence, ExpressionPrecedence.Relational)) { // Make sure the left hand side has at least one token. Debug.Assert(leftHandSide.Tokens.First != null, "The left hand side should not be empty"); // Get the is symbol. this.tokens.Add(this.GetToken(CsTokenType.Is, SymbolType.Is)); // The next token must be the type. this.GetNextSymbol(SymbolType.Other); // Get the expression representing the type. LiteralExpression rightHandSide = this.GetTypeTokenExpression(unsafeCode, true, true); if (rightHandSide == null || rightHandSide.Tokens.First == null) { throw this.CreateSyntaxException(); } // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last); // Create and return the expression. expression = new IsExpression(partialTokens, leftHandSide, rightHandSide); } return expression; }
public void VisitIsExpression(IsExpression isExpression) { StartNode(isExpression); isExpression.Expression.AcceptVisitor(this); Space(); WriteKeyword(IsExpression.IsKeywordRole); isExpression.Type.AcceptVisitor(this); EndNode(isExpression); }
public virtual void VisitIsExpression (IsExpression isExpression) { VisitChildren (isExpression); }
public override void VisitIsExpression (IsExpression isExpression) { base.VisitIsExpression (isExpression); var exprType = ctx.Resolve (isExpression.Expression).Type; var providedType = ctx.ResolveType (isExpression.Type); var exprBaseTypes = exprType.GetAllBaseTypes ().ToArray (); // providedType is a base type of exprType if (exprBaseTypes.Any (t => t.Equals (providedType))) return; if ((exprType.IsReferenceType == true && providedType.IsReferenceType == false) || (exprType.IsReferenceType == false && providedType.IsReferenceType == true)) { AddIssue (isExpression); return; } var typeParameter = exprType as ITypeParameter; var providedTypeParameter = providedType as ITypeParameter; if (typeParameter != null) { // check if providedType can be a derived type var providedBaseTypes = providedType.GetAllBaseTypes ().ToArray (); var providedTypeDef = providedType.GetDefinition (); // if providedType is sealed, check if it fullfills all the type parameter constraints, // otherwise, only check if it is derived from EffectiveBaseClass if (providedTypeParameter == null && (providedTypeDef == null || providedTypeDef.IsSealed)) { if (CheckTypeParameterConstraints (providedType, providedBaseTypes, typeParameter)) return; } else if (providedBaseTypes.Any (t => t.Equals (typeParameter.EffectiveBaseClass))) { return; } // if providedType is also a type parameter, check if base classes are compatible if (providedTypeParameter != null && exprBaseTypes.Any (t => t.Equals (providedTypeParameter.EffectiveBaseClass))) return; AddIssue (isExpression); return; } // check if exprType fullfills all the type parameter constraints if (providedTypeParameter != null && CheckTypeParameterConstraints (exprType, exprBaseTypes, providedTypeParameter)) return; switch (exprType.Kind) { case TypeKind.Class: var exprTypeDef = exprType.GetDefinition (); if (exprTypeDef == null) return; // exprType is sealed, but providedType is not a base type of it or it does not // fullfill all the type parameter constraints if (exprTypeDef.IsSealed) break; // check if providedType can be a derived type if (providedType.Kind == TypeKind.Interface || providedType.GetAllBaseTypes ().Any (t => t.Equals (exprType))) return; if (providedTypeParameter != null && exprBaseTypes.Any (t => t.Equals (providedTypeParameter.EffectiveBaseClass))) return; break; case TypeKind.Struct: case TypeKind.Delegate: case TypeKind.Enum: case TypeKind.Array: case TypeKind.Anonymous: case TypeKind.Null: break; default: return; } AddIssue (isExpression); }
void AddIssue(IsExpression isExpression) { AddIssue (isExpression, ctx.TranslateString ("Given expression is never of the provided type")); }
IExpression PrimaryExpression(IBlockNode Scope=null) { bool isModuleScoped = laKind == Dot; if (isModuleScoped) { Step(); if (IsEOF) { var dot = new TokenExpression(Dot) { Location = t.Location, EndLocation = t.EndLocation }; return new PostfixExpression_Access{ PostfixForeExpression = dot, AccessExpression = new TokenExpression(DTokens.Incomplete) }; } } // TemplateInstance if (IsTemplateInstance) { var tix = TemplateInstance(Scope); if (tix != null) tix.ModuleScopedIdentifier = isModuleScoped; return tix; } if (IsLambaExpression()) return LambaExpression(Scope); CodeLocation startLoc; switch (laKind) { // ArrayLiteral | AssocArrayLiteral case OpenSquareBracket: return ArrayLiteral(Scope); case New: return NewExpression(Scope); case Typeof: return new TypeDeclarationExpression(TypeOf()); case __traits: return TraitsExpression(); // Dollar (== Array length expression) case Dollar: Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; case Identifier: Step(); return new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation, ModuleScoped = isModuleScoped }; // SpecialTokens (this,super,null,true,false,$) // $ has been handled before case This: case Super: case Null: case True: case False: Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; case OpenParenthesis: if (IsFunctionLiteral()) goto case Function; // ( Expression ) Step(); var ret = new SurroundingParenthesesExpression() {Location=t.Location }; ret.Expression = Expression(); Expect(CloseParenthesis); ret.EndLocation = t.EndLocation; return ret; case Literal: Step(); startLoc = t.Location; // Concatenate multiple string literals here if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { var sb = new StringBuilder(t.RawCodeRepresentation ?? t.Value); while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { Step(); sb.Append(t.RawCodeRepresentation ?? t.Value); } return new IdentifierExpression(sb.ToString(), t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; } //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation }; return new IdentifierExpression(t.LiteralValue, t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; // FunctionLiteral case Delegate: case Function: case OpenCurlyBrace: var fl = new FunctionLiteral() { Location=la.Location}; fl.AnonymousMethod.Location = la.Location; if (laKind == Delegate || laKind == Function) { Step(); fl.LiteralToken = t.Kind; } // file.d:1248 /* listdir (".", delegate bool (DirEntry * de) { auto s = std.string.format("%s : c %s, w %s, a %s", de.name, toUTCString (de.creationTime), toUTCString (de.lastWriteTime), toUTCString (de.lastAccessTime)); return true; } ); */ if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate { if (!IsFunctionAttribute && Lexer.CurrentPeekToken.Kind == OpenParenthesis) fl.AnonymousMethod.Type = BasicType(); else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace) fl.AnonymousMethod.Type = Type(); if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); FunctionAttributes(fl.AnonymousMethod); } if (!IsEOF) { FunctionBody(fl.AnonymousMethod); fl.EndLocation = fl.AnonymousMethod.EndLocation; } else fl.EndLocation = la.Location; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; // AssertExpression case Assert: Step(); startLoc = t.Location; Expect(OpenParenthesis); var ce = new AssertExpression() { Location=startLoc}; var exprs = new List<IExpression>(); exprs.Add(AssignExpression()); if (laKind == (Comma)) { Step(); exprs.Add(AssignExpression()); } ce.AssignExpressions = exprs.ToArray(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; // MixinExpression case Mixin: Step(); var me = new MixinExpression() { Location=t.Location}; if (Expect(OpenParenthesis)) { me.AssignExpression = AssignExpression(); Expect(CloseParenthesis); } me.EndLocation = t.EndLocation; return me; // ImportExpression case Import: Step(); var ie = new ImportExpression() { Location=t.Location}; Expect(OpenParenthesis); ie.AssignExpression = AssignExpression(); Expect(CloseParenthesis); ie.EndLocation = t.EndLocation; return ie; // TypeidExpression case Typeid: Step(); var tide = new TypeidExpression() { Location=t.Location}; Expect(OpenParenthesis); if (IsAssignExpression()) tide.Expression = AssignExpression(Scope); else { Lexer.PushLookAheadBackup(); AllowWeakTypeParsing = true; tide.Type = Type(); AllowWeakTypeParsing = false; if (tide.Type == null || laKind != CloseParenthesis) { Lexer.RestoreLookAheadBackup(); tide.Expression = AssignExpression(); } else Lexer.PopLookAheadBackup(); } Expect (CloseParenthesis); tide.EndLocation = t.EndLocation; return tide; // IsExpression case Is: Step(); var ise = new IsExpression() { Location = t.Location }; Expect(OpenParenthesis); if ((ise.TestedType = Type()) == null) SynErr(laKind, "In an IsExpression, either a type or an expression is required!"); if (ise.TestedType != null) { if (laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal || Lexer.CurrentPeekToken.Kind == Colon)) { Step(); Strings.Add(strVal); ise.TypeAliasIdentifierHash = strVal.GetHashCode(); ise.TypeAliasIdLocation = t.Location; } else if (IsEOF) ise.TypeAliasIdentifierHash = DTokens.IncompleteIdHash; } if (laKind == Colon || laKind == Equal) { Step(); ise.EqualityTest = t.Kind == Equal; } else if (laKind == CloseParenthesis) { Step(); ise.EndLocation = t.EndLocation; return ise; } /* TypeSpecialization: Type struct union class interface enum function delegate super const immutable inout shared return */ bool specialTest = false; if (ise.EqualityTest) { switch (laKind) { case Typedef: // typedef is possible although it's not yet documented in the syntax docs case Enum: case Delegate: case Function: case Super: case Return: specialTest = true; break; case Const: case Immutable: case InOut: case Shared: specialTest = Peek(1).Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Comma; break; default: specialTest = IsClassLike(laKind); break; } } if (specialTest) { Step(); ise.TypeSpecializationToken = t.Kind; } else ise.TypeSpecialization = Type(); // TemplateParameterList if (laKind == Comma) { var tempParam = new List<TemplateParameter>(); do { Step(); tempParam.Add(TemplateParameter(null)); } while (laKind == Comma); ise.TemplateParameterList = tempParam.ToArray(); } Expect(CloseParenthesis); ise.EndLocation = t.EndLocation; return ise; default: if (DTokens.IsMetaIdentifier(laKind)) goto case Dollar; else if (IsBasicType()) { // BasicType . Identifier startLoc = la.Location; var bt=BasicType(); if ((bt is TypeOfDeclaration || bt is MemberFunctionAttributeDecl) && laKind!=Dot) return new TypeDeclarationExpression(bt); // Things like incomplete 'float.' expressions shall be parseable, too if (Expect(Dot) && (Expect(Identifier) || IsEOF)) return new PostfixExpression_Access() { PostfixForeExpression = new TypeDeclarationExpression(bt), AccessExpression = IsEOF ? new TokenExpression(Incomplete) as IExpression : new IdentifierExpression(t.Value) { Location=t.Location, EndLocation=t.EndLocation }, EndLocation = t.EndLocation }; return null; } SynErr(Identifier); if(laKind != CloseCurlyBrace) Step(); if (IsEOF) return new TokenExpression (DTokens.Incomplete) { Location = t.Location, EndLocation = t.Location }; // Don't know why, in rare situations, t tends to be null.. if (t == null) return null; return new TokenExpression() { Location = t.Location, EndLocation = t.EndLocation }; } }
public void VisitIsExpression(IsExpression isExpression) { JsonObject expression = CreateJsonExpression(isExpression); AddKeyword(expression, IsExpression.IsKeywordRole); expression.AddJsonValue("type-info", GenTypeInfo(isExpression.Type)); expression.AddJsonValue("expression", GenExpression(isExpression.Expression)); Push(expression); }
public override void Visit(IsExpression x) { // is(Type | if (x.TypeAliasIdentifierHash == DTokens.IncompleteIdHash && x.TestedType != null && !IsIncompleteDeclaration(x.TestedType)) { halt = true; explicitlyNoCompletion = true; } else base.Visit (x); }
IExpression PrimaryExpression(IBlockNode Scope=null) { bool isModuleScoped = laKind == Dot; if (isModuleScoped) { Step(); if (IsEOF) { LastParsedObject = new TokenExpression(Dot) { Location = t.Location, EndLocation = t.EndLocation }; TrackerVariables.ExpectingIdentifier = true; } } // Dollar (== Array length expression) if (laKind == Dollar || DTokens.MetaIdentifiers[laKind]) { Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; } // TemplateInstance if (IsTemplateInstance) { var tix = TemplateInstance(Scope); if (tix != null) tix.ModuleScopedIdentifier = isModuleScoped; return tix; } if (IsLambaExpression()) return LambaExpression(Scope); // Identifier if (laKind == Identifier) { Step(); return new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation, ModuleScoped = isModuleScoped }; } // SpecialTokens (this,super,null,true,false,$) // $ has been handled before if (laKind == (This) || laKind == (Super) || laKind == (Null) || laKind == (True) || laKind == (False)) { Step(); return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation }; } #region Literal if (laKind == Literal) { Step(); var startLoc = t.Location; // Concatenate multiple string literals here if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { var sb = new StringBuilder(t.RawCodeRepresentation ?? t.Value); while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral) { Step(); sb.Append(t.RawCodeRepresentation ?? t.Value); } return new IdentifierExpression(sb.ToString(), t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; } //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation }; return new IdentifierExpression(t.LiteralValue, t.LiteralFormat, t.Subformat) { Location = startLoc, EndLocation = t.EndLocation }; } #endregion #region ArrayLiteral | AssocArrayLiteral if (laKind == (OpenSquareBracket)) { Step(); var startLoc = t.Location; // Empty array literal if (laKind == CloseSquareBracket) { Step(); return new ArrayLiteralExpression(null) {Location=startLoc, EndLocation = t.EndLocation }; } /* * If it's an initializer, allow NonVoidInitializers as values. * Normal AssignExpressions otherwise. */ bool isInitializer = TrackerVariables.IsParsingInitializer; var firstExpression = isInitializer? NonVoidInitializer(Scope) : AssignExpression(Scope); // Associtative array if (laKind == Colon) { Step(); var ae = isInitializer ? new ArrayInitializer { Location = startLoc } : new AssocArrayExpression { Location=startLoc }; LastParsedObject = ae; var firstValueExpression = isInitializer? NonVoidInitializer(Scope) : AssignExpression(); ae.Elements.Add(new KeyValuePair<IExpression,IExpression>(firstExpression, firstValueExpression)); while (laKind == Comma) { Step(); if (laKind == CloseSquareBracket) break; var keyExpr = AssignExpression(); var valExpr=Expect(Colon) ? (isInitializer? NonVoidInitializer(Scope) : AssignExpression(Scope)) : null; ae.Elements.Add(new KeyValuePair<IExpression,IExpression>(keyExpr,valExpr)); } Expect(CloseSquareBracket); ae.EndLocation = t.EndLocation; return ae; } else // Normal array literal { var ae = new List<IExpression>(); LastParsedObject = ae; ae.Add(firstExpression); while (laKind == Comma) { Step(); if (laKind == CloseSquareBracket) // And again, empty expressions are allowed break; ae.Add(isInitializer? NonVoidInitializer(Scope) : AssignExpression(Scope)); } Expect(CloseSquareBracket); return new ArrayLiteralExpression(ae){ Location=startLoc, EndLocation = t.EndLocation }; } } #endregion #region FunctionLiteral if (laKind == Delegate || laKind == Function || laKind == OpenCurlyBrace || (laKind == OpenParenthesis && IsFunctionLiteral())) { var fl = new FunctionLiteral() { Location=la.Location}; LastParsedObject = fl; fl.AnonymousMethod.Location = la.Location; if (laKind == Delegate || laKind == Function) { Step(); fl.LiteralToken = t.Kind; } // file.d:1248 /* listdir (".", delegate bool (DirEntry * de) { auto s = std.string.format("%s : c %s, w %s, a %s", de.name, toUTCString (de.creationTime), toUTCString (de.lastWriteTime), toUTCString (de.lastAccessTime)); return true; } ); */ if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate { if (!IsFunctionAttribute && Lexer.CurrentPeekToken.Kind == OpenParenthesis) fl.AnonymousMethod.Type = BasicType(); else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace) fl.AnonymousMethod.Type = Type(); if (laKind == OpenParenthesis) fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod); FunctionAttributes(fl.AnonymousMethod); } if(!IsEOF) FunctionBody(fl.AnonymousMethod); fl.EndLocation = t.EndLocation; if (Scope != null) Scope.Add(fl.AnonymousMethod); return fl; } #endregion #region AssertExpression if (laKind == (Assert)) { Step(); var startLoc = t.Location; Expect(OpenParenthesis); var ce = new AssertExpression() { Location=startLoc}; LastParsedObject = ce; var exprs = new List<IExpression>(); exprs.Add(AssignExpression()); if (laKind == (Comma)) { Step(); exprs.Add(AssignExpression()); } ce.AssignExpressions = exprs.ToArray(); Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion #region MixinExpression | ImportExpression if (laKind == Mixin) { Step(); var e = new MixinExpression() { Location=t.Location}; LastParsedObject = e; if (Expect(OpenParenthesis)) { e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); } e.EndLocation = t.EndLocation; return e; } if (laKind == Import) { Step(); var e = new ImportExpression() { Location=t.Location}; LastParsedObject = e; Expect(OpenParenthesis); e.AssignExpression = AssignExpression(); Expect(CloseParenthesis); e.EndLocation = t.EndLocation; return e; } #endregion if (laKind == (Typeof)) { return new TypeDeclarationExpression(TypeOf()); } // TypeidExpression if (laKind == (Typeid)) { Step(); var ce = new TypeidExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); if (IsAssignExpression()) ce.Expression = AssignExpression(Scope); else { Lexer.PushLookAheadBackup(); AllowWeakTypeParsing = true; ce.Type = Type(); AllowWeakTypeParsing = false; if (ce.Type == null || laKind != CloseParenthesis) { Lexer.RestoreLookAheadBackup(); ce.Expression = AssignExpression(); } else Lexer.PopLookAheadBackup(); } if (!Expect(CloseParenthesis) && IsEOF) LastParsedObject = (ISyntaxRegion)ce.Type ?? ce.Expression; ce.EndLocation = t.EndLocation; return ce; } #region IsExpression if (laKind == Is) { Step(); var ce = new IsExpression() { Location=t.Location}; LastParsedObject = ce; Expect(OpenParenthesis); if((ce.TestedType = Type())==null) SynErr(laKind, "In an IsExpression, either a type or an expression is required!"); if (ce.TestedType!=null && laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal || Lexer.CurrentPeekToken.Kind == Colon)) { Step(); Strings.Add(strVal); ce.TypeAliasIdentifierHash = strVal.GetHashCode(); ce.TypeAliasIdLocation = t.Location; } if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } if (laKind == Colon || laKind == Equal) { Step(); ce.EqualityTest = t.Kind == Equal; } else if (laKind == CloseParenthesis) { Step(); ce.EndLocation = t.EndLocation; return ce; } /* TypeSpecialization: Type struct union class interface enum function delegate super const immutable inout shared return */ if (ce.EqualityTest && (ClassLike[laKind] || laKind==Typedef || // typedef is possible although it's not yet documented in the syntax docs laKind==Enum || laKind==Delegate || laKind==Function || laKind==Super || laKind==Return || ((laKind==Const || laKind == Immutable || laKind == InOut || laKind == Shared) && (Peek(1).Kind==CloseParenthesis || Lexer.CurrentPeekToken.Kind==Comma)))) { Step(); ce.TypeSpecializationToken = t.Kind; } else ce.TypeSpecialization = Type(); // TemplateParameterList if (laKind == Comma) { var ret = new List<TemplateParameter>(); do { Step(); ret.Add(TemplateParameter(null)); } while (laKind == Comma); ce.TemplateParameterList = ret.ToArray(); } Expect(CloseParenthesis); ce.EndLocation = t.EndLocation; return ce; } #endregion // NewExpression if (laKind == (New)) return NewExpression(Scope); // ( Expression ) if (laKind == OpenParenthesis) { Step(); var ret = new SurroundingParenthesesExpression() {Location=t.Location }; LastParsedObject = ret; ret.Expression = Expression(); Expect(CloseParenthesis); ret.EndLocation = t.EndLocation; return ret; } // TraitsExpression if (laKind == (__traits)) return TraitsExpression(); #region BasicType . Identifier if (IsBasicType()) { var startLoc = la.Location; var bt=BasicType(); if ((bt is TypeOfDeclaration || bt is MemberFunctionAttributeDecl) && laKind!=Dot) return new TypeDeclarationExpression(bt); // Things like incomplete 'float.' expressions shall be parseable, too if (Expect(Dot) && (Expect(Identifier) || IsEOF)) return new PostfixExpression_Access() { PostfixForeExpression = new TypeDeclarationExpression(bt), AccessExpression = string.IsNullOrEmpty(t.Value) ? null : new IdentifierExpression(t.Value) { Location=t.Location, EndLocation=t.EndLocation }, EndLocation = t.EndLocation }; return null; } #endregion SynErr(Identifier); if(laKind != CloseCurlyBrace) Step(); // Don't know why, in rare situations, t tends to be null.. if (t == null) return null; return new TokenExpression() { Location = t.Location, EndLocation = t.EndLocation }; }
/// <summary> /// Item1 - True, if isExpression returns true /// Item2 - If Item1 is true, it contains the type of the alias that is defined in the isExpression /// </summary> private Tuple<bool, AbstractType> evalIsExpression_EvalSpecToken(IsExpression isExpression, AbstractType typeToCheck, bool DoAliasHandling = false) { bool r = false; AbstractType res = null; switch (isExpression.TypeSpecializationToken) { /* * To handle semantic tokens like "return" or "super" it's just needed to * look into the current resolver context - * then, we'll be able to gather either the parent method or the currently scoped class definition. */ case DTokens.Struct: case DTokens.Union: case DTokens.Class: case DTokens.Interface: if (r = typeToCheck is UserDefinedType && ((TemplateIntermediateType)typeToCheck).Definition.ClassType == isExpression.TypeSpecializationToken) res = typeToCheck; break; case DTokens.Enum: if (!(typeToCheck is EnumType)) break; { var tr = (UserDefinedType)typeToCheck; r = true; res = tr.Base; } break; case DTokens.Function: case DTokens.Delegate: if (typeToCheck is DelegateType) { var isFun = false; var dgr = (DelegateType)typeToCheck; if (!dgr.IsFunctionLiteral) r = isExpression.TypeSpecializationToken == ( (isFun = ((DelegateDeclaration)dgr.DeclarationOrExpressionBase).IsFunction) ? DTokens.Function : DTokens.Delegate); // Must be a delegate otherwise else isFun = !(r = isExpression.TypeSpecializationToken == DTokens.Delegate); if (r) { //TODO if (isFun) { // TypeTuple of the function parameter types. For C- and D-style variadic functions, only the non-variadic parameters are included. // For typesafe variadic functions, the ... is ignored. } else { // the function type of the delegate } } } else // Normal functions are also accepted as delegates { r = isExpression.TypeSpecializationToken == DTokens.Delegate && typeToCheck is MemberSymbol && ((DSymbol)typeToCheck).Definition is DMethod; //TODO: Alias handling, same as couple of lines above } break; case DTokens.Super: //TODO: Test this var dc = DResolver.SearchClassLikeAt(ctxt.ScopedBlock, isExpression.Location) as DClassLike; if (dc != null) { var udt = DResolver.ResolveBaseClasses(new ClassType(dc, dc, null), ctxt, true) as ClassType; if (r = udt.Base != null && ResultComparer.IsEqual(typeToCheck, udt.Base)) { var l = new List<AbstractType>(); if (udt.Base != null) l.Add(udt.Base); if (udt.BaseInterfaces != null && udt.BaseInterfaces.Length != 0) l.AddRange(udt.BaseInterfaces); res = new DTuple(isExpression, l); } } break; case DTokens.Const: case DTokens.Immutable: case DTokens.InOut: // TODO? case DTokens.Shared: if (r = typeToCheck.Modifier == isExpression.TypeSpecializationToken) res = typeToCheck; break; case DTokens.Return: // TODO: Test IStatement _u = null; var dm = DResolver.SearchBlockAt(ctxt.ScopedBlock, isExpression.Location, out _u) as DMethod; if (dm != null) { var retType_ = TypeDeclarationResolver.GetMethodReturnType(dm, ctxt); if (r = retType_ != null && ResultComparer.IsEqual(typeToCheck, retType_)) res = retType_; } break; } return new Tuple<bool, AbstractType>(r, res); }
public override object Visit(Is isExpression) { var result = new IsExpression(); if (isExpression.Expr != null) result.AddChild((Expression)isExpression.Expr.Accept(this), Roles.Expression); result.AddChild(new CSharpTokenNode(Convert(isExpression.Location), IsExpression.IsKeywordRole), IsExpression.IsKeywordRole); if (isExpression.ProbeType != null) result.AddChild(ConvertToType(isExpression.ProbeType), Roles.Type); return result; }
public override void Visit(IsExpression x) { if (x.TypeAliasIdentifierHash == searchHash && symbol is TemplateParameter.Node && (symbol as TemplateParameter.Node).TemplateParameter == x.ArtificialFirstSpecParam) { l.Add (x.ArtificialFirstSpecParam); } base.Visit (x); }
public override object Visit (Is isExpression) { var result = new IsExpression (); result.AddChild ((INode)isExpression.Expr.Accept (this), IsExpression.Roles.Expression); result.AddChild (new CSharpTokenNode (Convert (isExpression.Location), "is".Length), IsExpression.Roles.Keyword); result.AddChild ((INode)isExpression.ProbeType.Accept (this), IsExpression.Roles.ReturnType); return result; }
public StringBuilder VisitIsExpression(IsExpression isExpression, int data) { throw new SLSharpException("SL# does not have reflection."); }
public CastBlock(IEmitter emitter, IsExpression isExpression) : base(emitter, isExpression) { this.Emitter = emitter; this.IsExpression = isExpression; }
public override void Visit (IsExpression x) { // is(Type | if (x.TypeAliasIdentifierHash == DTokens.IncompleteIdHash && x.TestedType != null && !IsIncompleteDeclaration(x.TestedType)) { halt = true; explicitlyNoCompletion = true; } else if (x.TypeSpecializationToken == DTokens.Incomplete) { prv = new CtrlSpaceCompletionProvider(cdgen, scopedBlock, MemberFilter.Types | MemberFilter.ExpressionKeywords | MemberFilter.StatementBlockKeywords); halt = true; } else base.Visit (x); }