public override Evaluation Analyze(UnaryEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; Evaluation result; switch (node.Operation) { case Operations.Print: case Operations.Clone: case Operations.ObjectCast: case Operations.ArrayCast: node.Expr = node.Expr.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); result = new Evaluation(node); break; default: Expression tmp; result = node.Expr.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Evaluate(node, out tmp); node.Expr = tmp; break; } return(result); }
public override Evaluation Analyze(AssertEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; // assertion: if (analyzer.Context.Config.Compiler.Debug) { Evaluation code_evaluation = node.CodeEx.Analyze(analyzer, ExInfoFromParent.DefaultExInfo); //Evaluation desc_evaluation = node.DescriptionEx.Analyze(analyzer, ExInfoFromParent.DefaultExInfo); // string parameter is parsed and converted to an expression: if (code_evaluation.HasValue) { _inlinedCode = Convert.ObjectToString(code_evaluation.Value); if (!string.IsNullOrEmpty(_inlinedCode)) { const string prefix = "return "; // the position of the last character before the parsed string: var statements = analyzer.BuildAst(node.CodeEx.Span.Start - prefix.Length + 1, String.Concat(prefix, _inlinedCode, ";")); // code is unevaluable: if (statements == null) { return(new Evaluation(node, true)); } if (statements.Length > 1) { analyzer.ErrorSink.Add(Warnings.MultipleStatementsInAssertion, analyzer.SourceUnit, node.Span); } Debug.Assert(statements.Length > 0 && statements[0] is JumpStmt); node.CodeEx = ((JumpStmt)statements[0]).Expression; } else { // empty assertion: return(new Evaluation(node, true)); } } else { node.CodeEx = code_evaluation.Expression; analyzer.AddCurrentRoutineProperty(RoutineProperties.ContainsEval); } // node.CodeEx = node.CodeEx.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); return(new Evaluation(node)); } else { // replace with "true" value in release mode: return(new Evaluation(node, true)); } }
public override Evaluation Analyze(NewEx node, Analyzer analyzer, ExInfoFromParent info) { Debug.Assert(node.IsMemberOf == null); access = info.Access; this.typeArgsResolved = TypeRefHelper.Analyze(node.ClassNameRef, analyzer); DType type = TypeRefHelper.ResolvedType(node.ClassNameRef); RoutineSignature signature; if (typeArgsResolved) { analyzer.AnalyzeConstructedType(type); } if (type != null) { bool error_reported = false; // make checks if we are sure about character of the type: if (type.IsIdentityDefinite) { if (type.IsAbstract || type.IsInterface) { analyzer.ErrorSink.Add(Errors.AbstractClassOrInterfaceInstantiated, analyzer.SourceUnit, node.Span, type.FullName); error_reported = true; } } // disallow instantiation of Closure if (type.RealType == typeof(PHP.Library.SPL.Closure)) { analyzer.ErrorSink.Add(Errors.ClosureInstantiated, analyzer.SourceUnit, node.Span, type.FullName); error_reported = true; } // type name resolved, look the constructor up: constructor = analyzer.ResolveConstructor(type, node.Span, analyzer.CurrentType, analyzer.CurrentRoutine, out runtimeVisibilityCheck); if (constructor.ResolveOverload(analyzer, node.CallSignature, node.Span, out signature) == DRoutine.InvalidOverloadIndex) { if (!error_reported) { analyzer.ErrorSink.Add(Errors.ClassHasNoVisibleCtor, analyzer.SourceUnit, node.Span, type.FullName); } } } else { signature = UnknownSignature.Default; } CallSignatureHelpers.Analyze(node.CallSignature, analyzer, signature, info, false); return(new Evaluation(node)); }
internal override void Analyze(Item node, Analyzer analyzer) { ExInfoFromParent info = new ExInfoFromParent(node); info.Access = AccessType.ReadRef; ((RefItem)node).RefToGet.Analyze(analyzer, info); base.Analyze(node, analyzer); }
public override Evaluation Analyze(EvalEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; node.Code = node.Code.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); analyzer.AddCurrentRoutineProperty(RoutineProperties.ContainsEval); return(new Evaluation(node)); }
public override Evaluation Analyze(T node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; TypeRefHelper.Analyze(node.TypeRef, analyzer); this.type = TypeRefHelper.ResolvedTypeOrUnknown(node.TypeRef); analyzer.AnalyzeConstructedType(type); return(new Evaluation(node)); }
public override Evaluation Analyze(IncDecEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; ExInfoFromParent var_info = new ExInfoFromParent(node); var_info.Access = AccessType.ReadAndWrite; node.Variable.Analyze(analyzer, var_info); return(new Evaluation(node)); }
public override Evaluation Analyze(ExitEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; if (node.ResulExpr != null) { node.ResulExpr = node.ResulExpr.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); } analyzer.EnterUnreachableCode(); return(new Evaluation(node)); }
public override Evaluation Analyze(IssetEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; var vars = node.VarList; for (int i = 0; i < vars.Count; i++) { vars[i].Analyze(analyzer, ExInfoFromParent.DefaultExInfo); } return(new Evaluation(node)); }
public void Analyze(StaticVarDecl /*!*/ node, Analyzer analyzer) { ExInfoFromParent sinfo = new ExInfoFromParent(node); sinfo.Access = AccessType.WriteRef; node.Variable.Analyze(analyzer, sinfo); if (node.Initializer != null) { node.Initializer = node.Initializer.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); } }
public override Evaluation Analyze(EmptyEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; var expression = node.Expression; var evaluation = expression .Analyze(analyzer, ExInfoFromParent.DefaultExInfo) .Evaluate(node, out expression); node.Expression = expression; return(evaluation); }
public override Evaluation Analyze(TypeOfEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; typeArgsResolved = TypeRefHelper.Analyze(node.ClassNameRef, analyzer); if (typeArgsResolved) { analyzer.AnalyzeConstructedType(TypeRefHelper.ResolvedType(node.ClassNameRef)); } return(new Evaluation(node)); }
public override Evaluation Analyze(ArrayEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; foreach (var i in node.Items) { if (i != null) { i.NodeCompiler <ItemCompiler>().Analyze(i, analyzer); } } return(new Evaluation(node)); }
public void Analyze(CatchItem /*!*/ node, Analyzer /*!*/ analyzer) { ExInfoFromParent info = new ExInfoFromParent(node); info.Access = AccessType.Write; resolvedType = analyzer.ResolveTypeName(node.ClassName, analyzer.CurrentType, analyzer.CurrentRoutine, node.Span, false); node.Variable.Analyze(analyzer, info); analyzer.EnterConditionalCode(); node.Statements.Analyze(analyzer); analyzer.LeaveConditionalCode(); }
public override Evaluation Analyze(InstanceOfEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; node.Expression = node.Expression.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); typeArgsResolved = TypeRefHelper.Analyze(node.ClassNameRef, analyzer); if (typeArgsResolved) { analyzer.AnalyzeConstructedType(TypeRefHelper.ResolvedType(node.ClassNameRef)); } return(new Evaluation(node)); }
public override Evaluation Analyze(IncludingEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; // if the expression should be emitted: if (characteristic == Characteristic.Dynamic || characteristic == Characteristic.StaticArgEvaluated) { node.Target = node.Target.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); } analyzer.AddCurrentRoutineProperty(RoutineProperties.ContainsInclude); analyzer.CurrentScope = node.Scope; return(new Evaluation(node)); }
public void Analyze(ForeachVar /*!*/ node, Analyzer analyzer) { ExInfoFromParent info = new ExInfoFromParent(node); if (node.Alias) { info.Access = AccessType.WriteRef; } else { info.Access = AccessType.Write; } // retval not needed node.Expression.Analyze(analyzer, info); }
internal override Statement Analyze(ForStmt node, Analyzer analyzer) { if (analyzer.IsThisCodeUnreachable()) { analyzer.ReportUnreachableCode(node.Span); return(EmptyStmt.Unreachable); } ExInfoFromParent info = new ExInfoFromParent(node); info.Access = AccessType.None; var initExList = node.InitExList; for (int i = 0; i < initExList.Count; i++) { initExList[i] = initExList[i].Analyze(analyzer, info).Literalize(); } var condExList = node.CondExList; if (condExList.Count > 0) { // all but the last expression is evaluated and the result is ignored (AccessType.None), // the last is read: for (int i = 0; i < condExList.Count - 1; i++) { condExList[i] = condExList[i].Analyze(analyzer, info).Literalize(); } condExList[condExList.Count - 1] = condExList[condExList.Count - 1].Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); } var actionExList = node.ActionExList; for (int i = 0; i < actionExList.Count; i++) { actionExList[i] = actionExList[i].Analyze(analyzer, info).Literalize(); } analyzer.EnterLoopBody(); node.Body = node.Body.Analyze(analyzer); analyzer.LeaveLoopBody(); return(node); }
public override Evaluation Analyze(ItemUse node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; // checks for write context of key-less array operator ($a =& $x[] is ok): if (node.Index == null && (access == AccessType.Read || access == AccessType.ReadAndWrite || access == AccessType.ReadAndWriteAndReadRef || access == AccessType.ReadAndWriteAndReadUnknown)) { analyzer.ErrorSink.Add(Errors.EmptyIndexInReadContext, analyzer.SourceUnit, node.Span); return(new Evaluation(node)); } base.Analyze(node, analyzer, info); ExInfoFromParent sinfo = new ExInfoFromParent(node); switch (info.Access) { case AccessType.Write: case AccessType.WriteRef: case AccessType.ReadRef: sinfo.Access = AccessType.Write; break; case AccessType.ReadAndWriteAndReadRef: case AccessType.WriteAndReadRef: case AccessType.ReadAndWrite: sinfo.Access = AccessType.ReadAndWrite; break; case AccessType.WriteAndReadUnknown: case AccessType.ReadAndWriteAndReadUnknown: sinfo.Access = info.Access; break; case AccessType.ReadUnknown: sinfo.Access = AccessType.ReadUnknown; break; default: sinfo.Access = AccessType.Read; break; } ((ItemUse)node).Array.Analyze(analyzer, sinfo); if (node.Index != null) { node.Index = node.Index.Analyze(analyzer, ExInfoFromParent.DefaultExInfo).Literalize(); } return(new Evaluation(node)); }
public override Evaluation Analyze(ConcatEx node, Analyzer analyzer, ExInfoFromParent info) { Debug.Assert(node.Expressions.Length > 0); access = info.Access; var concatChunks = AnalyzeChunks(analyzer, node.Expressions); node.Expressions = ChunkExpressions(concatChunks).ToArray(); // replace expressions with optimized one if (concatChunks.Count == 1 && concatChunks[0].HasValue) { return(new Evaluation(node, concatChunks[0].Value)); // can be resolved during compilation time } else { return(new Evaluation(node)); } }
internal override Statement Analyze(GlobalStmt node, Analyzer analyzer) { if (analyzer.IsThisCodeUnreachable()) { analyzer.ReportUnreachableCode(node.Span); return(EmptyStmt.Unreachable); } ExInfoFromParent info = new ExInfoFromParent(node); info.Access = AccessType.WriteRef; foreach (SimpleVarUse svu in node.VarList) { svu.Analyze(analyzer, info); } return(node); }
internal override Core.AST.Statement Analyze(EchoStmt node, Analyzer analyzer) { if (analyzer.IsThisCodeUnreachable()) { analyzer.ReportUnreachableCode(node.Span); return(EmptyStmt.Unreachable); } ExInfoFromParent info = ExInfoFromParent.DefaultExInfo; var parameters = node.Parameters; for (int i = 0; i < parameters.Length; i++) { parameters[i] = parameters[i].Analyze(analyzer, info).Literalize(); } return(node); }
public void Analyze(GlobalCode /*!*/ ast, Analyzer /*!*/ analyzer) { analyzer.LeaveUnreachableCode(); ExInfoFromParent info = new ExInfoFromParent(ast); // analyze auto-prepended inclusion (no code reachability checks): if (PrependedInclusion != null) { info.Access = AccessType.None; PrependedInclusion.Analyze(analyzer, info); } for (int i = 0; i < ast.Statements.Length; i++) // NOTE: ast.Statements may change during analysis, iterate in this way! { if (analyzer.IsThisCodeUnreachable() && ast.Statements[i].IsDeclaration) { //unreachable declarations in global code are valid analyzer.LeaveUnreachableCode(); ast.Statements[i] = ast.Statements[i].Analyze(analyzer); analyzer.EnterUnreachableCode(); } else { ast.Statements[i] = ast.Statements[i].Analyze(analyzer); } } if (!ast.SourceUnit.IsPure) { Analyzer.ValidateLabels(analyzer.ErrorSink, ast.SourceUnit, labels); } // analyze auto-prepended inclusion (no code reachability checks): if (AppendedInclusion != null) { info.Access = AccessType.Read; AppendedInclusion.Analyze(analyzer, info); } analyzer.LeaveUnreachableCode(); }
internal override Statement Analyze(JumpStmt node, Analyzer analyzer) { if (analyzer.IsThisCodeUnreachable()) { analyzer.ReportUnreachableCode(node.Span); return(EmptyStmt.Unreachable); } if (node.Expression != null) { ExInfoFromParent sinfo = ExInfoFromParent.DefaultExInfo; if (node.Type == JumpStmt.Types.Return && analyzer.CurrentRoutine != null && analyzer.CurrentRoutine.Signature.AliasReturn && node.Expression is VarLikeConstructUse) { sinfo.Access = AccessType.ReadRef; } node.Expression = node.Expression.Analyze(analyzer, sinfo).Literalize(); if (node.Type != JumpStmt.Types.Return && node.Expression.HasValue()) { int level = Convert.ObjectToInteger(node.Expression.GetValue()); if (level > analyzer.LoopNestingLevel || level < 0) { analyzer.ErrorSink.Add(Errors.InvalidBreakLevelCount, analyzer.SourceUnit, node.Span, level); } } } else if (node.Type != JumpStmt.Types.Return && analyzer.LoopNestingLevel == 0) { analyzer.ErrorSink.Add(Errors.InvalidBreakLevelCount, analyzer.SourceUnit, node.Span, 1); } // code in the same block after return, break, continue is unreachable analyzer.EnterUnreachableCode(); return(node); }
public override Evaluation Analyze(BinaryEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; ExInfoFromParent operand_info = ExInfoFromParent.DefaultExInfo; Evaluation left_eval = node.LeftExpr.Analyze(analyzer, operand_info); Evaluation right_eval; // Boolean expression evaluation semantics: if (node.Operation == Operations.Or) { analyzer.EnterConditionalCode(); right_eval = node.RightExpr.Analyze(analyzer, operand_info); analyzer.LeaveConditionalCode(); } else { right_eval = node.RightExpr.Analyze(analyzer, operand_info); } Expression rightTmp, leftTmp; Evaluation result = Evaluation.Evaluate(node, left_eval, out leftTmp, right_eval, out rightTmp); node.LeftExpr = leftTmp; node.RightExpr = rightTmp; // division by zero check: if ((node.Operation == Operations.Div || node.Operation == Operations.Mod) && result.HasValue && result.Value is bool && (bool)result.Value == false) { analyzer.ErrorSink.Add(Warnings.DivisionByZero, analyzer.SourceUnit, node.RightExpr.Span); } else if ((node.Operation == Operations.Div || node.Operation == Operations.Mod) && right_eval.HasValue && right_eval.Value is int && (int)right_eval.Value == 0) { result = new Evaluation(node, false); analyzer.ErrorSink.Add(Warnings.DivisionByZero, analyzer.SourceUnit, node.RightExpr.Span); } return(result); }
public override Evaluation Analyze(T node, Analyzer analyzer, ExInfoFromParent info) { bool already_resolved = constant != null; if (!already_resolved) { access = info.Access; ResolveName(node, analyzer); } if (constant.IsUnknown) { return(new Evaluation(node)); } KnownConstant known_const = (KnownConstant)constant; if (known_const.HasValue) { // constant value is known: return(new Evaluation(node, known_const.Value)); } else if (already_resolved) { // circular definition: constant.ReportCircularDefinition(analyzer.ErrorSink); return(new Evaluation(node)); } else { // value is not known yet, try to resolve it: if (known_const.Node != null) { known_const.Node.Analyze(analyzer); } return((known_const.HasValue) ? new Evaluation(node, known_const.Value) : new Evaluation(node)); } }
public override Evaluation Analyze(AssignEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; ExInfoFromParent lvalue_info = new ExInfoFromParent(node); ExInfoFromParent rvalue_info = new ExInfoFromParent(node); lvalue_info.Access = AccessType.WriteRef; rvalue_info.Access = AccessType.ReadRef; var refassignex = (RefAssignEx)node; node.lvalue = (VariableUse)node.LValue.Analyze(analyzer, lvalue_info).Expression; refassignex.rvalue = refassignex.RValue.Analyze(analyzer, rvalue_info).Literalize(); if (refassignex.RValue is NewEx) { //PhpException.Throw(PhpError.Deprecated, CoreResources.GetString("assign_new_as_ref_is_deprecated")); analyzer.ErrorSink.Add(Warnings.AssignNewByRefDeprecated, analyzer.SourceUnit, node.Span); } return(new Evaluation(node)); }
internal override Statement Analyze(ExpressionStmt node, Analyzer analyzer) { if (analyzer.IsThisCodeUnreachable()) { analyzer.ReportUnreachableCode(node.Span); return(EmptyStmt.Unreachable); } ExInfoFromParent info = new ExInfoFromParent(node); info.Access = AccessType.None; Evaluation expr_eval = node.Expression.Analyze(analyzer, info); // skip statement if it is evaluable (has no side-effects): if (expr_eval.HasValue) { return(EmptyStmt.Skipped); } node.Expression = expr_eval.Expression; return(node); }
public override Evaluation Analyze(ListEx node, Analyzer analyzer, ExInfoFromParent info) { access = info.Access; ExInfoFromParent sinfo = new ExInfoFromParent(node); // r-value if (node.RValue != null) { node.RValue = node.RValue.Analyze(analyzer, sinfo).Literalize(); } // l-values sinfo.Access = AccessType.Write; for (int i = 0; i < node.LValues.Count; i++) { if (node.LValues[i] != null) { node.LValues[i] = node.LValues[i].Analyze(analyzer, sinfo).Expression; } } return(new Evaluation(node)); }
public static void Analyze(this CallSignature /*!*/ node, Analyzer /*!*/ analyzer, RoutineSignature /*!*/ signature, ExInfoFromParent info, bool isBaseCtorCallConstrained) { node.NodeCompiler <ICallSignatureCompiler>().Analyze(node, analyzer, signature, info, isBaseCtorCallConstrained); }