public BoundStatement BindStatement(AST.Statement stmt) { Debug.Assert(stmt != null); if (stmt is AST.EchoStmt) return new BoundExpressionStatement(new BoundEcho(BindArguments(((AST.EchoStmt)stmt).Parameters))) { PhpSyntax = stmt }; if (stmt is AST.ExpressionStmt) return new BoundExpressionStatement(BindExpression(((AST.ExpressionStmt)stmt).Expression, BoundAccess.None)) { PhpSyntax = stmt }; if (stmt is AST.JumpStmt) return BindJumpStmt((AST.JumpStmt)stmt); if (stmt is AST.FunctionDecl) return new BoundFunctionDeclStatement(stmt.GetProperty<SourceFunctionSymbol>()); // see SourceDeclarations.PopulatorVisitor if (stmt is AST.TypeDecl) return new BoundTypeDeclStatement(stmt.GetProperty<SourceTypeSymbol>()); // see SourceDeclarations.PopulatorVisitor if (stmt is AST.GlobalStmt) return new BoundGlobalVariableStatement( ((AST.GlobalStmt)stmt).VarList.Cast<AST.DirectVarUse>() .Select(s => (BoundGlobalVariable)_locals.BindVariable(s.VarName, VariableKind.GlobalVariable, null)) .ToImmutableArray()); if (stmt is AST.StaticStmt) return new BoundStaticVariableStatement( ((AST.StaticStmt)stmt).StVarList .Select(s => (BoundStaticLocal)_locals.BindVariable(s.Variable, VariableKind.StaticVariable, () => (s.Initializer != null ? BindExpression(s.Initializer) : null))) .ToImmutableArray()) { PhpSyntax = stmt }; if (stmt is AST.UnsetStmt) return new BoundUnset( ((AST.UnsetStmt)stmt).VarList .Select(v => (BoundReferenceExpression)BindExpression(v, BoundAccess.Unset)) .ToImmutableArray()) { PhpSyntax = stmt }; if (stmt is AST.ThrowStmt) return new BoundThrowStatement(BindExpression(((AST.ThrowStmt)stmt).Expression, BoundAccess.Read)) { PhpSyntax = stmt }; if (stmt is AST.PHPDocStmt) return new BoundEmptyStatement(); throw new NotImplementedException(stmt.GetType().FullName); }
BoundRoutineCall BindFunctionCall(AST.FunctionCall x, BoundAccess access) { if (!access.IsRead && !access.IsNone) { throw new NotSupportedException(); } var boundinstance = (x.IsMemberOf != null) ? BindExpression(x.IsMemberOf, BoundAccess.Read/*Object?*/) : null; var boundargs = BindArguments(x.CallSignature.Parameters); if (x is AST.DirectFcnCall) { var f = (AST.DirectFcnCall)x; var fname = f.FullName; if (f.IsMemberOf == null) { return new BoundGlobalFunctionCall(fname.Name, fname.FallbackName, boundargs) .WithAccess(access); } else { Debug.Assert(fname.FallbackName.HasValue == false); Debug.Assert(fname.Name.QualifiedName.IsSimpleName); return new BoundInstanceFunctionCall(boundinstance, fname.Name, boundargs) .WithAccess(access); } } else if (x is AST.IndirectFcnCall) { var f = (AST.IndirectFcnCall)x; var nameExpr = BindExpression(f.NameExpr); return ((f.IsMemberOf == null) ? (BoundRoutineCall)new BoundGlobalFunctionCall(nameExpr, boundargs) : new BoundInstanceFunctionCall(boundinstance, new BoundUnaryEx(nameExpr, AST.Operations.StringCast), boundargs)) .WithAccess(access); } else if (x is AST.StaticMtdCall) { var f = (AST.StaticMtdCall)x; Debug.Assert(f.IsMemberOf == null); var boundname = (f is AST.DirectStMtdCall) ? new BoundRoutineName(new QualifiedName(((AST.DirectStMtdCall)f).MethodName)) : new BoundRoutineName(new BoundUnaryEx(BindExpression(((AST.IndirectStMtdCall)f).MethodNameVar), AST.Operations.StringCast)); return new BoundStaticFunctionCall(BindTypeRef(f.TargetType), boundname, boundargs) .WithAccess(access); } // throw new NotImplementedException(x.GetType().FullName); }
BoundExpression BindVarLikeConstructUse(AST.VarLikeConstructUse expr, BoundAccess access) { if (expr is AST.SimpleVarUse) return BindSimpleVarUse((AST.SimpleVarUse)expr, access); if (expr is AST.FunctionCall) return BindFunctionCall((AST.FunctionCall)expr, access); if (expr is AST.NewEx) return BindNew((AST.NewEx)expr, access); if (expr is AST.ArrayEx) return BindArrayEx((AST.ArrayEx)expr, access); if (expr is AST.ItemUse) return BindItemUse((AST.ItemUse)expr, access); if (expr is AST.StaticFieldUse) return BindFieldUse((AST.StaticFieldUse)expr, access); if (expr is AST.ListEx) return BindListEx((AST.ListEx)expr).WithAccess(access); throw new NotImplementedException(expr.GetType().FullName); }
BoundExpression BindExpressionCore(AST.Expression expr, BoundAccess access) { Debug.Assert(expr != null); if (expr is AST.Literal) return BindLiteral((AST.Literal)expr).WithAccess(access); if (expr is AST.ConstantUse) return BindConstUse((AST.ConstantUse)expr).WithAccess(access); if (expr is AST.VarLikeConstructUse) return BindVarLikeConstructUse((AST.VarLikeConstructUse)expr, access); if (expr is AST.BinaryEx) return BindBinaryEx((AST.BinaryEx)expr).WithAccess(access); if (expr is AST.AssignEx) return BindAssignEx((AST.AssignEx)expr, access); if (expr is AST.UnaryEx) return BindUnaryEx((AST.UnaryEx)expr, access); if (expr is AST.IncDecEx) return BindIncDec((AST.IncDecEx)expr).WithAccess(access); if (expr is AST.ConditionalEx) return BindConditionalEx((AST.ConditionalEx)expr).WithAccess(access); if (expr is AST.ConcatEx) return BindConcatEx((AST.ConcatEx)expr).WithAccess(access); if (expr is AST.IncludingEx) return BindIncludeEx((AST.IncludingEx)expr).WithAccess(access); if (expr is AST.InstanceOfEx) return BindInstanceOfEx((AST.InstanceOfEx)expr).WithAccess(access); if (expr is AST.PseudoConstUse) return BindPseudoConst((AST.PseudoConstUse)expr).WithAccess(access); if (expr is AST.IssetEx) return BindIsSet((AST.IssetEx)expr).WithAccess(access); if (expr is AST.ExitEx) return BindExitEx((AST.ExitEx)expr).WithAccess(access); if (expr is AST.EmptyEx) return BindIsEmptyEx((AST.EmptyEx)expr).WithAccess(access); throw new NotImplementedException(expr.GetType().FullName); }