Пример #1
0
        /// <summary>
        /// Gets the node of the graph associated with the specified source file.
        /// First, look up the table of processed nodes.
        /// If not there, check compiled units maintained by the manager.
        /// If it is not found in the manager's cache the source file is locked so that other compilers will
        /// wait until we finish compilation of the node. The new node is created if the compilation unit doesn't exist for it.
        /// </summary>
        internal CompilationUnit GetNode(PhpSourceFile /*!*/ sourceFile)
        {
            CompilationUnit result;

            if (!nodes.TryGetValue(sourceFile, out result))
            {
                ScriptModule module;

                module = (ScriptModule)context.Manager.LockForCompiling(sourceFile, context);

                if (module != null)
                {
                    result = module.CompilationUnit;
                }
                else
                {
                    ScriptCompilationUnit scriptResult = new ScriptCompilationUnit();
                    scriptResult.SourceUnit = new SourceFileUnit(scriptResult, sourceFile, context.Config.Globalization.PageEncoding);
                    result = scriptResult;
                }
                nodes.Add(sourceFile, result);
                NodeAdded(result);
            }

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Defines a new script belonging to the multiscript assembly builder.
        /// </summary>
        public ScriptBuilder /*!*/ DefineModule(ScriptCompilationUnit /*!*/ compilationUnit)
        {
            string        subnamespace = ScriptModule.GetSubnamespace(compilationUnit.SourceUnit.SourceFile.RelativePath, true);
            ScriptBuilder sb           = new ScriptBuilder(compilationUnit, this, subnamespace);

            MultiScriptAssembly.AddScriptModule(compilationUnit.SourceUnit.SourceFile, sb);
            return(sb);
        }
Пример #3
0
 public StaticInclusion(ScriptCompilationUnit /*!*/ includer, CompilationUnit /*!*/ includee, Scope scope,
                        bool isConditional, InclusionTypes inclusionType)
 {
     this.scope         = scope;
     this.inclusionType = inclusionType;
     this.includee      = includee;
     this.includer      = includer;
     this.isConditional = isConditional;
 }
Пример #4
0
        /// <summary>
        /// Defines one and only script belonging to the assembly builder.
        /// </summary>
        public ScriptBuilder /*!*/ DefineScript(ScriptCompilationUnit /*!*/ compilationUnit)
        {
            // defines a new script:
            string        subnamespace = ScriptModule.GetSubnamespace(compilationUnit.SourceUnit.SourceFile.RelativePath, true);
            ScriptBuilder sb           = new ScriptBuilder(compilationUnit, this, subnamespace);

            // adds the script into script assembly builder:
            this.SingleScriptAssembly.Module = sb;

            return(sb);
        }
Пример #5
0
        /// <summary>
        /// Creates a new script builder.
        /// </summary>
        /// <param name="unit">Compilation unit.</param>
        /// <param name="assemblyBuilder">Script assembly builder.</param>
        /// <param name="subnamespace">The script's subnamespace ending with a type delimiter or a <B>null</B> reference.</param>
        /// <returns>New instance.</returns>
        public ScriptBuilder(ScriptCompilationUnit /*!*/ unit, ScriptAssemblyBuilder /*!*/ assemblyBuilder, string subnamespace)
            : base(unit, assemblyBuilder.ScriptAssembly, subnamespace)
        {
            Debug.Assert(unit != null && assemblyBuilder != null);

            this.assemblyBuilder = assemblyBuilder;

            // remembers a timestamp of the source file:
            this.sourceTimestamp = File.GetLastWriteTime(unit.SourceUnit.SourceFile.FullPath);

            DefineBuilders(subnamespace);
        }
Пример #6
0
        private void ProcessNode(ScriptCompilationUnit /*!*/ node)
        {
            Debug.Assert(node.State == CompilationUnit.States.Initial);

            // parses the unit and fills its tables:
            node.Parse(context);

            // resolves outgoing edges:
            node.ResolveInclusions(this);

            // follow DFS tree edges:
            foreach (StaticInclusion edge in node.Inclusions)
            {
                switch (edge.Includee.State)
                {
                case CompilationUnit.States.Initial:
                    Debug.Assert(edge.Includee is ScriptCompilationUnit);

                    // recursive descent:
                    ProcessNode((ScriptCompilationUnit)edge.Includee);                             // TODO: consider!
                    node.MergeTables(edge);
                    break;

                case CompilationUnit.States.Parsed:
                    // edge closing a cycle:
                    pendingInclusions.Add(edge);
                    break;

                case CompilationUnit.States.Processed:
                    // transverse edge to already processed subtree:
                    node.MergeTables(edge);
                    break;

                case CompilationUnit.States.Compiled:
                    // descent edge to the compiled node:
                    edge.Includee.Reflect();
                    node.MergeTables(edge);
                    break;

                case CompilationUnit.States.Analyzed:
                case CompilationUnit.States.Reflected:
                    // descent or transverse edge to already analyzed or compiled and reflected node:
                    node.MergeTables(edge);
                    break;

                default:
                    Debug.Fail("Unexpected CU state");
                    throw null;
                }
            }

            node.State = CompilationUnit.States.Processed;
        }
Пример #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BasicScriptAssembly" /> class.
        /// </summary>
        /// <param name="assembly">Assembly of PHP script</param>
        /// <param name="assemblyName">Name of the assembly</param>
        /// <param name="compilationUnit">PHP script compilation unit</param>
        internal BasicScriptAssembly(
            Assembly /*!*/ assembly,
            AssemblyName assemblyName,
            ScriptCompilationUnit /*!*/ compilationUnit)
            : base(ApplicationContext.Default, assembly)
        {
            var module = assembly.ManifestModule;

            Debug.Assert(module != null, "There must be main module with manifest");
            var assemblyBuilder = new BasicScriptAssemblyBuilder(this, assemblyName, module);
            var subNamespace    = ScriptBuilder.GetSubnamespace(
                compilationUnit.SourceUnit.SourceFile.RelativePath, true);

            Builder = new ScriptBuilder(compilationUnit, assemblyBuilder, subNamespace);
        }
Пример #8
0
		/// <summary>
		/// Creates a new script builder.
		/// </summary>
		/// <param name="unit">Compilation unit.</param>
		/// <param name="assemblyBuilder">Script assembly builder.</param>
		/// <param name="subnamespace">The script's subnamespace ending with a type delimiter or a <B>null</B> reference.</param>
		/// <returns>New instance.</returns>
		public ScriptBuilder(ScriptCompilationUnit/*!*/ unit, ScriptAssemblyBuilder/*!*/ assemblyBuilder, string subnamespace)
			: base(unit, assemblyBuilder.ScriptAssembly, subnamespace)
		{
			Debug.Assert(unit != null && assemblyBuilder != null);

			this.assemblyBuilder = assemblyBuilder;

			// remembers a timestamp of the source file:
			this.sourceTimestampUtc = FileSystemUtils.GetLastModifiedTimeUtc(unit.SourceUnit.SourceFile.FullPath);

			DefineBuilders(subnamespace);
		}
Пример #9
0
		/// <summary>
		/// Defines a new script belonging to the multiscript assembly builder.
		/// </summary>
		public ScriptBuilder/*!*/ DefineModule(ScriptCompilationUnit/*!*/ compilationUnit)
		{
			string subnamespace = ScriptModule.GetSubnamespace(compilationUnit.SourceUnit.SourceFile.RelativePath, true);
			ScriptBuilder sb = new ScriptBuilder(compilationUnit, this, subnamespace);
			MultiScriptAssembly.AddScriptModule(compilationUnit.SourceUnit.SourceFile, sb);
			return sb;
		}
Пример #10
0
		/// <summary>
		/// Defines one and only script belonging to the assembly builder.
		/// </summary>
		public ScriptBuilder/*!*/ DefineScript(ScriptCompilationUnit/*!*/ compilationUnit)
		{
			// defines a new script:
            string subnamespace = ScriptModule.GetSubnamespace(compilationUnit.SourceUnit.SourceFile.RelativePath, true);
            ScriptBuilder sb = new ScriptBuilder(compilationUnit, this, subnamespace);

			// adds the script into script assembly builder:
			this.SingleScriptAssembly.Module = sb;

			return sb;
		}
Пример #11
0
        /// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
        internal void Emit(CodeGenerator /*!*/ codeGenerator)
        {
            // TODO: improve
            codeGenerator.EnterGlobalCodeDeclaration(this.varTable, labels, sourceUnit);

            // custom body prolog emittion:
            PluginHandler.EmitBeforeBody(codeGenerator.IL, statements);

            //
            if (codeGenerator.CompilationUnit.IsTransient)
            {
                codeGenerator.DefineLabels(labels);

                codeGenerator.ChainBuilder.Create();

                foreach (Statement statement in statements)
                {
                    statement.Emit(codeGenerator);
                }

                codeGenerator.ChainBuilder.End();

                // return + appended file emission:
                codeGenerator.EmitRoutineEpilogue(this, true);
            }
#if !SILVERLIGHT
            else if (codeGenerator.CompilationUnit.IsPure)
            {
                codeGenerator.ChainBuilder.Create();

                foreach (Statement statement in statements)
                {
                    // skip empty statements in global code (they emit sequence points, which is undesirable):
                    if (!(statement is EmptyStmt))
                    {
                        statement.Emit(codeGenerator);
                    }
                }

                codeGenerator.ChainBuilder.End();
            }
            else
            {
                ScriptCompilationUnit unit = (ScriptCompilationUnit)codeGenerator.CompilationUnit;

                ILEmitter il = codeGenerator.IL;

                if (codeGenerator.Context.Config.Compiler.Debug)
                {
                    codeGenerator.MarkSequencePoint(1, 1, 1, 2);
                    il.Emit(OpCodes.Nop);
                }

                codeGenerator.DefineLabels(labels);

                // CALL <self>.<Declare>(context);
                codeGenerator.EmitLoadScriptContext();
                il.Emit(OpCodes.Call, unit.ScriptBuilder.DeclareHelperBuilder);

                // IF (<is main script>) CALL <prepended script>.Main()
                if (prependedInclusion != null)
                {
                    prependedInclusion.Emit(codeGenerator);
                }

                codeGenerator.ChainBuilder.Create();

                foreach (Statement statement in statements)
                {
                    statement.Emit(codeGenerator);
                }

                codeGenerator.ChainBuilder.End();

                // return + appended file emission:
                codeGenerator.EmitRoutineEpilogue(this, false);
            }
#endif
            codeGenerator.LeaveGlobalCodeDeclaration();
        }
Пример #12
0
		public StaticInclusion(ScriptCompilationUnit/*!*/ includer, CompilationUnit/*!*/ includee, Scope scope,
			bool isConditional, InclusionTypes inclusionType)
		{
			this.scope = scope;
			this.inclusionType = inclusionType;
			this.includee = includee;
			this.includer = includer;
			this.isConditional = isConditional;
		}
Пример #13
0
		private void ProcessNode(ScriptCompilationUnit/*!*/ node)
		{
			Debug.Assert(node.State == CompilationUnit.States.Initial);

			// parses the unit and fills its tables:
			node.Parse(context);

			// resolves outgoing edges:
			node.ResolveInclusions(this);

			// follow DFS tree edges:
			foreach (StaticInclusion edge in node.Inclusions)
			{
				switch (edge.Includee.State)
				{
					case CompilationUnit.States.Initial:
						Debug.Assert(edge.Includee is ScriptCompilationUnit);

						// recursive descent:
						ProcessNode((ScriptCompilationUnit)edge.Includee); // TODO: consider!
						node.MergeTables(edge);
						break;

					case CompilationUnit.States.Parsed:
						// edge closing a cycle:
						pendingInclusions.Add(edge);
						break;

					case CompilationUnit.States.Processed:
						// transverse edge to already processed subtree:
						node.MergeTables(edge);
						break;

					case CompilationUnit.States.Compiled:
						// descent edge to the compiled node:
						edge.Includee.Reflect();
						node.MergeTables(edge);
						break;

					case CompilationUnit.States.Analyzed:
					case CompilationUnit.States.Reflected:
						// descent or transverse edge to already analyzed or compiled and reflected node:
						node.MergeTables(edge);
						break;

					default:
						Debug.Fail("Unexpected CU state");
						throw null;
				}
			}

			node.State = CompilationUnit.States.Processed;
		}
Пример #14
0
		/// <summary>
		/// Gets the node of the graph associated with the specified source file.
		/// First, look up the table of processed nodes. 
		/// If not there, check compiled units maintained by the manager.
		/// If it is not found in the manager's cache the source file is locked so that other compilers will 
		/// wait until we finish compilation of the node. The new node is created if the compilation unit doesn't exist for it.
		/// </summary>
		internal CompilationUnit GetNode(PhpSourceFile/*!*/ sourceFile)
		{
			CompilationUnit result;
			if (!nodes.TryGetValue(sourceFile, out result))
			{
				ScriptModule module;

                module = (ScriptModule)context.Manager.LockForCompiling(sourceFile, context);

				if (module != null)
				{
					result = module.CompilationUnit;
				}
				else
				{
					ScriptCompilationUnit scriptResult = new ScriptCompilationUnit();
					scriptResult.SourceUnit = new SourceFileUnit(scriptResult, sourceFile, context.Config.Globalization.PageEncoding);
					result = scriptResult;
				}
				nodes.Add(sourceFile, result);
				NodeAdded(result);
			}

			return result;
		}
Пример #15
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);
        }