public StringBuilder dataBindFunction;
public StringBuilder codeRenderFunction;
public bool useCodeRender;
+ public int codeRenderIndex;
public ControlStackData (Type controlType,
string controlID,
}
}
+ public int CodeRenderIndex {
+ get {
+ return top.codeRenderIndex++;
+ }
+ }
+
public StringBuilder CodeRenderFunction
{
get {
private string interfaces;
private string basetype;
private string parent;
+ private Type parentType;
private string fullPath;
- private static string enableSessionStateLiteral = ", System.Web.SessionState.IRequiresSessionState";
Hashtable options;
string privateBinPath;
HttpContext context;
+ SessionState sessionState = SessionState.Enabled;
+
static Type styleType = typeof (System.Web.UI.WebControls.Style);
static Type fontinfoType = typeof (System.Web.UI.WebControls.FontInfo);
CompilationFailed = 2
}
+ enum SessionState
+ {
+ Enabled,
+ ReadOnly,
+ Disabled
+ }
+
public AspGenerator (string pathToFile, ArrayList elements)
{
if (elements == null)
set { context = value; }
}
+ bool AddUsing (string nspace)
+ {
+ string _using = "using " + nspace + ";";
+ if (prolog.ToString ().IndexOf (_using) == -1) {
+ prolog.AppendFormat ("\t{0}\n", _using);
+ return true;
+ }
+
+ return false;
+ }
+
+ void AddInterface (Type type)
+ {
+ AddInterface (type.ToString ());
+ }
+
public void AddInterface (string iface)
{
- if (interfaces == "") {
- interfaces = iface;
+ if (interfaces == null) {
+ interfaces = ", " + iface;
} else {
string s = ", " + iface;
if (interfaces.IndexOf (s) == -1)
return output;
}
+ bool AddProtectedField (Type type, string fieldName)
+ {
+ if (parentType == null) {
+ declarations.AppendFormat ("\t\tprotected {0} {1};\n", type.ToString (), fieldName);
+ return true;
+ }
+
+ FieldInfo field = parentType.GetField (fieldName, BindingFlags.Public |
+ BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.Static);
+
+ if (field == null || (!field.IsPublic && !field.IsFamily)) {
+ declarations.AppendFormat ("\t\tprotected {0} {1};\n", type.ToString (), fieldName);
+ return true;
+ }
+
+ if (!field.FieldType.IsAssignableFrom (type)) {
+ string message = String.Format ("The base class includes the field '{0}', but its " +
+ "type '{1}' is not compatible with {2}",
+ fieldName, field.FieldType, type);
+
+ throw new ApplicationException (message);
+ }
+
+ return false;
+ }
+
+ private Type LoadParentType (string typeName)
+ {
+ // First try loaded assemblies, then try assemblies in Bin directory.
+ // By now i do this 'by hand' but may be this is a runtime/gac task.
+ Type type = null;
+ Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
+ foreach (Assembly ass in assemblies) {
+ type = ass.GetType (typeName);
+ if (type != null)
+ return type;
+ }
+
+ Assembly assembly;
+ string [] binDlls = Directory.GetFiles (privateBinPath, "*.dll");
+ foreach (string dll in binDlls) {
+ string dllPath = Path.Combine (privateBinPath, dll);
+ assembly = null;
+ try {
+ assembly = Assembly.LoadFrom (dllPath);
+ type = assembly.GetType (typeName);
+ } catch (Exception e) {
+ if (assembly != null) {
+ Console.WriteLine ("ASP.NET Warning: assembly {0} loaded", dllPath);
+ Console.WriteLine ("ASP.NET Warning: but type {0} not found", typeName);
+ } else {
+ Console.WriteLine ("ASP.NET Warning: unable to load type {0} from {1}",
+ typeName, dllPath);
+ }
+ Console.WriteLine ("ASP.NET Warning: error was: {0}", e.Message);
+ }
+
+ if (type != null)
+ return type;
+ }
+
+ return null;
+ }
+
private void PageDirective (TagAttributes att)
{
if (att ["ClassName"] != null){
}
if (att ["EnableSessionState"] != null){
+ if (!IsPage)
+ throw new ApplicationException ("EnableSessionState not allowed here.");
+
string est = (string) att ["EnableSessionState"];
if (0 == String.Compare (est, "false", true))
- interfaces = interfaces.Replace (enableSessionStateLiteral, "");
- else if (0 != String.Compare (est, "true", true))
+ sessionState = SessionState.Disabled;
+ else if (0 == String.Compare (est, "true", true))
+ sessionState = SessionState.Enabled;
+ else if (0 == String.Compare (est, "readonly", true))
+ sessionState = SessionState.ReadOnly;
+ else
throw new ApplicationException ("EnableSessionState in Page directive not set to " +
"a correct value: " + est);
}
- if (att ["Inherits"] != null)
+ if (att ["Inherits"] != null) {
parent = (string) att ["Inherits"];
+ parentType = LoadParentType (parent);
+ if (parentType == null)
+ throw new ApplicationException ("The class " + parent + " cannot be found.");
+ }
if (att ["CompilerOptions"] != null)
Options ["CompilerOptions"] = (string) att ["CompilerOptions"];
if (tag_name != "" || src != "")
throw new ApplicationException ("Invalid attributes for @ Register: " +
att.ToString ());
- prolog.AppendFormat ("\tusing {0};\n", name_space);
+
+ AddUsing (name_space);
string dll = privateBinPath + Path.DirectorySeparatorChar + assembly_name + ".dll";
+ // Hack: it should use assembly.load semantics...
+ // may be when we don't run mcs as a external program...
+ if (!File.Exists (dll))
+ dll = assembly_name;
+
Foundry.RegisterFoundry (tag_prefix, dll, name_space);
AddReference (dll);
return;
UserControlData data = GenerateUserControl (src, Context);
switch (data.result) {
case UserControlResult.OK:
- prolog.AppendFormat ("\tusing {0};\n", "ASP");
- string dll = "output" + Path.DirectorySeparatorChar + data.assemblyName + ".dll";
- Foundry.RegisterFoundry (tag_prefix, data.assemblyName, "ASP", data.className);
+ AddUsing ("ASP");
+ Foundry.RegisterFoundry (tag_prefix, tag_name, data.assemblyName, "ASP", data.className);
AddReference (data.assemblyName);
break;
case UserControlResult.FileNotFound:
throw new ApplicationException ("Wrong syntax in Import directive.");
string _using = "using " + value + ";";
- if (prolog.ToString ().IndexOf (_using) == -1) {
- prolog.AppendFormat ("\t{0}\n", _using);
+ if (AddUsing (value) == true) {
string imports = Options ["Import"] as string;
if (imports == null) {
imports = value;
throw new ApplicationException ("@ Implements not allowed in an application file.");
string iface = (string) att ["interface"];
- interfaces += ", " + iface;
+ AddInterface (iface);
break;
case "REGISTER":
if (IsApplication)
controls.Push (control_type, control_id, tag_id, children_kind, defaultPropertyName);
bool is_generic = control_type == typeof (System.Web.UI.HtmlControls.HtmlGenericControl);
functions.Push (current_function);
- if (control_type != typeof (System.Web.UI.WebControls.ListItem))
+ if (control_type != typeof (System.Web.UI.WebControls.ListItem) &&
+ prev_children_kind != ChildrenKind.DBCOLUMNS) {
current_function.AppendFormat ("\t\tprivate System.Web.UI.Control __BuildControl_" +
"{0} ()\n\t\t{{\n\t\t\t{1} __ctrl;\n\n\t\t\t__ctrl" +
" = new {1} ({2});\n\t\t\tthis.{0} = __ctrl;\n",
control_id, control_type,
(is_generic? "\"" + tag_id + "\"" : ""));
- else
+ } else {
current_function.AppendFormat ("\t\tprivate void __BuildControl_{0} ()\n\t\t{{" +
"\n\t\t\t{1} __ctrl;\n\t\t\t__ctrl = new {1} ();" +
"\n\t\t\tthis.{0} = __ctrl;\n",
control_id, control_type);
+ }
if (children_kind == ChildrenKind.CONTROLS || children_kind == ChildrenKind.OPTION)
current_function.Append ("\t\t\tSystem.Web.UI.IParserAccessor __parser = " +
string control_type_string = controls.PeekType ().ToString ();
StringBuilder db_function = controls.DataBindFunction;
string container;
- if (controls.Container == null)
+ if (controls.Container == null || !typeof (INamingContainer).IsAssignableFrom (controls.Container))
container = "System.Web.UI.Control";
- else
+ else {
container = controls.Container.ToString ();
+ }
if (db_function.Length == 0)
db_function.AppendFormat ("\t\tpublic void __DataBind_{0} (object sender, " +
"FromArgb ({1}, {2}, {3}, {4});\n",
var_name, c.A, c.R, c.G, c.B);
}
- }
- else {
+ }
+ else if (type == typeof (string [])) {
+ string [] subStrings = att.Split (',');
+ current_function.AppendFormat ("\t\t\t__ctrl.{0} = new String [] {{\n", var_name);
+ int end = subStrings.Length;
+ for (int i = 0; i < end; i++) {
+ string s = subStrings [i].Trim ();
+ current_function.AppendFormat ("\t\t\t\t\"{0}\"", s);
+ if (i == end - 1)
+ current_function.Append ("\t\t\t\t};\n");
+ else
+ current_function.Append (",\n");
+ }
+ } else {
throw new ApplicationException ("Unsupported type in property: " +
type.ToString ());
}
}
}
+ private void AddCodeRenderControl (StringBuilder function)
+ {
+ AddCodeRenderControl (function, controls.CodeRenderIndex);
+ }
+
private void AddCodeRenderControl (StringBuilder function, int index)
{
function.AppendFormat ("\t\t\tparameterContainer.Controls [{0}]." +
}
Type controlType = html_ctrl.ControlType;
- declarations.AppendFormat ("\t\tprotected {0} {1};\n", controlType, html_ctrl.ControlID);
+ AddProtectedField (controlType, html_ctrl.ControlID);
ChildrenKind children_kind;
if (0 == String.Compare (html_ctrl.TagID, "table", true))
{
AspComponent component = (AspComponent) elements.Current;
Type component_type = component.ComponentType;
- declarations.AppendFormat ("\t\tprotected {0} {1};\n", component_type, component.ControlID);
+ AddProtectedField (component_type, component.ControlID);
NewControlFunction (component.TagID, component.ControlID, component_type,
component.ChildrenKind, component.DefaultPropertyName);
- if (component_type.IsSubclassOf (typeof (System.Web.UI.UserControl)))
+ if (component_type == typeof (UserControl) ||
+ component_type.IsSubclassOf (typeof (System.Web.UI.UserControl)))
current_function.Append ("\t\t\t__ctrl.InitializeAsUserControl (Page);\n");
- if (component_type.IsSubclassOf (typeof (System.Web.UI.Control)))
+ if (component_type == typeof (Control) ||
+ component_type.IsSubclassOf (typeof (System.Web.UI.Control)))
current_function.AppendFormat ("\t\t\t__ctrl.ID = \"{0}\";\n", component.ControlID);
AddCodeForAttributes (component.ComponentType, component.Attributes);
current_function = new StringBuilder ();
functions.Push (current_function);
current_function.AppendFormat ("\t\tprivate void __BuildControl_{0} " +
- "(System.Web.UI.WebControl.DataGridColumnCollection __ctrl)\n" +
+ "(System.Web.UI.WebControls.DataGridColumnCollection __ctrl)\n" +
"\t\t{{\n", prop_id);
}
string default_id = Tag.GetDefaultID ();
Type type = typeof (System.Web.UI.WebControls.ListItem);
- declarations.AppendFormat ("\t\tprotected {0} {1};\n", type, default_id);
+ AddProtectedField (type, default_id);
NewControlFunction (tag.TagID, default_id, type, ChildrenKind.CONTROLS, null);
return;
}
StringBuilder db_function = new StringBuilder ();
string control_id = Tag.GetDefaultID ();
string control_type_string = "System.Web.UI.DataBoundLiteralControl";
- declarations.AppendFormat ("\t\tprotected {0} {1};\n", control_type_string, control_id);
+ AddProtectedField (typeof (System.Web.UI.DataBoundLiteralControl), control_id);
// Build the control
db_function.AppendFormat ("\t\tprivate System.Web.UI.Control __BuildControl_{0} ()\n" +
"\t\t{{\n\t\t\t{1} __ctrl;\n\n" +
init_funcs.Append (db_function);
current_function.AppendFormat ("\t\t\tthis.__BuildControl_{0} ();\n\t\t\t__parser." +
"AddParsedSubObject (this.{0});\n\n", control_id);
+
+ AddCodeRenderControl (controls.CodeRenderFunction);
}
private void ProcessCodeRenderTag ()
private void End ()
{
+ if (isPage) {
+ if (sessionState == SessionState.Enabled || sessionState == SessionState.ReadOnly)
+ AddInterface (typeof (System.Web.SessionState.IRequiresSessionState));
+
+ if (sessionState == SessionState.ReadOnly)
+ AddInterface (typeof (System.Web.SessionState.IReadOnlySessionState));
+ }
+
classDecl = "\tpublic class " + className + " : " + parent + interfaces + " {\n";
prolog.Append ("\n" + classDecl);
declarations.Append ("\t\tprivate static bool __intialized = false;\n\n");