public static void GenerateClassConstructorScript(ScriptGenerator generator, ClassSymbol classSymbol) { // NOTE: This is emitted last in the script file, and separate from the initial class definition // because it needs to be emitted after the class registration. foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Type == SymbolType.Field) && ((memberSymbol.Visibility & MemberVisibility.Static) != 0)) { if (((FieldSymbol)memberSymbol).IsConstant && ((memberSymbol.Visibility & (MemberVisibility.Public | MemberVisibility.Protected)) == 0)) { // PrivateInstance/Internal constant fields are omitted since they have been inlined continue; } MemberGenerator.GenerateScript(generator, memberSymbol); } } if (classSymbol.StaticConstructor != null) { ScriptTextWriter writer = generator.Writer; writer.Write("(function"); writer.WriteTrimmed(" () "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; CodeGenerator.GenerateScript(generator, classSymbol.StaticConstructor); writer.Indent--; writer.Write("})();"); writer.WriteSignificantNewLine(); } }
public static void GenerateScript(ScriptGenerator generator, MemberSymbol memberSymbol) { Debug.Assert(memberSymbol.Parent is TypeSymbol); TypeSymbol typeSymbol = (TypeSymbol)memberSymbol.Parent; string typeName = typeSymbol.FullGeneratedName; switch (memberSymbol.Type) { case SymbolType.Field: GenerateField(generator, typeName, (FieldSymbol)memberSymbol); break; case SymbolType.Indexer: GenerateIndexer(generator, typeName, (IndexerSymbol)memberSymbol); break; case SymbolType.Property: GenerateProperty(generator, typeName, (PropertySymbol)memberSymbol); break; case SymbolType.Method: GenerateMethod(generator, typeName, (MethodSymbol)memberSymbol); break; case SymbolType.Event: GenerateEvent(generator, typeName, (EventSymbol)memberSymbol); break; } }
public static void GenerateComment(ScriptGenerator generator, Symbol symbol) { ScriptTextWriter writer = generator.Writer; switch (symbol.Type) { case SymbolType.Class: GenerateClassComment(writer, (ClassSymbol)symbol); break; case SymbolType.Enumeration: GenerateEnumerationComment(writer, (EnumerationSymbol)symbol); break; case SymbolType.Event: GenerateEventComment(writer, (EventSymbol)symbol); break; case SymbolType.Indexer: GenerateIndexerComment(writer, (IndexerSymbol)symbol); break; case SymbolType.Interface: GenerateInterfaceComment(writer, (InterfaceSymbol)symbol); break; case SymbolType.Method: GenerateMethodComment(writer, (MethodSymbol)symbol); break; case SymbolType.Property: GeneratePropertyComment(writer, (PropertySymbol)symbol); break; default: Debug.Fail("Unexpected symbol type"); break; } }
private static void GenerateForStatement(ScriptGenerator generator, MemberSymbol symbol, ForStatement statement) { if (statement.Body == null) { return; } ScriptTextWriter writer = generator.Writer; writer.WriteTrimmed("for "); writer.Write("("); if (statement.Initializers != null) { ExpressionGenerator.GenerateExpressionList(generator, symbol, statement.Initializers); } else if (statement.Variables != null) { GenerateVariableDeclarations(generator, symbol, statement.Variables); } writer.WriteTrimmed("; "); if (statement.Condition != null) { ExpressionGenerator.GenerateExpression(generator, symbol, statement.Condition); } writer.WriteTrimmed("; "); if (statement.Increments != null) { ExpressionGenerator.GenerateExpressionList(generator, symbol, statement.Increments); } writer.WriteTrimmed(") "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; GenerateStatement(generator, symbol, statement.Body); writer.Indent--; writer.Write("}"); writer.WriteNewLine(); }
private static void GenerateBlockStatement(ScriptGenerator generator, MemberSymbol symbol, BlockStatement statement) { ScriptTextWriter writer = generator.Writer; foreach (Statement s in statement.Statements) { GenerateStatement(generator, symbol, s); } }
private static void GenerateExpressionStatement(ScriptGenerator generator, MemberSymbol symbol, ExpressionStatement statement) { ScriptTextWriter writer = generator.Writer; ExpressionGenerator.GenerateExpression(generator, symbol, statement.Expression); if (statement.IsFragment == false) { writer.Write(";"); writer.WriteNewLine(); } }
private static void GenerateErrorStatement(ScriptGenerator generator, MemberSymbol symbol, ErrorStatement statement) { ScriptTextWriter writer = generator.Writer; writer.Write("// ERROR: "); writer.Write(statement.Message); writer.WriteSignificantNewLine(); writer.Write("// ERROR: at "); writer.Write(statement.Location); writer.WriteSignificantNewLine(); }
public static void GenerateScript(ScriptGenerator generator, EventSymbol symbol, bool add) { SymbolImplementation accessorImpl; if (add) { accessorImpl = symbol.AdderImplementation; } else { accessorImpl = symbol.RemoverImplementation; } GenerateImplementationScript(generator, symbol, accessorImpl); }
public static void GenerateScript(ScriptGenerator generator, IndexerSymbol symbol, bool getter) { SymbolImplementation accessorImpl; if (getter) { accessorImpl = symbol.GetterImplementation; } else { accessorImpl = symbol.SetterImplementation; } GenerateImplementationScript(generator, symbol, accessorImpl); }
public static void GenerateRegistrationScript(ScriptGenerator generator, TypeSymbol typeSymbol) { ClassSymbol classSymbol = typeSymbol as ClassSymbol; if ((classSymbol != null) && classSymbol.IsExtenderClass) { return; } ScriptTextWriter writer = generator.Writer; writer.Write(typeSymbol.GeneratedName); writer.Write(": "); switch (typeSymbol.Type) { case SymbolType.Class: writer.Write("[ "); writer.Write(typeSymbol.FullGeneratedName); writer.Write(", "); if (((ClassSymbol)typeSymbol).IsStaticClass == false) { writer.Write(typeSymbol.FullGeneratedName); writer.Write("$, "); } else { writer.Write("null, "); } if ((classSymbol.BaseClass == null) || classSymbol.IsTestClass) { // TODO: We need to introduce the notion of a base class that only exists in the metadata // and not at runtime. At that point this check of IsTestClass can be generalized. writer.Write("null"); } else { writer.Write(classSymbol.BaseClass.FullGeneratedName); } if (classSymbol.Interfaces != null) { foreach (InterfaceSymbol interfaceSymbol in classSymbol.Interfaces) { writer.Write(", "); writer.Write(interfaceSymbol.FullGeneratedName); } } writer.Write(" ]"); break; case SymbolType.Interface: writer.Write("[ "); writer.Write(typeSymbol.FullGeneratedName); writer.Write(" ]"); break; case SymbolType.Record: case SymbolType.Resources: case SymbolType.Enumeration: writer.Write(typeSymbol.FullGeneratedName); break; } }
public static void GenerateStatement(ScriptGenerator generator, MemberSymbol symbol, Statement statement) { switch (statement.Type) { case StatementType.Block: GenerateBlockStatement(generator, symbol, (BlockStatement)statement); break; case StatementType.Empty: break; case StatementType.VariableDeclaration: GenerateVariableDeclarationStatement(generator, symbol, (VariableDeclarationStatement)statement); break; case StatementType.Return: GenerateReturnStatement(generator, symbol, (ReturnStatement)statement); break; case StatementType.Expression: GenerateExpressionStatement(generator, symbol, (ExpressionStatement)statement); break; case StatementType.IfElse: GenerateIfElseStatement(generator, symbol, (IfElseStatement)statement); break; case StatementType.While: GenerateWhileStatement(generator, symbol, (WhileStatement)statement); break; case StatementType.For: GenerateForStatement(generator, symbol, (ForStatement)statement); break; case StatementType.ForIn: GenerateForInStatement(generator, symbol, (ForInStatement)statement); break; case StatementType.Switch: GenerateSwitchStatement(generator, symbol, (SwitchStatement)statement); break; case StatementType.Break: GenerateBreakStatement(generator, symbol, (BreakStatement)statement); break; case StatementType.Continue: GenerateContinueStatement(generator, symbol, (ContinueStatement)statement); break; case StatementType.Throw: GenerateThrowStatement(generator, symbol, (ThrowStatement)statement); break; case StatementType.TryCatchFinally: GenerateTryCatchFinallyStatement(generator, symbol, (TryCatchFinallyStatement)statement); break; case StatementType.Error: GenerateErrorStatement(generator, symbol, (ErrorStatement)statement); break; default: Debug.Fail("Unexpected statement type: " + statement.Type); break; } }
private static void GenerateBaseInitializerExpression(ScriptGenerator generator, MemberSymbol symbol, BaseInitializerExpression expression) { ScriptTextWriter writer = generator.Writer; Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".initializeBase(this"); if (expression.Parameters != null) { writer.Write(","); writer.WriteTrimmed(" [ "); GenerateExpressionList(generator, symbol, expression.Parameters); writer.WriteTrimmed(" ]"); } writer.Write(")"); }
public static void GenerateScript(ScriptGenerator generator, NamespaceSymbol namespaceSymbol, Dictionary<string,bool> generatedNamespaces) { Debug.Assert(generator != null); Debug.Assert(namespaceSymbol != null); Debug.Assert(namespaceSymbol.HasApplicationTypes); ScriptTextWriter writer = generator.Writer; // First generate enums and interfaces which do not have cross-dependencies // (Classes for example, might have dependencies on enums) foreach (TypeSymbol type in namespaceSymbol.Types) { if (type.IsApplicationType) { if (type.IsTestType && (generator.Options.IncludeTests == false)) { continue; } string namespaceName = type.GeneratedNamespace; if ((namespaceName.Length != 0) && (generatedNamespaces.ContainsKey(namespaceName) == false)) { writer.Write("Type.registerNamespace('"); writer.Write(namespaceName); writer.Write("');"); writer.WriteNewLine(); writer.WriteNewLine(); generatedNamespaces[namespaceName] = true; } } if (type.IsApplicationType && ((type.Type == SymbolType.Enumeration) || (type.Type == SymbolType.Interface) || (type.Type == SymbolType.Record) || (type.Type == SymbolType.Resources))) { TypeGenerator.GenerateScript(generator, type); } } foreach (TypeSymbol type in namespaceSymbol.Types) { if (type.IsApplicationType && (type.Type == SymbolType.Class)) { if (type.IsTestType && (generator.Options.IncludeTests == false)) { continue; } TypeGenerator.GenerateScript(generator, type); } } }
public static void GenerateClassRegistrationScript(ScriptGenerator generator, ClassSymbol classSymbol) { // NOTE: This is emitted towards the end of the script file as opposed to immediately after the // class definition, because it allows us to reference other class (base class, interfaces) // without having to do a manual topological sort to get the ordering of class definitions // that would be needed otherwise. ScriptTextWriter writer = generator.Writer; string name = classSymbol.FullGeneratedName; writer.Write(name); writer.Write(".registerClass('"); writer.Write(generator.Options.AssemblyName); writer.Write("', '"); writer.Write(name); writer.Write("'"); // TODO: We need to introduce the notion of a base class that only exists in the metadata // and not at runtime. At that point this check of IsTestClass can be generalized. if (classSymbol.IsTestClass) { writer.Write(");"); writer.WriteNewLine(); return; } if (classSymbol.BaseClass != null) { writer.WriteTrimmed(", "); writer.Write(classSymbol.BaseClass.FullGeneratedName); } if (classSymbol.Interfaces != null) { if (classSymbol.BaseClass == null) { writer.WriteTrimmed(", "); writer.Write("null"); } foreach (InterfaceSymbol interfaceSymbol in classSymbol.Interfaces) { writer.WriteTrimmed(", "); writer.Write(interfaceSymbol.FullGeneratedName); } } writer.Write(");"); writer.WriteNewLine(); }
private static void GenerateSwitchStatement(ScriptGenerator generator, MemberSymbol symbol, SwitchStatement statement) { ScriptTextWriter writer = generator.Writer; writer.WriteTrimmed("switch "); writer.Write("("); ExpressionGenerator.GenerateExpression(generator, symbol, statement.Condition); writer.WriteTrimmed(") "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; foreach (SwitchGroup group in statement.Groups) { if (group.Cases != null) { foreach (Expression caseExpression in group.Cases) { writer.Write("case "); ExpressionGenerator.GenerateExpression(generator, symbol, caseExpression); writer.Write(":"); writer.WriteNewLine(); } } if (group.IncludeDefault) { writer.Write("default:"); writer.WriteNewLine(); } writer.Indent++; foreach (Statement childStatement in group.Statements) { GenerateStatement(generator, symbol, childStatement); } writer.Indent--; } writer.Indent--; writer.Write("}"); writer.WriteNewLine(); }
private static void GenerateEventExpression(ScriptGenerator generator, MemberSymbol symbol, EventExpression expression) { ScriptTextWriter writer = generator.Writer; EventSymbol eventSymbol = expression.Event; ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); if (eventSymbol.HasCustomAccessors) { writer.Write("."); if (expression.Type == ExpressionType.EventAdd) { writer.Write(eventSymbol.AddAccessor); } else { writer.Write(eventSymbol.RemoveAccessor); } writer.Write("('"); writer.Write(expression.Event.GeneratedName); writer.Write("', "); ExpressionGenerator.GenerateExpression(generator, symbol, expression.Handler); writer.Write(")"); } else { if (expression.Type == ExpressionType.EventAdd) { writer.Write(".add_"); } else { writer.Write(".remove_"); } writer.Write(expression.Event.GeneratedName); writer.Write("("); ExpressionGenerator.GenerateExpression(generator, symbol, expression.Handler); writer.Write(")"); } }
public static void GenerateClassConstructorScript(ScriptGenerator generator, ClassSymbol classSymbol) { // NOTE: This is emitted last in the script file, and separate from the initial class definition // because it needs to be emitted after the class registration. foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Type == SymbolType.Field) && ((memberSymbol.Visibility & MemberVisibility.Static) != 0)) { FieldSymbol fieldSymbol = (FieldSymbol)memberSymbol; if (fieldSymbol.IsConstant && ((memberSymbol.Visibility & (MemberVisibility.Public | MemberVisibility.Protected)) == 0)) { // PrivateInstance/Internal constant fields are omitted since they have been inlined continue; } if (fieldSymbol.HasInitializer) { MemberGenerator.GenerateScript(generator, memberSymbol); } } } if (classSymbol.StaticConstructor != null) { ScriptTextWriter writer = generator.Writer; SymbolImplementation implementation = classSymbol.StaticConstructor.Implementation; bool requiresFunctionScope = implementation.DeclaresVariables; if (requiresFunctionScope) { writer.WriteLine("(function() {"); writer.Indent++; } CodeGenerator.GenerateScript(generator, classSymbol.StaticConstructor); if (requiresFunctionScope) { writer.Indent--; writer.Write("})();"); writer.WriteLine(); } } }
private static void GenerateImplementationScript(ScriptGenerator generator, MemberSymbol symbol, SymbolImplementation implementation) { generator.StartImplementation(implementation); try { bool generateThisCacheStatement = false; if ((symbol.Visibility & MemberVisibility.Static) == 0) { CodeMemberSymbol codeMemberSymbol = symbol as CodeMemberSymbol; if ((codeMemberSymbol != null) && (codeMemberSymbol.AnonymousMethods != null)) { foreach (AnonymousMethodSymbol anonymousMethod in codeMemberSymbol.AnonymousMethods) { if ((anonymousMethod.Visibility & MemberVisibility.Static) == 0) { generateThisCacheStatement = true; break; } } } } if (generateThisCacheStatement) { ScriptTextWriter writer = generator.Writer; writer.WriteLine("var $this = this;"); writer.WriteLine(); } foreach (Statement statement in implementation.Statements) { StatementGenerator.GenerateStatement(generator, symbol, statement); } } finally { generator.EndImplementation(); } }
private static void GeneratePropertyExpression(ScriptGenerator generator, MemberSymbol symbol, PropertyExpression expression) { Debug.Assert(expression.Type == ExpressionType.PropertyGet); ScriptTextWriter writer = generator.Writer; if (expression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, 'get_"); writer.Write(expression.Property.GeneratedName); writer.Write("')"); } else { ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference); writer.Write(".get_"); writer.Write(expression.Property.GeneratedName); writer.Write("()"); } }
private static void GenerateTryCatchFinallyStatement(ScriptGenerator generator, MemberSymbol symbol, TryCatchFinallyStatement statement) { ScriptTextWriter writer = generator.Writer; writer.WriteTrimmed("try "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; GenerateStatement(generator, symbol, statement.Body); writer.Indent--; writer.Write("}"); writer.WriteNewLine(); if (statement.Catch != null) { writer.WriteTrimmed("catch "); writer.Write("("); writer.Write(statement.ExceptionVariable.GeneratedName); writer.WriteTrimmed(") "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; GenerateStatement(generator, symbol, statement.Catch); writer.Indent--; writer.Write("}"); writer.WriteNewLine(); } if (statement.Finally != null) { writer.WriteTrimmed("finally "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; GenerateStatement(generator, symbol, statement.Finally); writer.Indent--; writer.Write("}"); writer.WriteNewLine(); } }
private static void GenerateEvent(ScriptGenerator generator, string typeName, EventSymbol eventSymbol) { ScriptTextWriter writer = generator.Writer; ParameterSymbol valueParameter = eventSymbol.Parameters[0]; if (generator.Options.Minimize) { bool obfuscateParams = !eventSymbol.IsPublic; if (obfuscateParams) { valueParameter.SetTransformedName("$p0"); } } string eventName = eventSymbol.GeneratedName; string fieldName = eventName; if (eventSymbol.DefaultImplementation) { fieldName = "__" + Utility.CreateCamelCaseName(eventSymbol.Name); Debug.Assert(eventSymbol.Parent.Type == SymbolType.Class); Symbol fieldSymbol = ((ClassSymbol)eventSymbol.Parent).GetMember(fieldName); Debug.Assert((fieldSymbol != null) && (fieldSymbol.Type == SymbolType.Field)); fieldName = fieldSymbol.GeneratedName; } string fieldReference; if ((eventSymbol.Visibility & MemberVisibility.Static) == 0) { fieldReference = "this."; } else { fieldReference = typeName + "."; } fieldReference += fieldName; bool instanceMember = true; if ((eventSymbol.Visibility & MemberVisibility.Static) != 0) { instanceMember = false; writer.Write(typeName); writer.Write("."); } writer.Write("add_"); writer.Write(eventName); if (instanceMember) { writer.WriteTrimmed(": "); } else { writer.WriteTrimmed(" = "); } writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(typeName.Replace(".", "_")); writer.Write("$add_"); writer.Write(eventName); } writer.Write("("); writer.Write(valueParameter.GeneratedName); writer.Write(")"); writer.WriteTrimmed(" {"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, eventSymbol); } if (eventSymbol.DefaultImplementation) { writer.Write(fieldReference); writer.WriteTrimmed(" = "); writer.Write("ss.Delegate.combine("); writer.Write(fieldReference); writer.WriteTrimmed(", "); writer.Write(valueParameter.GeneratedName); writer.Write(");"); writer.WriteNewLine(); } else { CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ true); } writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteSignificantNewLine(); } if (instanceMember) { writer.Write(","); writer.WriteNewLine(); } else { writer.Write(typeName); writer.Write("."); } writer.Write("remove_"); writer.Write(eventName); if (instanceMember) { writer.WriteTrimmed(": "); } else { writer.WriteTrimmed(" = "); } writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(typeName.Replace(".", "_")); writer.Write("$remove_"); writer.Write(eventName); } writer.Write("("); writer.Write(valueParameter.GeneratedName); writer.Write(")"); writer.WriteTrimmed(" {"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, eventSymbol); } if (eventSymbol.DefaultImplementation) { writer.Write(fieldReference); writer.WriteTrimmed(" = "); writer.Write("ss.Delegate.remove("); writer.Write(fieldReference); writer.WriteTrimmed(", "); writer.Write(valueParameter.GeneratedName); writer.Write(");"); writer.WriteNewLine(); } else { CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ false); } writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteSignificantNewLine(); } }
private static void GenerateForInStatement(ScriptGenerator generator, MemberSymbol symbol, ForInStatement statement) { ScriptTextWriter writer = generator.Writer; if (statement.IsDictionaryEnumeration) { writer.Write("var "); writer.Write(statement.DictionaryVariable.GeneratedName); writer.WriteTrimmed(" = "); ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression); writer.Write(";"); writer.WriteNewLine(); writer.WriteTrimmed("for "); writer.Write("(var "); writer.Write(statement.LoopVariable.GeneratedName); writer.Write(" in "); writer.Write(statement.DictionaryVariable.GeneratedName); writer.WriteTrimmed(") "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; writer.Write("var "); writer.Write(statement.ItemVariable.GeneratedName); writer.WriteTrimmed(" = "); writer.WriteTrimmed("{ "); writer.WriteTrimmed("key: "); writer.Write(statement.LoopVariable.GeneratedName); writer.WriteTrimmed(", "); writer.WriteTrimmed("value: "); writer.Write(statement.DictionaryVariable.GeneratedName); writer.Write("["); writer.Write(statement.LoopVariable.GeneratedName); writer.Write("]"); writer.WriteTrimmed(" };"); writer.WriteNewLine(); GenerateStatement(generator, symbol, statement.Body); writer.Indent--; writer.Write("}"); writer.WriteNewLine(); } else { writer.Write("var "); writer.Write(statement.LoopVariable.GeneratedName); writer.WriteTrimmed(" = "); writer.Write("ss.IEnumerator.getEnumerator("); ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression); writer.Write(");"); writer.WriteNewLine(); writer.WriteTrimmed("while "); writer.Write("("); writer.Write(statement.LoopVariable.GeneratedName); writer.WriteTrimmed(".moveNext()) "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; writer.Write("var "); writer.Write(statement.ItemVariable.GeneratedName); writer.WriteTrimmed(" = "); writer.Write(statement.LoopVariable.GeneratedName); writer.Write(".current;"); writer.WriteNewLine(); GenerateStatement(generator, symbol, statement.Body); writer.Indent--; writer.Write("}"); writer.WriteNewLine(); } }
private static void GenerateUnaryExpression(ScriptGenerator generator, MemberSymbol symbol, UnaryExpression expression) { ScriptTextWriter writer = generator.Writer; PropertyExpression propExpression = expression.Operand as PropertyExpression; if ((propExpression != null) && ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PostIncrement) || (expression.Operator == Operator.PreDecrement) || (expression.Operator == Operator.PostDecrement))) { Debug.Assert(propExpression.Type == ExpressionType.PropertyGet); string fudgeOperator; GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".set_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("("); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(".get_"); writer.Write(propExpression.Property.GeneratedName); writer.Write("()"); if ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PostIncrement)) { writer.WriteTrimmed(" + "); fudgeOperator = " - "; } else { writer.WriteTrimmed(" - "); fudgeOperator = " + "; } writer.Write("1"); writer.Write(")"); if ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PreDecrement)) { writer.WriteTrimmed(fudgeOperator); writer.Write("1"); } return; } if ((expression.Operator == Operator.PreIncrement) || (expression.Operator == Operator.PreDecrement)) { ExpressionGenerator.GenerateExpression(generator, symbol, expression.Operand); writer.Write(OperatorConverter.OperatorToString(expression.Operator)); } else { writer.Write(OperatorConverter.OperatorToString(expression.Operator)); ExpressionGenerator.GenerateExpression(generator, symbol, expression.Operand); } }
private static void GenerateClass(ScriptGenerator generator, ClassSymbol classSymbol) { ScriptTextWriter writer = generator.Writer; string name = classSymbol.FullGeneratedName; writer.Write("function "); writer.Write(name); writer.Write("("); if ((classSymbol.Constructor != null) && (classSymbol.Constructor.Parameters != null)) { bool firstParameter = true; foreach (ParameterSymbol parameterSymbol in classSymbol.Constructor.Parameters) { if (firstParameter == false) { writer.Write(", "); } writer.Write(parameterSymbol.GeneratedName); firstParameter = false; } } writer.WriteLine(") {"); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, classSymbol); } foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Type == SymbolType.Field) && (memberSymbol.Visibility & MemberVisibility.Static) == 0) { FieldSymbol fieldSymbol = (FieldSymbol)memberSymbol; if (fieldSymbol.HasInitializer) { writer.Write("this."); writer.Write(fieldSymbol.GeneratedName); writer.Write(" = "); CodeGenerator.GenerateScript(generator, fieldSymbol); writer.Write(";"); writer.WriteLine(); } } } if (classSymbol.Constructor != null) { CodeGenerator.GenerateScript(generator, classSymbol.Constructor); } else if ((classSymbol.BaseClass != null) && (classSymbol.IsTestClass == false)) { writer.Write(classSymbol.BaseClass.FullGeneratedName); writer.Write(".call(this);"); writer.WriteLine(); } writer.Indent--; writer.WriteLine("}"); foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Type != SymbolType.Field) && (memberSymbol.Visibility & MemberVisibility.Static) != 0) { MemberGenerator.GenerateScript(generator, memberSymbol); } } if (classSymbol.IsStaticClass == false) { writer.Write("var "); writer.Write(name); writer.WriteLine("$ = {"); writer.Indent++; bool firstMember = true; foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Visibility & MemberVisibility.Static) == 0) { if (memberSymbol.Type == SymbolType.Field) { continue; } if ((memberSymbol is CodeMemberSymbol) && ((CodeMemberSymbol)memberSymbol).IsAbstract) { continue; } if (firstMember == false) { writer.WriteLine(","); } MemberGenerator.GenerateScript(generator, memberSymbol); firstMember = false; } } if (classSymbol.Indexer != null) { if (firstMember == false) { writer.WriteLine(","); } MemberGenerator.GenerateScript(generator, classSymbol.Indexer); } writer.Indent--; writer.WriteLine(); writer.Write("};"); writer.WriteLine(); } }
private static void GenerateNewExpression(ScriptGenerator generator, MemberSymbol symbol, NewExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.IsSpecificType) { string type = expression.AssociatedType.FullGeneratedName; if (type.Equals("Array")) { if (expression.Parameters == null) { writer.Write("[]"); } else if ((expression.Parameters.Count == 1) && (expression.Parameters[0].EvaluatedType == symbol.SymbolSet.ResolveIntrinsicType(IntrinsicType.Integer))) { writer.Write("new Array("); GenerateExpression(generator, symbol, expression.Parameters[0]); writer.Write(")"); } else { writer.Write("["); GenerateExpressionList(generator, symbol, expression.Parameters); writer.Write("]"); } return; } else if (type.Equals("Object")) { if (expression.Parameters == null) { writer.Write("{}"); } else { writer.WriteTrimmed("{ "); GenerateExpressionListAsNameValuePairs(generator, symbol, expression.Parameters); writer.WriteTrimmed(" }"); } return; } else if (expression.AssociatedType.Type == SymbolType.Record) { if (expression.AssociatedType.IgnoreNamespace == false) { writer.Write(expression.AssociatedType.GeneratedNamespace); writer.Write("."); } writer.Write("$create_"); writer.Write(expression.AssociatedType.GeneratedName); writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); return; } } writer.Write("new "); if (expression.IsSpecificType) { writer.Write(expression.AssociatedType.FullGeneratedName); } else { GenerateExpression(generator, symbol, expression.TypeExpression); } writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); }
private static void GenerateThisExpression(ScriptGenerator generator, MemberSymbol symbol, ThisExpression expression) { ScriptTextWriter writer = generator.Writer; writer.Write("this"); }
public static void GenerateScript(ScriptGenerator generator, AnonymousMethodSymbol symbol) { GenerateImplementationScript(generator, symbol, symbol.Implementation); }
private static void GenerateLocalExpression(ScriptGenerator generator, MemberSymbol symbol, LocalExpression expression) { ScriptTextWriter writer = generator.Writer; writer.Write(expression.Symbol.GeneratedName); }
private static void GenerateInterface(ScriptGenerator generator, InterfaceSymbol interfaceSymbol) { ScriptTextWriter writer = generator.Writer; string interfaceName = interfaceSymbol.FullGeneratedName; if (interfaceSymbol.Namespace.Length == 0) { writer.Write("window."); } writer.Write(interfaceName); writer.WriteTrimmed(" = "); writer.Write("function()"); writer.WriteTrimmed(" { "); if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, interfaceSymbol); } writer.Write("};"); writer.WriteNewLine(); if (generator.Options.DebugFlavor) { writer.Write(interfaceName); writer.Write(".prototype = {"); writer.WriteLine(); writer.Indent++; bool firstMember = true; foreach (MemberSymbol member in interfaceSymbol.Members) { if (firstMember == false) { writer.Write(","); writer.WriteLine(); } if (member.Type == SymbolType.Property) { writer.Write("get_"); writer.Write(member.GeneratedName); writer.WriteTrimmed(" : "); writer.Write("null"); if (((PropertySymbol)member).IsReadOnly == false) { writer.Write(","); writer.WriteLine(); writer.Write("set_"); writer.Write(member.GeneratedName); writer.WriteTrimmed(" : "); writer.Write("null"); } } else if (member.Type == SymbolType.Event) { writer.Write("add_"); writer.Write(member.GeneratedName); writer.WriteTrimmed(" : "); writer.Write("null,"); writer.WriteLine(); writer.Write("remove_"); writer.Write(member.GeneratedName); writer.WriteTrimmed(" : "); writer.Write("null"); } else { writer.Write(member.GeneratedName); writer.WriteTrimmed(" : "); writer.Write("null"); } firstMember = false; } writer.Indent--; writer.WriteLine(); writer.Write("}"); writer.WriteSignificantNewLine(); } writer.Write(interfaceName); writer.Write(".registerInterface('"); writer.Write(interfaceName); writer.Write("');"); writer.WriteNewLine(); }
public static void GenerateScript(ScriptGenerator generator, ClassSymbol testClassSymbol) { Debug.Assert(generator != null); List <MethodSymbol> testMethods = new List <MethodSymbol>(); bool hasSetup = false; bool hasCleanup = false; foreach (MemberSymbol member in testClassSymbol.Members) { if (member.Type == SymbolType.Method) { if (String.CompareOrdinal(member.Name, "Setup") == 0) { hasSetup = true; } else if (String.CompareOrdinal(member.Name, "Cleanup") == 0) { hasCleanup = true; } else if (member.Name.StartsWith("Test", StringComparison.Ordinal)) { testMethods.Add((MethodSymbol)member); } } } ScriptTextWriter writer = generator.Writer; writer.WriteLine(); writer.Write("module('"); writer.Write(testClassSymbol.GeneratedName); writer.WriteLine("', {"); writer.Indent++; writer.WriteLine("setup: function() {"); writer.Indent++; writer.Write("this.instance = new "); writer.Write(testClassSymbol.FullGeneratedName); writer.WriteLine("();"); if (hasSetup) { writer.WriteLine("this.instance.setup();"); } writer.Indent--; writer.WriteLine("},"); writer.WriteLine("teardown: function() {"); writer.Indent++; if (hasCleanup) { writer.WriteLine("this.instance.cleanup();"); } writer.WriteLine("delete this.instance;"); writer.Indent--; writer.WriteLine("}"); writer.Indent--; writer.WriteLine("});"); writer.WriteLine(); foreach (MethodSymbol testMethod in testMethods) { writer.Write("test('"); writer.Write(testMethod.GeneratedName); writer.WriteLine("', function() {"); writer.Indent++; writer.Write("this.instance."); writer.Write(testMethod.GeneratedName); writer.WriteLine("();"); writer.Indent--; writer.WriteLine("});"); } }
private static void GenerateTypeExpression(ScriptGenerator generator, MemberSymbol symbol, TypeExpression expression) { ScriptTextWriter writer = generator.Writer; writer.Write(expression.AssociatedType.FullGeneratedName); }
private static void GenerateThisExpression(ScriptGenerator generator, MemberSymbol symbol, ThisExpression expression) { ScriptTextWriter writer = generator.Writer; writer.Write(generator.CurrentImplementation.ThisIdentifier); }
private static void GenerateProperty(ScriptGenerator generator, string typeName, PropertySymbol propertySymbol) { if (propertySymbol.IsAbstract) { return; } ScriptTextWriter writer = generator.Writer; bool instanceMember = true; if ((propertySymbol.Visibility & MemberVisibility.Static) != 0) { instanceMember = false; writer.Write(typeName); writer.Write("."); } writer.Write("get_"); writer.Write(propertySymbol.GeneratedName); if (instanceMember) { writer.WriteTrimmed(": "); } else { writer.WriteTrimmed(" = "); } writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(typeName.Replace(".", "_")); writer.Write("$get_"); writer.Write(propertySymbol.GeneratedName); } writer.Write("()"); writer.WriteTrimmed(" {"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, propertySymbol); } CodeGenerator.GenerateScript(generator, propertySymbol, /* getter */ true); writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteSignificantNewLine(); } if (propertySymbol.IsReadOnly == false) { ParameterSymbol valueParameter = propertySymbol.Parameters[0]; if (generator.Options.Minimize) { bool obfuscateParams = !propertySymbol.IsPublic; if (obfuscateParams) { valueParameter.SetTransformedName("$p0"); } } if (instanceMember) { writer.Write(","); writer.WriteNewLine(); } else { writer.Write(typeName); writer.Write("."); } writer.Write("set_"); writer.Write(propertySymbol.GeneratedName); if (instanceMember) { writer.WriteTrimmed(": "); } else { writer.WriteTrimmed(" = "); } writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(typeName.Replace(".", "_")); writer.Write("$set_"); writer.Write(propertySymbol.GeneratedName); } writer.Write("("); writer.Write(valueParameter.GeneratedName); writer.Write(")"); writer.WriteTrimmed(" {"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, propertySymbol); } CodeGenerator.GenerateScript(generator, propertySymbol, /* getter */ false); writer.Write("return "); writer.Write(valueParameter.GeneratedName); writer.Write(";"); writer.WriteNewLine(); writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteSignificantNewLine(); } } }
private static void GenerateMethod(ScriptGenerator generator, string typeName, MethodSymbol methodSymbol) { if (methodSymbol.IsAbstract) { return; } ScriptTextWriter writer = generator.Writer; bool instanceMember = ((methodSymbol.Visibility & MemberVisibility.Static) == 0); if (instanceMember == false) { if (methodSymbol.IsGlobalMethod) { string mixinRoot = null; if (methodSymbol.Parent.Type == SymbolType.Class) { mixinRoot = ((ClassSymbol)methodSymbol.Parent).MixinRoot; } if (String.IsNullOrEmpty(mixinRoot)) { mixinRoot = "window"; } writer.Write(mixinRoot); } else { writer.Write(typeName); } writer.Write("."); } writer.Write(methodSymbol.GeneratedName); if (instanceMember) { writer.WriteTrimmed(": "); } else { writer.WriteTrimmed(" = "); } writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(typeName.Replace(".", "_")); writer.Write("$"); writer.Write(methodSymbol.GeneratedName); } writer.Write("("); if (methodSymbol.Parameters != null) { bool obfuscateParams = false; if (generator.Options.Minimize) { obfuscateParams = !methodSymbol.IsPublic; } int paramIndex = 0; foreach (ParameterSymbol parameterSymbol in methodSymbol.Parameters) { if (paramIndex > 0) { writer.WriteTrimmed(", "); } if (obfuscateParams) { parameterSymbol.SetTransformedName("$p" + paramIndex); } writer.Write(parameterSymbol.GeneratedName); paramIndex++; } } writer.WriteTrimmed(") "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, methodSymbol); } CodeGenerator.GenerateScript(generator, methodSymbol); writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteSignificantNewLine(); } }
private static void GenerateIndexer(ScriptGenerator generator, string typeName, PropertySymbol indexerSymbol) { if (indexerSymbol.IsAbstract) { return; } ScriptTextWriter writer = generator.Writer; bool instanceMember = true; if ((indexerSymbol.Visibility & MemberVisibility.Static) != 0) { instanceMember = false; writer.Write(typeName); writer.Write("."); } bool obfuscateParams = !indexerSymbol.IsPublic; if (obfuscateParams && generator.Options.Minimize) { for (int i = 0; i < indexerSymbol.Parameters.Count; i++) { ParameterSymbol parameterSymbol = indexerSymbol.Parameters[i]; parameterSymbol.SetTransformedName("$p" + i); } } writer.Write("get_"); writer.Write(indexerSymbol.GeneratedName); if (instanceMember) { writer.WriteTrimmed(": "); } else { writer.WriteTrimmed(" = "); } writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(typeName.Replace(".", "_")); writer.Write("$get_"); writer.Write(indexerSymbol.GeneratedName); } writer.Write("("); for (int i = 0; i < indexerSymbol.Parameters.Count - 1; i++) { ParameterSymbol parameterSymbol = indexerSymbol.Parameters[i]; if (i > 0) { writer.WriteTrimmed(", "); } writer.Write(parameterSymbol.GeneratedName); } writer.Write(")"); writer.WriteTrimmed(" {"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, indexerSymbol); } CodeGenerator.GenerateScript(generator, (IndexerSymbol)indexerSymbol, /* getter */ true); writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteSignificantNewLine(); } if (indexerSymbol.IsReadOnly == false) { if (instanceMember) { writer.Write(","); writer.WriteNewLine(); } else { writer.Write(typeName); writer.Write("."); } writer.Write("set_"); writer.Write(indexerSymbol.GeneratedName); if (instanceMember) { writer.WriteTrimmed(": "); } else { writer.WriteTrimmed(" = "); } writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(typeName.Replace(".", "_")); writer.Write("$set_"); writer.Write(indexerSymbol.GeneratedName); } writer.Write("("); for (int i = 0; i < indexerSymbol.Parameters.Count; i++) { ParameterSymbol parameterSymbol = indexerSymbol.Parameters[i]; if (i > 0) { writer.WriteTrimmed(", "); } writer.Write(parameterSymbol.GeneratedName); } writer.Write(")"); writer.WriteTrimmed(" {"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, indexerSymbol); } CodeGenerator.GenerateScript(generator, (IndexerSymbol)indexerSymbol, /* getter */ false); writer.Write("return "); writer.Write(indexerSymbol.Parameters[indexerSymbol.Parameters.Count - 1].GeneratedName); writer.Write(";"); writer.WriteNewLine(); writer.Indent--; writer.Write("}"); if (instanceMember == false) { writer.WriteSignificantNewLine(); } } }
private static void GenerateRecord(ScriptGenerator generator, RecordSymbol recordSymbol) { ScriptTextWriter writer = generator.Writer; string recordName = recordSymbol.GeneratedName; if ((recordSymbol.Namespace.Length == 0) || recordSymbol.IgnoreNamespace) { writer.Write("window."); } else { writer.Write(recordSymbol.GeneratedNamespace); writer.Write("."); } writer.Write("$create_"); writer.Write(recordName); writer.WriteTrimmed(" = "); writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(recordSymbol.FullGeneratedName.Replace(".", "_")); } writer.Write("("); if (recordSymbol.Constructor != null) { ConstructorSymbol ctorSymbol = recordSymbol.Constructor; if (ctorSymbol.Parameters != null) { bool firstParameter = true; foreach (ParameterSymbol parameterSymbol in ctorSymbol.Parameters) { if (firstParameter == false) { writer.WriteTrimmed(", "); } writer.Write(parameterSymbol.GeneratedName); firstParameter = false; } } } writer.WriteTrimmed(")"); writer.WriteTrimmed(" {"); if (recordSymbol.Constructor != null) { writer.Indent++; writer.WriteNewLine(); writer.Write("var $o"); writer.WriteTrimmed(" = "); writer.WriteTrimmed("{ "); writer.Write("};"); writer.WriteNewLine(); CodeGenerator.GenerateScript(generator, recordSymbol.Constructor); writer.Write("return $o;"); writer.WriteNewLine(); writer.Indent--; } else { writer.WriteTrimmed(" return {}; "); } writer.Write("}"); writer.WriteSignificantNewLine(); }
public static void GenerateExpression(ScriptGenerator generator, MemberSymbol symbol, Expression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Parenthesized) { writer.Write("("); } switch (expression.Type) { case ExpressionType.Literal: GenerateLiteralExpression(generator, symbol, (LiteralExpression)expression); break; case ExpressionType.Local: GenerateLocalExpression(generator, symbol, (LocalExpression)expression); break; case ExpressionType.Member: Debug.Fail("MemberExpression missed from conversion to higher level expression."); break; case ExpressionType.Field: GenerateFieldExpression(generator, symbol, (FieldExpression)expression); break; case ExpressionType.EnumerationField: GenerateEnumerationFieldExpression(generator, symbol, (EnumerationFieldExpression)expression); break; case ExpressionType.PropertyGet: GeneratePropertyExpression(generator, symbol, (PropertyExpression)expression); break; case ExpressionType.PropertySet: Debug.Fail("PropertyExpression(set) should be covered as part of BinaryExpression logic."); break; case ExpressionType.MethodInvoke: case ExpressionType.DelegateInvoke: GenerateMethodExpression(generator, symbol, (MethodExpression)expression); break; case ExpressionType.BaseInitializer: GenerateBaseInitializerExpression(generator, symbol, (BaseInitializerExpression)expression); break; case ExpressionType.EventAdd: case ExpressionType.EventRemove: GenerateEventExpression(generator, symbol, (EventExpression)expression); break; case ExpressionType.Indexer: GenerateIndexerExpression(generator, symbol, (IndexerExpression)expression); break; case ExpressionType.This: GenerateThisExpression(generator, symbol, (ThisExpression)expression); break; case ExpressionType.Base: Debug.Fail("BaseExpression not handled by container expression."); break; case ExpressionType.New: GenerateNewExpression(generator, symbol, (NewExpression)expression); break; case ExpressionType.Unary: GenerateUnaryExpression(generator, symbol, (UnaryExpression)expression); break; case ExpressionType.Binary: GenerateBinaryExpression(generator, symbol, (BinaryExpression)expression); break; case ExpressionType.Conditional: GenerateConditionalExpression(generator, symbol, (ConditionalExpression)expression); break; case ExpressionType.Type: GenerateTypeExpression(generator, symbol, (TypeExpression)expression); break; case ExpressionType.Delegate: GenerateDelegateExpression(generator, symbol, (DelegateExpression)expression); break; case ExpressionType.LateBound: GenerateLateBoundExpression(generator, symbol, (LateBoundExpression)expression); break; case ExpressionType.InlineScript: GenerateInlineScriptExpression(generator, symbol, (InlineScriptExpression)expression); break; case ExpressionType.NewDelegate: GenerateExpression(generator, symbol, ((NewDelegateExpression)expression).TypeExpression); break; default: Debug.Fail("Unexpected expression type: " + expression.Type); break; } if (expression.Parenthesized) { writer.Write(")"); } }
public static void GenerateScript(ScriptGenerator generator, FieldSymbol symbol) { GenerateImplementationScript(generator, symbol, symbol.Implementation); }
private static void GenerateLateBoundExpression(ScriptGenerator generator, MemberSymbol symbol, LateBoundExpression expression) { ScriptTextWriter writer = generator.Writer; string name = null; LiteralExpression literalNameExpression = expression.NameExpression as LiteralExpression; if ((literalNameExpression != null) && (literalNameExpression.Value is string)) { name = (string)literalNameExpression.Value; Debug.Assert(String.IsNullOrEmpty(name) == false); } if (expression.Operation == LateBoundOperation.DeleteField) { writer.Write("delete "); } if (expression.Operation == LateBoundOperation.GetScriptType) { writer.Write("typeof("); } else if (expression.Operation == LateBoundOperation.HasMethod) { writer.Write("(typeof("); } else if (expression.Operation == LateBoundOperation.HasField) { writer.Write("("); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write(" in "); } if (expression.ObjectReference != null) { GenerateExpression(generator, symbol, expression.ObjectReference); } switch (expression.Operation) { case LateBoundOperation.InvokeMethod: if (Utility.IsValidIdentifier(name)) { if (expression.ObjectReference != null) { writer.Write("."); } writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write("("); if (expression.Parameters.Count != 0) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); break; case LateBoundOperation.GetField: if (Utility.IsValidIdentifier(name)) { writer.Write("."); writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } break; case LateBoundOperation.SetField: if (Utility.IsValidIdentifier(name)) { writer.Write("."); writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write(" = "); GenerateExpressionList(generator, symbol, expression.Parameters); break; case LateBoundOperation.DeleteField: if (Utility.IsValidIdentifier(name)) { writer.Write("."); writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } break; case LateBoundOperation.GetScriptType: writer.Write(")"); break; case LateBoundOperation.HasField: writer.Write(")"); break; case LateBoundOperation.HasMethod: if (Utility.IsValidIdentifier(name)) { if (expression.ObjectReference != null) { writer.Write("."); } writer.Write(name); } else { writer.Write("["); GenerateExpression(generator, symbol, expression.NameExpression); writer.Write("]"); } writer.Write(") === 'function')"); break; } }
private static void GenerateLiteralExpression(ScriptGenerator generator, MemberSymbol symbol, LiteralExpression expression) { ScriptTextWriter writer = generator.Writer; object value = expression.Value; string textValue = null; if (value == null) { textValue = "null"; } else { if (value is bool) { if ((bool)value) { textValue = "true"; } else { textValue = "false"; } } else if ((value is char) || (value is string)) { textValue = Utility.QuoteString(value.ToString()); } else if (value is TypeSymbol) { textValue = ((TypeSymbol)value).FullGeneratedName; } else if (value is Expression[]) { Expression[] values = (Expression[])value; if (values.Length == 0) { textValue = "[]"; } else { writer.WriteTrimmed("[ "); GenerateExpressionList(generator, symbol, (Expression[])value); writer.WriteTrimmed(" ]"); } } else { textValue = Convert.ToString(value, CultureInfo.InvariantCulture); } } if (textValue != null) { writer.Write(textValue); } }
private static void GenerateMethodExpression(ScriptGenerator generator, MemberSymbol symbol, MethodExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Method.SkipGeneration) { // If this method is to be skipped from generation, just generate the // left-hand-side object reference, and skip everything past it, including // the dot. GenerateExpression(generator, symbol, expression.ObjectReference); return; } if (expression.ObjectReference is BaseExpression) { Debug.Assert(symbol.Parent is ClassSymbol); Debug.Assert(expression.Method.IsGlobalMethod == false); writer.Write(((ClassSymbol)symbol.Parent).FullGeneratedName); writer.Write(".callBaseMethod(this, '"); writer.Write(expression.Method.GeneratedName); writer.Write("'"); if ((expression.Parameters != null) && (expression.Parameters.Count != 0)) { writer.Write(","); writer.WriteTrimmed(" [ "); GenerateExpressionList(generator, symbol, expression.Parameters); writer.WriteTrimmed(" ]"); } writer.Write(")"); } else { if (expression.Method.IsGlobalMethod) { if (expression.Method.Parent is ClassSymbol) { string mixinRoot = ((ClassSymbol)expression.Method.Parent).MixinRoot; if (String.IsNullOrEmpty(mixinRoot) == false) { writer.Write(mixinRoot); writer.Write("."); } } } else { GenerateExpression(generator, symbol, expression.ObjectReference); if (expression.Method.GeneratedName.Length != 0) { writer.Write("."); } } if (expression.Method.GeneratedName.Length != 0) { writer.Write(expression.Method.GeneratedName); } writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); } }
private static void GenerateMethodExpression(ScriptGenerator generator, MemberSymbol symbol, MethodExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Method.SkipGeneration) { // If this method is to be skipped from generation, just generate the // left-hand-side object reference, and skip everything past it, including // the dot. GenerateExpression(generator, symbol, expression.ObjectReference); return; } if (expression.ObjectReference is BaseExpression) { Debug.Assert(expression.Method.IsExtension == false); writer.Write(((BaseExpression)expression.ObjectReference).EvaluatedType.FullGeneratedName); writer.Write(".prototype."); writer.Write(expression.Method.GeneratedName); writer.Write(".call("); writer.Write(generator.CurrentImplementation.ThisIdentifier); if ((expression.Parameters != null) && (expression.Parameters.Count != 0)) { writer.Write(", "); GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); } else { if (expression.Method.IsAliased) { writer.Write(expression.Method.Alias); writer.Write("("); if ((expression.Method.Visibility & MemberVisibility.Static) == 0) { GenerateExpression(generator, symbol, expression.ObjectReference); if ((expression.Parameters != null) && (expression.Parameters.Count != 0)) { writer.Write(", "); } } if ((expression.Parameters != null) && (expression.Parameters.Count != 0)) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); } else { if (expression.Method.IsExtension) { Debug.Assert(expression.Method.Parent.Type == SymbolType.Class); string extendee = ((ClassSymbol)expression.Method.Parent).Extendee; Debug.Assert(String.IsNullOrEmpty(extendee) == false); writer.Write(extendee); writer.Write("."); } else { GenerateExpression(generator, symbol, expression.ObjectReference); if (expression.Method.GeneratedName.Length != 0) { writer.Write("."); } } if (expression.Method.GeneratedName.Length != 0) { writer.Write(expression.Method.GeneratedName); } writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); } } }
private static void GenerateEnumeration(ScriptGenerator generator, EnumerationSymbol enumSymbol) { ScriptTextWriter writer = generator.Writer; string enumName = enumSymbol.FullGeneratedName; writer.Write("var "); writer.Write(enumSymbol.FullGeneratedName); writer.Write(" = {"); writer.Indent++; bool firstValue = true; foreach (MemberSymbol memberSymbol in enumSymbol.Members) { EnumerationFieldSymbol fieldSymbol = memberSymbol as EnumerationFieldSymbol; if (fieldSymbol == null) { continue; } if (firstValue == false) { writer.Write(", "); } writer.WriteLine(); writer.Write(fieldSymbol.GeneratedName); writer.Write(": "); if (enumSymbol.UseNamedValues) { writer.Write(Utility.QuoteString(enumSymbol.CreateNamedValue(fieldSymbol))); } else { writer.Write(fieldSymbol.Value); } firstValue = false; } writer.Indent--; writer.WriteLine(); writer.Write("};"); writer.WriteLine(); }
private static void GenerateInterface(ScriptGenerator generator, InterfaceSymbol interfaceSymbol) { ScriptTextWriter writer = generator.Writer; string interfaceName = interfaceSymbol.FullGeneratedName; writer.Write("function "); writer.Write(interfaceName); writer.WriteLine("() { }"); }
public static void GenerateScript(ScriptGenerator generator, TypeSymbol typeSymbol) { Debug.Assert(generator != null); Debug.Assert(typeSymbol != null); Debug.Assert(typeSymbol.IsApplicationType); if (typeSymbol.Type == SymbolType.Delegate) { // No-op ... there is currently nothing to generate for a particular delegate type return; } if ((typeSymbol.Type == SymbolType.Record) && (typeSymbol.IsPublic == false) && (((RecordSymbol)typeSymbol).Constructor == null)) { // Nothing to generate for internal records with no explicit ctor return; } if ((typeSymbol.Type == SymbolType.Class) && ((ClassSymbol)typeSymbol).IsModuleClass) { // No members on script modules, which only contain startup code return; } ScriptTextWriter writer = generator.Writer; writer.WriteLine("// " + typeSymbol.FullName); writer.WriteLine(); switch (typeSymbol.Type) { case SymbolType.Class: if (((ClassSymbol)typeSymbol).IsExtenderClass) { GenerateExtensionMethods(generator, (ClassSymbol)typeSymbol); } else { GenerateClass(generator, (ClassSymbol)typeSymbol); } break; case SymbolType.Interface: GenerateInterface(generator, (InterfaceSymbol)typeSymbol); break; case SymbolType.Enumeration: GenerateEnumeration(generator, (EnumerationSymbol)typeSymbol); break; case SymbolType.Record: GenerateRecord(generator, (RecordSymbol)typeSymbol); break; case SymbolType.Resources: GenerateResources(generator, (ResourcesSymbol)typeSymbol); break; } writer.WriteLine(); writer.WriteLine(); }
private static void GenerateResources(ScriptGenerator generator, ResourcesSymbol resourcesSymbol) { ScriptTextWriter writer = generator.Writer; string resourcesName = resourcesSymbol.FullGeneratedName; writer.Write("var "); writer.Write(resourcesName); writer.WriteLine(" = {"); writer.Indent++; bool firstValue = true; foreach (FieldSymbol member in resourcesSymbol.Members) { Debug.Assert(member.Value is string); if (firstValue == false) { writer.Write(","); writer.WriteLine(); } writer.Write(member.GeneratedName); writer.Write(": "); writer.Write(Utility.QuoteString((string)member.Value)); firstValue = false; } writer.Indent--; writer.WriteLine(); writer.Write("};"); writer.WriteLine(); }
private static void GenerateNewExpression(ScriptGenerator generator, MemberSymbol symbol, NewExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.IsSpecificType) { string type = expression.AssociatedType.FullGeneratedName; if (type.Equals("Array")) { if (expression.Parameters == null) { writer.Write("[]"); } else if ((expression.Parameters.Count == 1) && (expression.Parameters[0].EvaluatedType == symbol.SymbolSet.ResolveIntrinsicType(IntrinsicType.Integer))) { writer.Write("new Array("); GenerateExpression(generator, symbol, expression.Parameters[0]); writer.Write(")"); } else { writer.Write("["); GenerateExpressionList(generator, symbol, expression.Parameters); writer.Write("]"); } return; } else if (type.Equals("Object")) { if (expression.Parameters == null) { writer.Write("{}"); } else { writer.Write("{ "); GenerateExpressionListAsNameValuePairs(generator, symbol, expression.Parameters); writer.Write(" }"); } return; } else if (type.Equals("Tuple")) { if ((expression.Parameters == null) || (expression.Parameters.Count == 0)) { writer.Write("{ }"); } else { writer.Write("{ "); for (int i = 0; i < expression.Parameters.Count; i++) { if (i != 0) { writer.Write(", "); } writer.Write("item"); writer.Write(i + 1); writer.Write(": "); GenerateExpression(generator, symbol, expression.Parameters[i]); } writer.Write(" }"); } return; } else if (expression.AssociatedType.Type == SymbolType.Record) { if (expression.AssociatedType.IsApplicationType && ((RecordSymbol)expression.AssociatedType).Constructor == null) { writer.Write("{ }"); return; } writer.Write(expression.AssociatedType.FullGeneratedName); writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); return; } } writer.Write("new "); if (expression.IsSpecificType) { writer.Write(expression.AssociatedType.FullGeneratedName); } else { GenerateExpression(generator, symbol, expression.TypeExpression); } writer.Write("("); if (expression.Parameters != null) { GenerateExpressionList(generator, symbol, expression.Parameters); } writer.Write(")"); }
private static void GenerateExtensionMethods(ScriptGenerator generator, ClassSymbol classSymbol) { foreach (MemberSymbol memberSymbol in classSymbol.Members) { Debug.Assert(memberSymbol.Type == SymbolType.Method); Debug.Assert((memberSymbol.Visibility & MemberVisibility.Static) != 0); MemberGenerator.GenerateScript(generator, memberSymbol); } }
private static void GenerateClass(ScriptGenerator generator, ClassSymbol classSymbol) { if (classSymbol.HasGlobalMethods) { GenerateGlobalMethods(generator, classSymbol); generator.AddGeneratedClass(classSymbol); return; } ScriptTextWriter writer = generator.Writer; string name = classSymbol.FullGeneratedName; if (classSymbol.Namespace.Length == 0) { writer.Write("window."); } writer.Write(name); writer.WriteTrimmed(" = "); writer.Write("function"); if (generator.Options.DebugFlavor) { writer.Write(" "); writer.Write(name.Replace(".", "_")); } writer.Write("("); if ((classSymbol.Constructor != null) && (classSymbol.Constructor.Parameters != null)) { bool firstParameter = true; foreach (ParameterSymbol parameterSymbol in classSymbol.Constructor.Parameters) { if (firstParameter == false) { writer.WriteTrimmed(", "); } writer.Write(parameterSymbol.GeneratedName); firstParameter = false; } } writer.WriteTrimmed(") "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, classSymbol); } foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Type == SymbolType.Field) && (memberSymbol.Visibility & MemberVisibility.Static) == 0) { FieldSymbol fieldSymbol = (FieldSymbol)memberSymbol; if (fieldSymbol.HasInitializer) { writer.Write("this."); writer.Write(fieldSymbol.GeneratedName); writer.WriteTrimmed(" = "); CodeGenerator.GenerateScript(generator, fieldSymbol); writer.Write(";"); writer.WriteNewLine(); } } } if (classSymbol.Constructor != null) { CodeGenerator.GenerateScript(generator, classSymbol.Constructor); } else if (classSymbol.BaseClass != null) { writer.Write(classSymbol.FullGeneratedName); writer.Write(".initializeBase(this);"); writer.WriteNewLine(); } writer.Indent--; writer.Write("}"); writer.WriteSignificantNewLine(); foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Type != SymbolType.Field) && (memberSymbol.Visibility & MemberVisibility.Static) != 0) { MemberGenerator.GenerateScript(generator, memberSymbol); } } bool hasPrototypeMembers = false; bool firstMember = true; bool lastMemberWasField = true; foreach (MemberSymbol memberSymbol in classSymbol.Members) { if ((memberSymbol.Visibility & MemberVisibility.Static) == 0) { if ((memberSymbol.Type == SymbolType.Field) && ((FieldSymbol)memberSymbol).HasInitializer) { continue; } if ((memberSymbol is CodeMemberSymbol) && ((CodeMemberSymbol)memberSymbol).IsAbstract) { continue; } if (hasPrototypeMembers == false) { hasPrototypeMembers = true; writer.Write(name); writer.Write(".prototype"); writer.WriteTrimmed(" = "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; } if (firstMember == false) { writer.Write(","); writer.WriteNewLine(); } if ((lastMemberWasField == false) || !(memberSymbol is FieldSymbol)) { writer.WriteNewLine(); } MemberGenerator.GenerateScript(generator, memberSymbol); lastMemberWasField = (memberSymbol is FieldSymbol); firstMember = false; } } if (classSymbol.Indexer != null) { if (hasPrototypeMembers == false) { hasPrototypeMembers = true; writer.Write(name); writer.Write(".prototype"); writer.WriteTrimmed(" = "); writer.Write("{"); writer.WriteNewLine(); writer.Indent++; } if (firstMember == false) { writer.Write(","); writer.WriteNewLine(); } MemberGenerator.GenerateScript(generator, classSymbol.Indexer); } if (hasPrototypeMembers) { writer.Indent--; writer.WriteNewLine(); writer.Write("}"); writer.WriteSignificantNewLine(); } generator.AddGeneratedClass(classSymbol); }
private static void GenerateRecord(ScriptGenerator generator, RecordSymbol recordSymbol) { ScriptTextWriter writer = generator.Writer; string recordName = recordSymbol.FullGeneratedName; writer.Write("function "); writer.Write(recordName); writer.Write("("); if (recordSymbol.Constructor != null) { ConstructorSymbol ctorSymbol = recordSymbol.Constructor; if (ctorSymbol.Parameters != null) { bool firstParameter = true; foreach (ParameterSymbol parameterSymbol in ctorSymbol.Parameters) { if (firstParameter == false) { writer.Write(", "); } writer.Write(parameterSymbol.GeneratedName); firstParameter = false; } } } writer.Write(") {"); if (recordSymbol.Constructor != null) { writer.Indent++; writer.WriteLine(); writer.WriteLine("var $o = {};"); CodeGenerator.GenerateScript(generator, recordSymbol.Constructor); writer.Write("return $o;"); writer.WriteLine(); writer.Indent--; } else { writer.Write(" return {}; "); } writer.Write("}"); writer.WriteLine(); }
private static void GenerateDelegate(ScriptGenerator generator, DelegateSymbol delegateSymbol) { // No-op // There is currently nothing to generate for a particular delegate type }
private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSymbol symbol, BinaryExpression expression) { ScriptTextWriter writer = generator.Writer; if (expression.Operator == Operator.Equals) { PropertyExpression propExpression = expression.LeftOperand as PropertyExpression; if (propExpression != null) { Debug.Assert(propExpression.Type == ExpressionType.PropertySet); if (propExpression.ObjectReference is BaseExpression) { ClassSymbol classSymbol = (ClassSymbol)symbol.Parent; writer.Write("ss.baseProperty("); writer.Write(classSymbol.FullGeneratedName); writer.Write(", '"); writer.Write(propExpression.Property.GeneratedName); writer.Write("').set.call("); writer.Write(generator.CurrentImplementation.ThisIdentifier); writer.Write(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } else { GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write("."); writer.Write(propExpression.Property.GeneratedName); writer.Write(" = "); GenerateExpression(generator, symbol, expression.RightOperand); } return; } IndexerExpression indexExpression = expression.LeftOperand as IndexerExpression; if ((indexExpression != null) && !indexExpression.Indexer.UseScriptIndexer) { Debug.Assert(indexExpression.Type == ExpressionType.Indexer); if (indexExpression.ObjectReference is BaseExpression) { writer.Write(((BaseExpression)indexExpression.ObjectReference).EvaluatedType.FullGeneratedName); writer.Write(".prototype.set_"); writer.Write(indexExpression.Indexer.GeneratedName); writer.Write(".call("); writer.Write(generator.CurrentImplementation.ThisIdentifier); writer.Write(", "); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.Write(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } else { IndexerSymbol indexerSymbol = indexExpression.Indexer; GenerateExpression(generator, symbol, indexExpression.ObjectReference); writer.Write(".set_"); writer.Write(indexerSymbol.GeneratedName); writer.Write("("); GenerateExpressionList(generator, symbol, indexExpression.Indices); writer.Write(", "); GenerateExpression(generator, symbol, expression.RightOperand); writer.Write(")"); } return; } } else if ((expression.Operator == Operator.PlusEquals) || (expression.Operator == Operator.MinusEquals) || (expression.Operator == Operator.MultiplyEquals) || (expression.Operator == Operator.DivideEquals) || (expression.Operator == Operator.ModEquals) || (expression.Operator == Operator.BitwiseOrEquals) || (expression.Operator == Operator.BitwiseAndEquals) || (expression.Operator == Operator.BitwiseXorEquals) || (expression.Operator == Operator.ShiftLeftEquals) || (expression.Operator == Operator.ShiftRightEquals) || (expression.Operator == Operator.UnsignedShiftRightEquals)) { PropertyExpression propExpression = expression.LeftOperand as PropertyExpression; if (propExpression != null) { Debug.Assert(propExpression.Type == ExpressionType.PropertyGet); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write("."); writer.Write(propExpression.Property.GeneratedName); writer.Write(" = "); GenerateExpression(generator, symbol, propExpression.ObjectReference); writer.Write(OperatorConverter.OperatorToString(expression.Operator - 1)); GenerateExpression(generator, symbol, expression.RightOperand); return; } } else if ((expression.Operator == Operator.Is) || (expression.Operator == Operator.As)) { TypeExpression typeExpression = expression.RightOperand as TypeExpression; Debug.Assert(typeExpression != null); writer.Write("ss."); if (expression.Operator == Operator.Is) { writer.Write("canCast("); } else { writer.Write("safeCast("); } GenerateExpression(generator, symbol, expression.LeftOperand); writer.Write(", "); writer.Write(typeExpression.AssociatedType.FullGeneratedName); writer.Write(")"); return; } else if ((expression.Operator == Operator.EqualEqualEqual) || (expression.Operator == Operator.NotEqualEqual)) { LiteralExpression literalExpression = expression.RightOperand as LiteralExpression; if (literalExpression != null) { // Optimize generated script to perform loose equality checks for false-y values // (null, false, 0, empty string) // TODO: This should really be happening at compilation time, rather than generation // time. Because this is happening at generation time, we get something like // if (!!x) when if(x) would suffice just so we can get // foo(!!x) where foo is a method expecting a boolean. // Doing this at compilation time would allow handling if scenarios specially. bool optimizable = false; bool checkForFalse = false; if (literalExpression.Value is bool) { optimizable = true; bool compareValue = (bool)literalExpression.Value; if ((compareValue && (expression.Operator == Operator.NotEqualEqual)) || (!compareValue && (expression.Operator == Operator.EqualEqualEqual))) { checkForFalse = true; } } else if ((literalExpression.Value is int) && (((int)literalExpression.Value) == 0)) { optimizable = true; checkForFalse = (expression.Operator == Operator.EqualEqualEqual); } else if ((literalExpression.Value is string) && ((string)literalExpression.Value == String.Empty)) { optimizable = true; checkForFalse = (expression.Operator == Operator.EqualEqualEqual); } if (optimizable) { bool parenthesize = false; writer.Write(checkForFalse ? "!" : "!!"); if ((expression.LeftOperand.Parenthesized == false) && ((expression.LeftOperand.Type == ExpressionType.Binary) || (expression.LeftOperand.Type == ExpressionType.Conditional) || (expression.LeftOperand.Type == ExpressionType.InlineScript))) { parenthesize = true; writer.Write("("); } GenerateExpression(generator, symbol, expression.LeftOperand); if (parenthesize) { writer.Write(")"); } return; } } } GenerateExpression(generator, symbol, expression.LeftOperand); writer.Write(OperatorConverter.OperatorToString(expression.Operator)); GenerateExpression(generator, symbol, expression.RightOperand); }
private static void GenerateEnumeration(ScriptGenerator generator, EnumerationSymbol enumSymbol) { ScriptTextWriter writer = generator.Writer; if (enumSymbol.Namespace.Length == 0) { writer.Write("window."); } writer.Write(enumSymbol.FullGeneratedName); writer.WriteTrimmed(" = "); writer.Write("function()"); writer.WriteTrimmed(" { "); if (generator.Options.EnableDocComments) { DocCommentGenerator.GenerateComment(generator, enumSymbol); } writer.Write("};"); writer.WriteNewLine(); writer.Write(enumSymbol.FullGeneratedName); writer.Write(".prototype = {"); writer.Indent++; bool firstValue = true; foreach (MemberSymbol memberSymbol in enumSymbol.Members) { EnumerationFieldSymbol fieldSymbol = memberSymbol as EnumerationFieldSymbol; if (fieldSymbol == null) { continue; } if (firstValue == false) { writer.WriteTrimmed(", "); } writer.WriteNewLine(); writer.Write(fieldSymbol.GeneratedName); writer.WriteTrimmed(": "); if (enumSymbol.UseNamedValues) { writer.Write(Utility.QuoteString(enumSymbol.CreateNamedValue(fieldSymbol))); } else { writer.Write(fieldSymbol.Value); } firstValue = false; } writer.Indent--; writer.WriteNewLine(); writer.WriteTrimmed("}"); writer.WriteSignificantNewLine(); writer.Write(enumSymbol.FullGeneratedName); writer.Write(".registerEnum('"); writer.Write(enumSymbol.FullGeneratedName); writer.WriteTrimmed("', "); writer.Write(enumSymbol.Flags ? "true" : "false"); writer.Write(");"); writer.WriteNewLine(); }