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