示例#1
0
        /// <summary>
        /// Try to find constant by given <paramref name="name"/> in compile time.
        /// </summary>
        /// <param name="analyzer">Actual <see cref="Analyzer"/>.</param>
        /// <param name="name">Constant name, including class constants.</param>
        /// <param name="exists">Outputs <c>true</c> or <c>false</c> if the existance of the constant was determined.</param>
        /// <returns>Constant descriptor.</returns>
        private static PHP.Core.Reflection.DConstant EvaluateConstant(Analyzer analyzer, string name, out bool? exists)
        {
            if (name == null)
                name = string.Empty;

            // try global constant:
            QualifiedName? alias;
            var constant = analyzer.SourceUnit.ResolveConstantName(new QualifiedName(new Name(name)), analyzer.CurrentScope, out alias, null, PHP.Core.Parsers.Position.Invalid, false);

            if (constant != null)
            {
                exists = true;  // we surely know, the constant is defined.
                return constant;
            }
            
            // try class constant:
            string typename, constname;
            if (Name.IsClassMemberSyntax(name, out typename, out constname))
            {
                var type = analyzer.SourceUnit.ResolveTypeName(new QualifiedName(new Name(typename)), analyzer.CurrentScope, out alias, null, PHP.Core.Parsers.Position.Invalid, false);

                if (type != null && !type.IsUnknown)
                {
                    Core.Reflection.ClassConstant classconst;
                    type.GetConstant(new VariableName(constname), null /* class constants are global only */, out classconst);
                    Debug.Assert(classconst == null || classconst.IsPublic, "Class constant are expected to be public only.");
                    exists = (classconst != null);  // we surely know, wheter the constant is or is not defined.
                    return classconst;
                }
            }

            // special constants defined in runtime, but definitely defined:
            if (name == "PHALANGER")
            {
                exists = true;
                return null;
            }

            // do not evaluate in compile time
            exists = null;   // we are not sure about existance of this constant.
            return null;
        }
示例#2
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Statement.Analyze"]/*'/>
		internal override Statement/*!*/ Analyze(Analyzer/*!*/ analyzer)
		{
			if (analyzer.IsThisCodeUnreachable())
			{
				analyzer.ReportUnreachableCode(position);
				return EmptyStmt.Unreachable;
			}

			Evaluation cond_eval = condExpr.Analyze(analyzer, ExInfoFromParent.DefaultExInfo);

			if (cond_eval.HasValue)
			{
				if (Convert.ObjectToBoolean(cond_eval.Value))
				{
					// unbounded loop:
					condExpr = null;
				}
				else
				{
					// unreachable body:
					if (type == Type.While)
					{
						body.ReportUnreachable(analyzer);
						return EmptyStmt.Unreachable;
					}
				}
			}

			condExpr = cond_eval.Literalize();

			analyzer.EnterLoopBody();
			body = body.Analyze(analyzer);
			analyzer.LeaveLoopBody();

			return this;
		}
示例#3
0
		internal void AnalyzeDocComment(Analyzer/*!*/ analyzer, XmlDocFileBuilder/*!*/ builder)
		{
			// TODO
		}
示例#4
0
        public static PHP.Core.Compiler.AST.FunctionCallEvaluateInfo Defined_Analyze(Analyzer analyzer, string name)
        {
            bool? exists;
            var constant = EvaluateConstant(analyzer, name, out exists);

            if (exists != null)
                return new Core.Compiler.AST.FunctionCallEvaluateInfo()
                {
                    value = exists.Value    // constant existance is known in compile time
                };

            // check in run time:
            return null;
        }
示例#5
0
        public static PHP.Core.Compiler.AST.FunctionCallEvaluateInfo Exists_Analyze(Analyzer analyzer, string name)
        {
            QualifiedName? alias;

            DRoutine routine = analyzer.SourceUnit.ResolveFunctionName(
                new QualifiedName(new Name(name)),
                analyzer.CurrentScope,
                out alias,
                null,
                PHP.Core.Parsers.Position.Invalid,
                false);

            if (routine == null || routine.IsUnknown)
                return null;  // function is not known at the compilation time. However it can be defined at the runtime (dynamic include, script library, etc).

            return new PHP.Core.Compiler.AST.FunctionCallEvaluateInfo()
            {
                value = true    // function is definitely known the the compilation time
            };
        }
示例#6
0
        public static PHP.Core.Compiler.AST.FunctionCallEvaluateInfo GetParentClass_Analyze(Analyzer analyzer, string name)
        {
            QualifiedName? alias;

            DType type = analyzer.SourceUnit.ResolveTypeName(
                new QualifiedName(new Name(name)),
                analyzer.CurrentScope,
                out alias,
                null,
                PHP.Core.Parsers.Position.Invalid,
                false);

            if (type == null || type.IsUnknown)
                return null;  // type is not known at the compilation time. However it can be defined at the runtime (dynamic include, script library, etc).

            // type is definitely known the the compilation time
            var parent_type = type.Base;
            return new PHP.Core.Compiler.AST.FunctionCallEvaluateInfo()
            {
                value = (parent_type == null ? null : parent_type.FullName)
            };
        }
示例#7
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Statement.Analyze"]/*'/>
		internal override Statement/*!*/ Analyze(Analyzer/*!*/ analyzer)
		{
			if (analyzer.IsThisCodeUnreachable())
			{
				analyzer.ReportUnreachableCode(position);
				return EmptyStmt.Unreachable;
			}

			ExInfoFromParent info = ExInfoFromParent.DefaultExInfo;

			Statement result = this;
			bool is_first = true;
			int remaining = conditions.Count;
			int last_non_null = -1;

			for (int i = 0; i < conditions.Count; i++)
			{
				// "else":
				if (conditions[i].Condition == null)
				{
					Debug.Assert(i > 0);

					if (!is_first) analyzer.EnterConditionalCode();
					conditions[i].Statement = conditions[i].Statement.Analyze(analyzer);
					if (!is_first) analyzer.LeaveConditionalCode();
					last_non_null = i;

					break;
				}

				// all but the condition before the first non-evaluable including are conditional:
				if (!is_first) analyzer.EnterConditionalCode();
				Evaluation cond_eval = conditions[i].Condition.Analyze(analyzer, info);
				if (!is_first) analyzer.LeaveConditionalCode();

				if (cond_eval.HasValue)
				{
					if (Convert.ObjectToBoolean(cond_eval.Value))
					{
						// condition is evaluated to be true //

						// analyze the first statement unconditionally, the the others conditionally:
						if (!is_first) analyzer.EnterConditionalCode();
						conditions[i].Statement = conditions[i].Statement.Analyze(analyzer);
						if (!is_first) analyzer.LeaveConditionalCode();

						// the remaining conditions are unreachable:
						for (int j = i + 1; j < conditions.Count; j++)
						{
							conditions[j].Statement.ReportUnreachable(analyzer);
							conditions[j] = null;
							remaining--;
						}

						conditions[i].Condition = null;
						last_non_null = i;

						break;
					}
					else
					{
						// condition is evaluated to be false //

						// remove the condition, report unreachable code:
						conditions[i].Statement.ReportUnreachable(analyzer);
						conditions[i] = null;
						remaining--;
					}
				}
				else
				{
					// condition is not evaluable:
					conditions[i].Condition = cond_eval.Expression;

					// analyze statement conditinally:
					analyzer.EnterConditionalCode();
                    conditions[i].Statement = conditions[i].Statement.Analyze(analyzer);
					analyzer.LeaveConditionalCode();

					is_first = false;
					last_non_null = i;
				}
			}

			if (remaining == 0)
				return EmptyStmt.Skipped;

			Debug.Assert(last_non_null != -1 && conditions[last_non_null] != null);

			// only "else" remained:
			if (remaining == 1 && conditions[last_non_null].Condition == null)
				return conditions[last_non_null].Statement;

			// compact the list (remove nulls):
			if (remaining < conditions.Count)
			{
				List<ConditionalStmt> compacted = new List<ConditionalStmt>(remaining);
				foreach (ConditionalStmt condition in conditions)
				{
					if (condition != null)
						compacted.Add(condition);
				}
				conditions = compacted;
			}

			return this;
		}
示例#8
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Statement.Analyze"]/*'/>
		internal override Statement/*!*/ Analyze(Analyzer/*!*/ analyzer)
		{
			if (analyzer.IsThisCodeUnreachable())
			{
				analyzer.ReportUnreachableCode(position);
				return EmptyStmt.Unreachable;
			}

			//next version: array.SetSeqPoint();
			enumeree.Analyze(analyzer, ExInfoFromParent.DefaultExInfo);
			if (keyVariable != null) keyVariable.Analyze(analyzer);
			valueVariable.Analyze(analyzer);

			analyzer.EnterLoopBody();
			body = body.Analyze(analyzer);
			analyzer.LeaveLoopBody();
			return this;
		}
示例#9
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Statement.Analyze"]/*'/>
		internal override Statement Analyze(Analyzer analyzer)
		{
			if (analyzer.IsThisCodeUnreachable())
			{
				analyzer.ReportUnreachableCode(position);
				return EmptyStmt.Unreachable;
			}

			ExInfoFromParent info = new ExInfoFromParent(this);

			info.Access = AccessType.None;

			for (int i = 0; i < initExList.Count; i++)
			{
				initExList[i] = initExList[i].Analyze(analyzer, info).Literalize();
			}

			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();
			}

			for (int i = 0; i < actionExList.Count; i++)
			{
				actionExList[i] = actionExList[i].Analyze(analyzer, info).Literalize();
			}

			analyzer.EnterLoopBody();
			body = body.Analyze(analyzer);
			analyzer.LeaveLoopBody();

			return this;
		}
示例#10
0
		internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position,
			out RoutineSignature overloadSignature)
		{
			if (callSignature.GenericParams.Count > 0)
			{
				analyzer.ErrorSink.Add(Errors.GenericCallToLibraryFunction, analyzer.SourceUnit, position);
				callSignature = new CallSignature(callSignature.Parameters, TypeRef.EmptyList);
			}

			bool exact_match;
			int result = ResolveOverload(callSignature.Parameters.Count, out exact_match);

			if (!exact_match)
			{
				// library function with wrong number of actual arguments:
				analyzer.ErrorSink.Add(Errors.InvalidArgumentCountForFunction, analyzer.SourceUnit, position, FullName);
			}

			overloadSignature = overloads[result];
			return result;
		}
示例#11
0
		/// <summary>
		/// Finds most suitable overload. Returns <see cref="InvalidOverloadIndex"/> and 
		/// <see cref="UnknownSignature.Default"/> in <c>overloadSignature</c> if no suitable overload exists.
		/// </summary>
		internal abstract int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position,
			out RoutineSignature overloadSignature);
示例#12
0
		internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position,
			out RoutineSignature overloadSignature)
		{
			if (callSignature.Parameters.Count < signature.MandatoryParamCount)
			{
				if (IsConstructor)
				{
					analyzer.ErrorSink.Add(Warnings.TooFewCtorParameters, analyzer.SourceUnit, position,
						DeclaringType.FullName, signature.MandatoryParamCount, callSignature.Parameters.Count);
				}
				else if (IsStatic)
				{
					analyzer.ErrorSink.Add(Warnings.TooFewMethodParameters, analyzer.SourceUnit, position,
						DeclaringType.FullName, this.FullName, signature.MandatoryParamCount.ToString(),
			callSignature.Parameters.Count.ToString());
				}
			}

			overloadSignature = signature;
			return 0;
		}
示例#13
0
		internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position,
			out RoutineSignature overloadSignature)
		{
			if (callSignature.Parameters.Count < signature.MandatoryParamCount)
			{
				analyzer.ErrorSink.Add(Warnings.TooFewFunctionParameters, analyzer.SourceUnit, position,
					qualifiedName, signature.MandatoryParamCount, callSignature.Parameters.Count);
			}

			overloadSignature = signature;
			return 0;
		}
示例#14
0
        public static PHP.Core.AST.DirectFcnCall.EvaluateInfo ClassExists_Analyze_1(Analyzer analyzer, string name)
        {
            QualifiedName? alias;

            DType type = analyzer.SourceUnit.ResolveTypeName(
                new QualifiedName(new Name(name)),
                analyzer.CurrentScope,
                out alias,
                null,
                PHP.Core.Parsers.Position.Invalid,
                false);

            if (type == null || type.IsUnknown)
                return null;  // type is not known at the compilation time. However it can be defined at the runtime (dynamic include, script library, etc).

            return new PHP.Core.AST.DirectFcnCall.EvaluateInfo()
            {
                value = true    // type is definitely known the the compilation time
            };
        }
示例#15
0
        public static PHP.Core.Compiler.AST.FunctionCallEvaluateInfo Constant_Analyze(Analyzer analyzer, string name)
        {
            bool? exists;
            var constant = EvaluateConstant(analyzer, name, out exists);

            if (constant != null && constant.HasValue)
                return new Core.Compiler.AST.FunctionCallEvaluateInfo()
                {
                    value = constant.Value  // evaluated value in compile time
                };

            // check in run time:
            return null;
        }
示例#16
0
        internal override void Analyze(Analyzer analyzer)
        {
            if (!this.analyzed)
            {
                base.Analyze(analyzer);

                // check some special constants (ignoring namespace)
                if (this.Name.Value == GlobalConstant.Null.FullName ||
                    this.Name.Value == GlobalConstant.False.FullName ||
                    this.Name.Value == GlobalConstant.True.FullName)
                    analyzer.ErrorSink.Add(FatalErrors.ConstantRedeclared, analyzer.SourceUnit, Position, this.Name.Value);
            }
        }
示例#17
0
		internal void Analyze(Analyzer/*!*/ analyzer)
		{
			analyzer.LeaveUnreachableCode();
			
			ExInfoFromParent info = new ExInfoFromParent(this);

			// analyze auto-prepended inclusion (no code reachability checks):
			if (prependedInclusion != null)
			{
				info.Access = AccessType.None;
				prependedInclusion.Analyze(analyzer, info);
			}

			for (int i = 0; i < statements.Count; i++)
			{
				if (analyzer.IsThisCodeUnreachable() && statements[i].IsDeclaration)
				{
					//unreachable declarations in global code are valid
					analyzer.LeaveUnreachableCode();
					statements[i] = statements[i].Analyze(analyzer);
					analyzer.EnterUnreachableCode();
				}
				else
				{
					statements[i] = statements[i].Analyze(analyzer);
				}
			}

			if (!sourceUnit.CompilationUnit.IsPure)
				Analyzer.ValidateLabels(analyzer.ErrorSink, sourceUnit, labels);

			// analyze auto-prepended inclusion (no code reachability checks):
			if (appendedInclusion != null)
			{
				info.Access = AccessType.Read;
				appendedInclusion.Analyze(analyzer, info);
			}

			analyzer.LeaveUnreachableCode();
		}
示例#18
0
		internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position,
			out RoutineSignature/*!*/ overloadSignature)
		{
			if (overloads.Count == 0)
			{
				if (DeclaringType.TypeDesc is ClrDelegateDesc)
				{
					overloadSignature = UnknownSignature.Delegate;
					return 0;
				}

				// structures without ctor:
				if (DeclaringType.TypeDesc.RealType.IsValueType)
				{
					overloadSignature = UnknownSignature.Default;
					return 0;
				}

				Debug.Assert(this.IsConstructor, "Only constructors can have no overload.");
				overloadSignature = UnknownSignature.Default;
				return DRoutine.InvalidOverloadIndex;
			}

			int i = 0;
			bool found = false;

			Overload overload;
			while (i < overloads.Count && (overload = overloads[i]).MandatoryParamCount <= callSignature.Parameters.Count)
			{
				if (overload.MandatoryParamCount == callSignature.Parameters.Count ||
					(overload.Flags & OverloadFlags.IsVararg) != 0)
				{
					found = true;
					break;
				}

				i++;
			}

			// TODO: by type resolving
			// evaluate arguments?

			if (!found)
			{
				analyzer.ErrorSink.Add(Warnings.InvalidArgumentCountForMethod, analyzer.SourceUnit, position,
					this.DeclaringType.FullName, this.FullName);

				if (i > 0) i--;
				overloadSignature = overloads[i];
				return i;
			}

			overloadSignature = overloads[i];
			return i;
		}
示例#19
0
		internal void Analyze(Analyzer analyzer)
		{
			ExInfoFromParent info = new ExInfoFromParent(this);
			if (alias) info.Access = AccessType.WriteRef;
			else info.Access = AccessType.Write;

			//retval not needed
			variable.Analyze(analyzer, info);
		}
示例#20
0
 internal override int ResolveOverload(Analyzer analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature)
 {
     overloadSignature = signature;
     return 0;
 }
示例#21
0
		internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position,
			out RoutineSignature overloadSignature)
		{
			overloadSignature = UnknownSignature.Default;
			return 0;
		}
示例#22
0
		internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position,
			out RoutineSignature overloadSignature)
		{
			// no ctor defined => default is to be used => should have no parameters;
			// do not report errors if the declaring type is open type (constructed or a generic parameter);
			if (declaringType.IsDefinite && IsConstructor && declaringType.IsClosed && callSignature.Parameters.Count > 0)
			{
				analyzer.ErrorSink.Add(Warnings.NoCtorDefined, analyzer.SourceUnit, position, declaringType.FullName);
				declaringType.ReportError(analyzer.ErrorSink, Warnings.RelatedLocation);
			}

			overloadSignature = UnknownSignature.Default;
			return 0;
		}
示例#23
0
 public static PHP.Core.Compiler.AST.FunctionCallEvaluateInfo ClassExists_Analyze_2(Analyzer analyzer, string name, bool autoload)
 {
     // ignore autoload at the compile time
     return ClassExists_Analyze_1(analyzer, name);
 }
示例#24
0
		internal override Statement/*!*/ Analyze(Analyzer/*!*/ analyzer)
		{
			analyzer.EnterNamespace(this);

            this.Statements.Analyze(analyzer);
			
			analyzer.LeaveNamespace();

			return this;
		}
示例#25
0
        public static bool ExtensionLoaded_Analyze(Analyzer/*!*/analyzer, string extension)
        {
            Debug.Assert(analyzer != null);

            foreach (var loadedExtension in analyzer.Context.ApplicationContext.GetLoadedExtensions())
                if (String.Compare(loadedExtension, extension, StringComparison.CurrentCultureIgnoreCase) == 0)
                    return true;

            return false;
        }
示例#26
0
		internal override Statement/*!*/ Analyze(Analyzer/*!*/ analyzer)
		{
			attributes.AnalyzeMembers(analyzer, analyzer.CurrentScope);
			attributes.Analyze(analyzer, this);

			bool is_unreachable = analyzer.IsThisCodeUnreachable();

			foreach (GlobalConstantDecl cd in constants)
			{
				cd.GlobalConstant.Declaration.IsUnreachable = is_unreachable;
				// cd.Constant.CustomAttributes = attributes;
				cd.Analyze(analyzer);
			}

			if (is_unreachable)
			{
				analyzer.ReportUnreachableCode(position);
				return EmptyStmt.Unreachable;
			}
			else
			{
				return this;
			}
		}
示例#27
0
        public static PHP.Core.Compiler.AST.FunctionCallEvaluateInfo CreateFunction_Analyze(
            Analyzer analyzer,
            PHP.Core.AST.CallSignature callSignature,
            string args, string body)
        {
            if (analyzer.IsInsideIncompleteClass())
                return null;  // in this case, the DirectFnCall will not be Emitted. Therefore the lambda routine will not be declared and compilation will fail when emitting not fully declared lambda FunctionDecl.

            // has to be a valid identifier:
            // actually this name is never used then
            string function_name = "__" + Guid.NewGuid().ToString().Replace('-', '_'); //DynamicCode.GenerateLambdaName(args, body);

            string prefix1, prefix2;
            DynamicCode.GetLamdaFunctionCodePrefixes(function_name, args, out prefix1, out prefix2);

            PHP.Core.Parsers.Position pos_args = callSignature.Parameters[0].Position;
            PHP.Core.Parsers.Position pos_body = callSignature.Parameters[1].Position;

            // function __XXXXXX(<args>){<fill><body>}
            string fill = GetInlinedLambdaCodeFill(pos_args, pos_body);
            string code = String.Concat(prefix2, fill, body, "}");

            // the position of the first character of the parsed code:
            // (note that escaped characters distort position a little bit, which cannot be eliminated so easily)
            PHP.Core.Parsers.Position pos = PHP.Core.Parsers.Position.Initial;
            pos.FirstOffset = pos_args.FirstOffset - prefix1.Length + 1;
            pos.FirstColumn = pos_args.FirstColumn - prefix1.Length + 1;
            pos.FirstLine = pos_args.FirstLine;

            // parses function source code:
            var counter = new PHP.Core.Parsers.Parser.ReductionsCounter();
            var ast = analyzer.BuildAst(pos, code, counter);
            if (ast == null || ast.Statements == null)
                return null;   // the function cannot be parsed

            Debug.Assert(counter.FunctionCount == 1);

            var decl_node = (PHP.Core.AST.FunctionDecl)ast.Statements[0];

            // adds declaration to the end of the global code statement list:
            analyzer.AddLambdaFcnDeclaration(decl_node);

            //
            return new PHP.Core.Compiler.AST.FunctionCallEvaluateInfo()
            {
                //.inlined = InlinedFunction.CreateFunction;
                emitDeclareLamdaFunction = true,

                // modify declaration:
                newRoutine = Core.Compiler.AST.FunctionDeclCompilerHelper.ConvertToLambda(decl_node, analyzer),
            };
        }
示例#28
0
		public bool AnalyzeDfsTree(PhpSourceFile/*!*/ rootSourceFile)
		{
			CompilationUnit root = GetNode(rootSourceFile);

			ScriptCompilationUnit rootScript = root as ScriptCompilationUnit;
			if (rootScript != null && rootScript.State == CompilationUnit.States.Initial)
			{
				Analyzer analyzer = null;

				try
				{
					// builds the tree of parsed units via DFS:
					ProcessNode(rootScript);

					// finishes pending inclusions via MFP:
					ProcessPendingInclusions();

					analyzer = new Analyzer(context);

					// pre-analysis:
					rootScript.PreAnalyzeRecursively(analyzer);

					// member analysis:
					rootScript.AnalyzeMembersRecursively(analyzer);

					if (context.Errors.AnyFatalError) return false;

					// full analysis:
					rootScript.AnalyzeRecursively(analyzer);

					if (context.Errors.AnyFatalError) return false;

					// perform post analysis:
					analyzer.PostAnalyze();

					if (context.Errors.AnyError) return false;

					// TODO:
					// define constructed types:
					analyzer.DefineConstructedTypeBuilders();
				}
				catch (CompilerException)
				{
					root.State = CompilationUnit.States.Erroneous;
					return false;
				}

				if (context.Errors.AnyError) return false;
			}
			else if (root.State != CompilationUnit.States.Analyzed && root.State != CompilationUnit.States.Reflected)
			{
				return false;
			}

			return true;
		}