Ejemplo n.º 1
0
        private static string CreateTypeArgumentName(TypeSymbol typeArgument)
        {
            if (typeArgument is GenericParameterSymbol parameterSymbol)
            {
                if (parameterSymbol.Owner is ClassSymbol)
                {
                    return($"{DSharpStringResources.ScriptExportMember("getTypeArgument")}(this, '{typeArgument.FullGeneratedName}')");
                }

                return($"{DSharpStringResources.GeneratedScript.GENERIC_ARGS_PARAMETER_NAME}['{typeArgument.FullGeneratedName}']");
            }

            if (typeArgument.IsGeneric)
            {
                StringBuilder stringBuilder = new StringBuilder();

                //Local method to recursively write the string.
                void Write(string value) => stringBuilder.Append(value);

                stringBuilder.Append(DSharpStringResources.ScriptExportMember("getGenericConstructor"));
                stringBuilder.Append("(");
                stringBuilder.Append(typeArgument.FullGeneratedName);
                stringBuilder.Append(", ");
                WriteGenericTypeArguments(Write, typeArgument.GenericArguments, typeArgument.GenericParameters);
                stringBuilder.Append(")");
                return(stringBuilder.ToString());
            }

            return(typeArgument.FullGeneratedName);
        }
Ejemplo n.º 2
0
        private static void GenerateClassRegistrationScript(ScriptGenerator generator, ClassSymbol classSymbol)
        {
            ScriptTextWriter writer = generator.Writer;

            //class definition
            writer.Write($"{DSharpStringResources.ScriptExportMember("defineClass")}(");
            writer.Write(classSymbol.FullGeneratedName);
            writer.Write(", ");

            if (classSymbol.IsStaticClass)
            {
                writer.Write("null, ");
            }
            else
            {
                writer.Write(classSymbol.FullGeneratedName);
                writer.Write("$, ");
            }

            WriteConstructorParameters(classSymbol, writer);
            WriteBaseClass(classSymbol, writer);
            WriteInterfaces(writer, classSymbol.Interfaces);

            writer.Write(")");
        }
Ejemplo n.º 3
0
        private static void GenerateInterfaceRegistrationScript(ScriptGenerator generator,
                                                                InterfaceSymbol interfaceSymbol)
        {
            ScriptTextWriter writer = generator.Writer;

            writer.Write($"{DSharpStringResources.ScriptExportMember("defineInterface")}(");
            writer.Write(interfaceSymbol.FullGeneratedName);

            if (interfaceSymbol.Interfaces != null)
            {
                writer.Write(", [");
                bool first = true;

                foreach (InterfaceSymbol inheritedInterface in interfaceSymbol.Interfaces)
                {
                    if (!first)
                    {
                        writer.Write(", ");
                    }

                    writer.Write(inheritedInterface.FullGeneratedName);
                    first = false;
                }

                writer.Write("]");
            }

            writer.Write(")");
        }
Ejemplo n.º 4
0
        private static void GenerateBaseInitializerExpression(ScriptGenerator generator, MemberSymbol symbol,
                                                              BaseInitializerExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            Debug.Assert(symbol.Parent is ClassSymbol);

            ClassSymbol baseClass = ((ClassSymbol)symbol.Parent).BaseClass;

            Debug.Assert(baseClass != null);

            if (baseClass.GenericArguments?.Any() ?? false)
            {
                writer.Write(DSharpStringResources.ScriptExportMember("getGenericConstructor"));
                writer.Write("(");
                writer.Write(baseClass.FullGeneratedName);
                writer.Write(", ");
                generator.WriteGenericTypeArgumentsMap(baseClass.GenericArguments, baseClass.GenericParameters);
                writer.Write(")");
            }
            else
            {
                writer.Write(baseClass.FullGeneratedName);
            }

            writer.Write(".call(this");

            if (expression.Parameters != null)
            {
                writer.Write(", ");
                GenerateExpressionList(generator, symbol, expression.Parameters);
            }

            writer.Write(")");
        }
Ejemplo n.º 5
0
        //TODO: Investigate removing these.
        private void ImportPseudoMembers(PseudoClassMembers memberSet, ClassSymbol classSymbol)
        {
            // Import pseudo members that go on the class but aren't defined in mscorlib.dll
            // These are meant to be used by internal compiler-generated transformations etc.
            // and aren't meant to be referenced directly in C# code.

            if (memberSet == PseudoClassMembers.Script)
            {
                AddScriptSymbolPseudoMembers(classSymbol);

                return;
            }

            if (memberSet == PseudoClassMembers.Arguments)
            {
                TypeSymbol objectType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Object), null,
                                                                                   SymbolFilter.Types);
                Debug.Assert(objectType != null);

                IndexerSymbol indexer = new IndexerSymbol(classSymbol, objectType,
                                                          MemberVisibility.Public | MemberVisibility.Static);
                indexer.SetScriptIndexer();
                classSymbol.AddMember(indexer);

                return;
            }

            if (memberSet == PseudoClassMembers.Dictionary)
            {
                TypeSymbol intType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Int32), null, SymbolFilter.Types);
                Debug.Assert(intType != null);

                TypeSymbol stringType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(String), null,
                                                                                   SymbolFilter.Types);
                Debug.Assert(stringType != null);

                // Define Dictionary.Keys
                MethodSymbol getKeysMethod = new MethodSymbol("GetKeys", classSymbol,
                                                              symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static);
                getKeysMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keys"));
                classSymbol.AddMember(getKeysMethod);

                // Define Dictionary.Values
                MethodSymbol getValuesMethod = new MethodSymbol("GetValues", classSymbol,
                                                                symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static);
                getValuesMethod.SetTransformName(DSharpStringResources.ScriptExportMember("values"));
                classSymbol.AddMember(getValuesMethod);

                // Define Dictionary.GetCount
                MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType,
                                                            MemberVisibility.Public | MemberVisibility.Static);
                countMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keyCount"));
                classSymbol.AddMember(countMethod);
            }
        }
Ejemplo n.º 6
0
        internal static string GetNodeTransformName(this ParseNodeList parseNodeList)
        {
            string dsharpMemberName = parseNodeList?.GetAttributeValue(DSharpStringResources.DSHARP_MEMBER_NAME_ATTRIBUTE);

            if (!string.IsNullOrEmpty(dsharpMemberName))
            {
                return(DSharpStringResources.ScriptExportMember(dsharpMemberName));
            }

            return(parseNodeList?.GetAttributeValue(DSharpStringResources.SCRIPT_ALIAS_ATTRIBUTE));
        }
Ejemplo n.º 7
0
        private static void GenerateEnumerationRegistrationScript(
            ScriptGenerator generator,
            EnumerationSymbol enumerationSymbol)
        {
            ScriptTextWriter writer = generator.Writer;

            writer.Write($"new {DSharpStringResources.ScriptExportMember("Enum")}(");
            writer.Write($"'{enumerationSymbol.FullGeneratedName}'");
            writer.Write(", ");
            writer.Write(enumerationSymbol.FullGeneratedName);
            writer.Write(")");
        }
Ejemplo n.º 8
0
        private static void GenerateEnumeration(ScriptGenerator generator, EnumerationSymbol enumSymbol)
        {
            ScriptTextWriter writer   = generator.Writer;
            string           enumName = enumSymbol.FullGeneratedName;

            writer.Write("var ");
            writer.Write(enumName);
            writer.Write(" = new ");
            writer.Write(DSharpStringResources.ScriptExportMember("Enum"));
            writer.Write("('");
            writer.Write(enumName);
            writer.Write("', ");
            writer.Write("{");
            writer.Indent++;

            bool firstValue = true;

            foreach (MemberSymbol memberSymbol in enumSymbol.Members)
            {
                if (!(memberSymbol is EnumerationFieldSymbol fieldSymbol))
                {
                    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();
        }
Ejemplo n.º 9
0
        private static string CreateTypeArgumentName(TypeSymbol typeArgument, bool writeNameMap)
        {
            if (typeArgument.SymbolSet.ResolveIntrinsicType(IntrinsicType.Nullable).Name == typeArgument.Name)
            {
                return(CreateTypeArgumentName(typeArgument.GenericArguments.First(), writeNameMap));
            }

            if (typeArgument is GenericParameterSymbol parameterSymbol)
            {
                if (writeNameMap)
                {
                    return($"'{typeArgument.FullGeneratedName}'");
                }

                if (parameterSymbol.Owner is ClassSymbol owner)
                {
                    return($"{DSharpStringResources.ScriptExportMember("getTypeArgument")}(this, '{typeArgument.FullGeneratedName}', {owner.FullGeneratedName})");
                }

                return($"{DSharpStringResources.GeneratedScript.GENERIC_ARGS_PARAMETER_NAME}['{typeArgument.FullGeneratedName}']");
            }

            if (typeArgument.Type == SymbolType.Delegate)
            {
                return("Function");
            }

            if (typeArgument.IsGeneric)
            {
                StringBuilder stringBuilder = new StringBuilder();

                //Local method to recursively write the string.
                void Write(string value) => stringBuilder.Append(value);

                stringBuilder.Append(DSharpStringResources.ScriptExportMember("getGenericConstructor"));
                stringBuilder.Append("(");
                stringBuilder.Append(typeArgument.FullGeneratedName);
                stringBuilder.Append(", ");
                WriteGenericTypeArguments(Write, typeArgument.GenericArguments, typeArgument.GenericParameters);
                stringBuilder.Append(")");
                return(stringBuilder.ToString());
            }

            return(typeArgument.FullGeneratedName);
        }
Ejemplo n.º 10
0
        private static void GeneratePropertySetter(ScriptGenerator generator, string typeName,
                                                   PropertySymbol propertySymbol, ScriptTextWriter writer,
                                                   bool instanceMember)
        {
            ParameterSymbol valueParameter = propertySymbol.Parameters[0];

            if (instanceMember)
            {
                writer.Write("$set_");
                writer.Write(propertySymbol.GeneratedName);
                writer.Write(": ");
            }
            else
            {
                writer.Write($"{DSharpStringResources.ScriptExportMember("createPropertySet")}(");
                writer.Write(typeName);
                writer.Write(", '");
                writer.Write(propertySymbol.GeneratedName);
                writer.Write("', ");
            }

            writer.Write("function(");
            writer.Write(valueParameter.GeneratedName);
            writer.WriteLine(") {");
            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.WriteLine();
            writer.Indent--;
            writer.Write("}");

            if (instanceMember == false)
            {
                writer.WriteLine(");");
            }
        }
Ejemplo n.º 11
0
        public static string GetTransformedName(ICustomAttributeProvider attributeProvider)
        {
            CustomAttribute dsharpScriptMemberName = GetAttribute(attributeProvider, "System.Runtime.CompilerServices.DSharpScriptMemberNameAttribute");

            if (dsharpScriptMemberName != null)
            {
                return(DSharpStringResources.ScriptExportMember(GetAttributeArgument(dsharpScriptMemberName)));
            }

            CustomAttribute scriptAliasAttribute =
                GetAttribute(attributeProvider, "System.Runtime.CompilerServices.ScriptAliasAttribute");

            if (scriptAliasAttribute != null)
            {
                return(GetAttributeArgument(scriptAliasAttribute));
            }

            return(null);
        }
Ejemplo n.º 12
0
        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;
            }

            if (propertySymbol.HasGetter)
            {
                GeneratePropertyGetter(generator, typeName, propertySymbol, writer, instanceMember);
            }

            if (propertySymbol.HasSetter)
            {
                if (instanceMember && propertySymbol.HasGetter)
                {
                    writer.WriteLine(",");
                }

                GeneratePropertySetter(generator, typeName, propertySymbol, writer, instanceMember);
            }

            if (propertySymbol.Visibility.HasFlag(MemberVisibility.Static) && propertySymbol.IsAutoProperty())
            {
                writer.Write(DSharpStringResources.ScriptExportMember("defineProperty"));
                writer.Write($"({((ClassSymbol)propertySymbol.Parent).FullGeneratedName}, '{propertySymbol.GeneratedName}');");
                writer.WriteLine();
            }
        }
Ejemplo n.º 13
0
        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)
            {
                writer.Write(typeName);
                writer.Write(".");
            }

            writer.Write(methodSymbol.GeneratedMemberName);

            if (instanceMember)
            {
                writer.Write(": ");
            }
            else
            {
                writer.Write(" = ");
            }

            bool hasParams = HasParamsModifier(methodSymbol);

            if (hasParams)
            {
                writer.Write($"{DSharpStringResources.ScriptExportMember("paramsGenerator")}(");
                writer.Write("{0}, ", methodSymbol.GetGeneratedParamsCount());
            }

            writer.Write("function(");
            WriteParameters(methodSymbol, writer, true);

            writer.WriteLine(") {");
            writer.Indent++;

            if (generator.Options.EnableDocComments)
            {
                DocCommentGenerator.GenerateComment(generator, methodSymbol);
            }

            CodeGenerator.GenerateScript(generator, methodSymbol);
            writer.Indent--;
            writer.Write("}");

            if (hasParams)
            {
                writer.Write(")");
            }

            if (instanceMember == false)
            {
                writer.WriteLine(";");
            }
        }
Ejemplo n.º 14
0
        private static void GenerateEvent(ScriptGenerator generator, string typeName, EventSymbol eventSymbol)
        {
            ScriptTextWriter writer = generator.Writer;

            ParameterSymbol valueParameter = eventSymbol.Parameters[0];

            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.Write(": ");
            }
            else
            {
                writer.Write(" = ");
            }

            writer.Write("function(");
            writer.Write(valueParameter.GeneratedName);
            writer.WriteLine(") {");
            writer.Indent++;

            if (generator.Options.EnableDocComments)
            {
                DocCommentGenerator.GenerateComment(generator, eventSymbol);
            }

            if (eventSymbol.DefaultImplementation)
            {
                writer.Write(fieldReference);
                writer.Write($" = {DSharpStringResources.ScriptExportMember("bindAdd")}(");
                writer.Write(fieldReference);
                writer.Write(", ");
                writer.Write(valueParameter.GeneratedName);
                writer.WriteLine(");");
            }
            else
            {
                CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ true);
            }

            writer.Indent--;
            writer.Write("}");

            if (instanceMember == false)
            {
                writer.WriteLine(";");
            }

            if (instanceMember)
            {
                writer.WriteLine(",");
            }
            else
            {
                writer.Write(typeName);
                writer.Write(".");
            }

            writer.Write("remove_");
            writer.Write(eventName);

            if (instanceMember)
            {
                writer.Write(": ");
            }
            else
            {
                writer.Write(" = ");
            }

            writer.Write("function(");
            writer.Write(valueParameter.GeneratedName);
            writer.WriteLine(") {");
            writer.Indent++;

            if (generator.Options.EnableDocComments)
            {
                DocCommentGenerator.GenerateComment(generator, eventSymbol);
            }

            if (eventSymbol.DefaultImplementation)
            {
                writer.Write(fieldReference);
                writer.Write($" = {DSharpStringResources.ScriptExportMember("bindSub")}(");
                writer.Write(fieldReference);
                writer.Write(", ");
                writer.Write(valueParameter.GeneratedName);
                writer.WriteLine(");");
            }
            else
            {
                CodeGenerator.GenerateScript(generator, eventSymbol, /* add */ false);
            }

            writer.Indent--;
            writer.Write("}");

            if (instanceMember == false)
            {
                writer.WriteLine(";");
            }
        }
Ejemplo n.º 15
0
        private static void GenerateClassConstructor(ScriptGenerator generator, ClassSymbol classSymbol, ScriptTextWriter writer, string name)
        {
            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 (var property in GetNonReadonlyAutoProperties(classSymbol))
            {
                writer.Write(DSharpStringResources.ScriptExportMember("defineProperty"));
                writer.Write($"(this, '{property.GeneratedName}');");
                writer.WriteLine();
            }

            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)
            {
                writer.Write(classSymbol.BaseClass.FullGeneratedName);
                writer.Write(".call(this);");
                writer.WriteLine();
            }

            writer.Indent--;
            writer.WriteLine("}");
        }
Ejemplo n.º 16
0
        private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSymbol symbol,
                                                     BinaryExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            if (expression.Operator == Operator.Equals)
            {
                if (expression.LeftOperand is PropertyExpression propExpression)
                {
                    Debug.Assert(propExpression.Type == ExpressionType.PropertySet);

                    if (propExpression.ObjectReference is BaseExpression)
                    {
                        ClassSymbol classSymbol = (ClassSymbol)symbol.Parent;
                        writer.Write($"{DSharpStringResources.ScriptExportMember("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);
                    }

                    propExpression.Property.IncrementReferenceCount();
                    return;
                }

                if (expression.LeftOperand is IndexerExpression indexExpression)
                {
                    IndexerSymbol indexerSymbol = indexExpression.Indexer;

                    if (!indexerSymbol.UseScriptIndexer)
                    {
                        Debug.Assert(indexExpression.Type == ExpressionType.Indexer);

                        if (indexExpression.ObjectReference is BaseExpression objectReference)
                        {
                            writer.Write(objectReference.EvaluatedType.FullGeneratedName);
                            writer.Write(".prototype.set_");
                            writer.Write(indexerSymbol.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
                        {
                            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(")");
                        }

                        indexExpression.Indexer.IncrementReferenceCount();
                        return;
                    }
                    else if (indexerSymbol.Parent is TypeSymbol typeSymbol && !typeSymbol.IsNativeArray)
                    {
                        writer.Write($"ss.setItem(");
                        GenerateExpression(generator, symbol, indexExpression.ObjectReference);
                        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)
            {
                if (expression.LeftOperand is PropertyExpression propExpression)
                {
                    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);

                    propExpression.Property.IncrementReferenceCount();
                    return;
                }
            }
            else if (expression.Operator == Operator.Is ||
                     expression.Operator == Operator.As)
            {
                TypeExpression typeExpression = expression.RightOperand as TypeExpression;
                Debug.Assert(typeExpression != null);

                writer.Write(DSharpStringResources.ScriptExportMember(string.Empty));

                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(")");
                typeExpression.AssociatedType.IncrementReferenceCount();
                return;
            }
            else if (expression.Operator == Operator.EqualEqualEqual ||
                     expression.Operator == Operator.NotEqualEqual)
            {
                if (expression.RightOperand is LiteralExpression literalExpression)
                {
                    // 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 compareValue)
                    {
                        optimizable = true;

                        if (compareValue && expression.Operator == Operator.NotEqualEqual ||
                            !compareValue && expression.Operator == Operator.EqualEqualEqual)
                        {
                            checkForFalse = true;
                        }
                    }
                    else if (literalExpression.Value is int i && i == 0)
                    {
                        optimizable   = true;
                        checkForFalse = expression.Operator == Operator.EqualEqualEqual;
                    }
                    else if (literalExpression.Value is string s && s == 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;
                    }
                }
            }
Ejemplo n.º 17
0
        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.IsExtension)
                {
                    string extendee = null;

                    if (methodSymbol.Parent.Type == SymbolType.Class)
                    {
                        extendee = ((ClassSymbol)methodSymbol.Parent).Extendee;
                    }

                    if (string.IsNullOrEmpty(extendee))
                    {
                        extendee = "this";
                    }

                    writer.Write(extendee);
                }
                else
                {
                    writer.Write(typeName);
                }

                writer.Write(".");
            }

            writer.Write(methodSymbol.GeneratedMemberName);

            if (instanceMember)
            {
                writer.Write(": ");
            }
            else
            {
                writer.Write(" = ");
            }

            bool hasParams = HasParamsModifier(methodSymbol);

            if (hasParams)
            {
                writer.Write($"{DSharpStringResources.ScriptExportMember("paramsGenerator")}(");
                writer.Write("{0}, ", methodSymbol.Parameters.Count - 1);
            }

            writer.Write("function(");
            WriteParameters(methodSymbol, writer);

            writer.WriteLine(") {");
            writer.Indent++;

            if (generator.Options.EnableDocComments)
            {
                DocCommentGenerator.GenerateComment(generator, methodSymbol);
            }

            CodeGenerator.GenerateScript(generator, methodSymbol);
            writer.Indent--;
            writer.Write("}");

            if (hasParams)
            {
                writer.Write(")");
            }

            if (instanceMember == false)
            {
                writer.WriteLine(";");
            }
        }
Ejemplo n.º 18
0
        private static void GenerateClassConstructor(ScriptGenerator generator, ClassSymbol classSymbol, ScriptTextWriter writer, string name)
        {
            var ctorSymbol = classSymbol.Constructor;

            if (HasParamsModifier(ctorSymbol))
            {
                writer.Write($"var {name} = ss.namedFunction('{name}',");
                writer.Write($"{DSharpStringResources.ScriptExportMember("paramsGenerator")}(");
                writer.Write($"{ctorSymbol.GetGeneratedParamsCount()}, function");
            }
            else
            {
                writer.Write("function ");
                writer.Write(name);
            }

            writer.Write("(");

            if (ctorSymbol != null && ctorSymbol.Parameters != null)
            {
                bool firstParameter = true;

                foreach (ParameterSymbol parameterSymbol in ctorSymbol.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 (var property in GetNonReadonlyAutoProperties(classSymbol))
            {
                writer.Write(DSharpStringResources.ScriptExportMember("defineProperty"));
                writer.Write($"(this, '{property.GeneratedName}', ");

                var initialValueExpression = Compiler.ImplementationBuilder.GetDefaultValueExpression(property.AssociatedType, property.SymbolSet);
                ExpressionGenerator.GenerateLiteralExpression(generator, property, initialValueExpression);

                writer.Write(");");
                writer.WriteLine();
            }

            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 (ctorSymbol != null)
            {
                CodeGenerator.GenerateScript(generator, ctorSymbol);
            }
            else if (classSymbol.BaseClass is ClassSymbol baseClass)
            {
                ExpressionGenerator.WriteFullTypeName(writer, baseClass);
                writer.WriteLine(".call(this);");
            }

            writer.Indent--;
            writer.WriteLine("}");

            if (HasParamsModifier(ctorSymbol))
            {
                writer.WriteLine($"));");
            }
        }
Ejemplo n.º 19
0
        private static void GenerateClassRegistrationScript(ScriptGenerator generator, ClassSymbol classSymbol)
        {
            ScriptTextWriter writer = generator.Writer;

            //class definition
            writer.Write($"{DSharpStringResources.ScriptExportMember("defineClass")}(");
            writer.Write(classSymbol.FullGeneratedName);
            writer.Write(", ");

            if (classSymbol.IsStaticClass)
            {
                writer.Write("null, ");
            }
            else
            {
                writer.Write(classSymbol.FullGeneratedName);
                writer.Write("$, ");
            }

            //constructor params
            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(", ");
                    }

                    TypeSymbol parameterType     = parameterSymbol.ValueType;
                    string     parameterTypeName = GetParameterTypeName(parameterType);
                    writer.Write(parameterTypeName);
                    firstParameter = false;
                }
            }

            writer.Write("], ");

            //base class
            if (classSymbol.BaseClass == null)
            {
                // 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);
            }

            //interfaces
            if (classSymbol.Interfaces != null)
            {
                writer.Write(", [");
                bool first = true;

                foreach (InterfaceSymbol inheritedInterface in classSymbol.Interfaces)
                {
                    if (!first)
                    {
                        writer.Write(", ");
                    }

                    string parameterTypeName = GetParameterTypeName(inheritedInterface);
                    writer.Write(parameterTypeName);
                    first = false;
                }

                writer.Write("]");
            }

            writer.Write(")");
        }
Ejemplo n.º 20
0
        private void AddScriptSymbolPseudoMembers(ClassSymbol classSymbol)
        {
            var symbolTable = symbols.SystemNamespace;

            TypeSymbol objectType = symbolTable.FindSymbol <TypeSymbol>(nameof(Object), null, SymbolFilter.Types);
            TypeSymbol stringType = symbolTable.FindSymbol <TypeSymbol>(nameof(String), null, SymbolFilter.Types);
            TypeSymbol boolType   = symbolTable.FindSymbol <TypeSymbol>(nameof(Boolean), null, SymbolFilter.Types);
            TypeSymbol dateType   = symbolTable.FindSymbol <TypeSymbol>("Date", null, SymbolFilter.Types);
            TypeSymbol voidType   = symbols.ResolveIntrinsicType(IntrinsicType.Void);
            TypeSymbol typeSymbol = symbols.ResolveIntrinsicType(IntrinsicType.Type);

            Debug.Assert(objectType != null);
            Debug.Assert(stringType != null);
            Debug.Assert(boolType != null);
            Debug.Assert(dateType != null);
            Debug.Assert(voidType != null);

            // Enumerate - IEnumerable.GetEnumerator gets mapped to this

            MethodSymbol enumerateMethod = new MethodSymbol("Enumerate", classSymbol, objectType,
                                                            MemberVisibility.Public | MemberVisibility.Static);

            enumerateMethod.SetTransformName(DSharpStringResources.ScriptExportMember("enumerate"));
            enumerateMethod.AddParameter(new ParameterSymbol("obj", enumerateMethod, objectType, ParameterMode.In));
            classSymbol.AddMember(enumerateMethod);

            // TypeName - Type.Name gets mapped to this

            MethodSymbol typeNameMethod = new MethodSymbol("GetTypeName", classSymbol, stringType,
                                                           MemberVisibility.Public | MemberVisibility.Static);

            typeNameMethod.SetTransformName(DSharpStringResources.ScriptExportMember("typeName"));
            typeNameMethod.AddParameter(new ParameterSymbol("obj", typeNameMethod, objectType, ParameterMode.In));
            classSymbol.AddMember(typeNameMethod);

            // CompareDates - Date equality checks get converted to call to compareDates

            MethodSymbol compareDatesMethod = new MethodSymbol("CompareDates", classSymbol, boolType,
                                                               MemberVisibility.Public | MemberVisibility.Static);

            compareDatesMethod.SetTransformName(DSharpStringResources.ScriptExportMember("compareDates"));
            compareDatesMethod.AddParameter(new ParameterSymbol("d1", compareDatesMethod, dateType,
                                                                ParameterMode.In));
            compareDatesMethod.AddParameter(new ParameterSymbol("d2", compareDatesMethod, dateType,
                                                                ParameterMode.In));
            classSymbol.AddMember(compareDatesMethod);

            //createReadonlyPropertyMethod - setups a replacement for readonly assignment expressions to generate readonly properties.

            MethodSymbol createReadonlyPropertyMethod
                = new MethodSymbol("CreateReadonlyProperty", classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static);

            createReadonlyPropertyMethod.SetTransformName(DSharpStringResources.ScriptExportMember("createReadonlyProperty"));

            createReadonlyPropertyMethod.AddParameter(new ParameterSymbol("instance", createReadonlyPropertyMethod, objectType, ParameterMode.In));
            createReadonlyPropertyMethod.AddParameter(new ParameterSymbol("propertyName", createReadonlyPropertyMethod, stringType, ParameterMode.In));
            createReadonlyPropertyMethod.AddParameter(new ParameterSymbol("value", createReadonlyPropertyMethod, objectType, ParameterMode.In));

            classSymbol.AddMember(createReadonlyPropertyMethod);

            MethodSymbol definePropertyMethod = new MethodSymbol("DefineMethod", classSymbol, voidType, MemberVisibility.Public | MemberVisibility.Static);

            definePropertyMethod.SetTransformName(DSharpStringResources.ScriptExportMember("defineProperty"));

            definePropertyMethod.AddParameter(new ParameterSymbol("instance", definePropertyMethod, objectType, ParameterMode.In));
            definePropertyMethod.AddParameter(new ParameterSymbol("propertyName", definePropertyMethod, stringType, ParameterMode.In));

            classSymbol.AddMember(definePropertyMethod);

            MethodSymbol getGenericConstructorMethod
                = new MethodSymbol("getGenericConstructor", classSymbol, typeSymbol, MemberVisibility.Public | MemberVisibility.Static);

            getGenericConstructorMethod.SetTransformName(DSharpStringResources.ScriptExportMember("getGenericConstructor"));
            getGenericConstructorMethod.AddParameter(
                new ParameterSymbol("ctorMethod", getGenericConstructorMethod, typeSymbol, ParameterMode.In));
            getGenericConstructorMethod.AddParameter(
                new ParameterSymbol("typeArguments", getGenericConstructorMethod, objectType, ParameterMode.In));

            classSymbol.AddMember(getGenericConstructorMethod);

            MethodSymbol getTypeArgument
                = new MethodSymbol("getTypeArgument", classSymbol, typeSymbol, MemberVisibility.Public | MemberVisibility.Static);

            getTypeArgument.SetTransformName(DSharpStringResources.ScriptExportMember("getTypeArgument"));
            getTypeArgument.AddParameter(
                new ParameterSymbol("instance", getTypeArgument, objectType, ParameterMode.In));
            getTypeArgument.AddParameter(
                new ParameterSymbol("typeArgumentName", getTypeArgument, stringType, ParameterMode.In));
            getTypeArgument.AddParameter(
                new ParameterSymbol("templateType", getTypeArgument, typeSymbol, ParameterMode.In));
            classSymbol.AddMember(getTypeArgument);

            MethodSymbol getGenericTemplateMethod
                = new MethodSymbol("getGenericTemplate", classSymbol, typeSymbol, MemberVisibility.Public | MemberVisibility.Static);

            getGenericTemplateMethod.SetTransformName(DSharpStringResources.ScriptExportMember("getGenericTemplate"));
            getGenericTemplateMethod.AddParameter(
                new ParameterSymbol("ctorMethod", getGenericTemplateMethod, typeSymbol, ParameterMode.In));
            getGenericTemplateMethod.AddParameter(
                new ParameterSymbol("typeParameters", getGenericTemplateMethod, objectType, ParameterMode.In));

            classSymbol.AddMember(getGenericTemplateMethod);
        }
Ejemplo n.º 21
0
        private void GenerateModuleExports(SymbolSet symbolSet, IEnumerable <TypeSymbol> types)
        {
            if (!types.Any())
            {
                return;
            }

            IEnumerable <TypeSymbol> publicTypes   = types.Where(type => type.IsPublic);
            IEnumerable <TypeSymbol> internalTypes = types.Where(type => type.IsInternal);

            Writer.Write($"var $exports = {DSharpStringResources.ScriptExportMember("module")}('");
            Writer.Write(symbolSet.ScriptName);
            Writer.Write("',");

            if (internalTypes.Any())
            {
                Writer.WriteLine();
                Writer.Indent++;
                Writer.WriteLine("{");
                Writer.Indent++;
                bool firstType = true;

                foreach (TypeSymbol type in internalTypes)
                {
                    if (type.Type == SymbolType.Record && ((RecordSymbol)type).Constructor == null)
                    {
                        continue;
                    }

                    if (firstType == false)
                    {
                        Writer.WriteLine(",");
                    }

                    TypeGenerator.GenerateRegistrationScript(this, type);
                    firstType = false;
                }

                Writer.Indent--;
                Writer.WriteLine();
                Writer.Write("},");
                Writer.Indent--;
            }
            else
            {
                Writer.Write(" null,");
            }

            if (publicTypes.Any())
            {
                Writer.WriteLine();
                Writer.Indent++;
                Writer.WriteLine("{");
                Writer.Indent++;
                bool firstType = true;

                foreach (TypeSymbol type in publicTypes)
                {
                    if (firstType == false)
                    {
                        Writer.WriteLine(",");
                    }

                    TypeGenerator.GenerateRegistrationScript(this, type);
                    firstType = false;
                }

                Writer.Indent--;
                Writer.WriteLine();
                Writer.Write("}");
                Writer.Indent--;
            }
            else
            {
                Writer.Write(" null");
            }

            Writer.WriteLine(");");
            Writer.WriteLine();
        }
Ejemplo n.º 22
0
        public void GenerateScript(SymbolSet symbolSet)
        {
            Debug.Assert(symbolSet != null);

            List <TypeSymbol> types         = new List <TypeSymbol>();
            List <TypeSymbol> publicTypes   = new List <TypeSymbol>();
            List <TypeSymbol> internalTypes = new List <TypeSymbol>();

            bool hasNonModuleInternalTypes = false;

            foreach (NamespaceSymbol namespaceSymbol in symbolSet.Namespaces)
            {
                if (namespaceSymbol.HasApplicationTypes)
                {
                    foreach (TypeSymbol type in namespaceSymbol.Types)
                    {
                        if (type.IsApplicationType == false)
                        {
                            continue;
                        }

                        if (type.Type == SymbolType.Delegate)
                        {
                            // Nothing needs to be generated for delegate types.
                            continue;
                        }

                        if (type.Type == SymbolType.Enumeration &&
                            (type.IsPublic == false || ((EnumerationSymbol)type).Constants))
                        {
                            // Internal enums can be skipped since their values have been inlined.
                            // Public enums marked as constants can also be skipped since their
                            // values will always be inlined.
                            continue;
                        }

                        types.Add(type);

                        if (type.IsPublic)
                        {
                            publicTypes.Add(type);
                        }
                        else
                        {
                            if (type.Type != SymbolType.Class ||
                                ((ClassSymbol)type).IsModuleClass == false)
                            {
                                hasNonModuleInternalTypes = true;
                            }

                            internalTypes.Add(type);
                        }
                    }
                }
            }

            // Sort the types, so similar types of types are grouped, and parent classes
            // come before derived classes.
            IComparer <TypeSymbol> typeComparer = new TypeComparer();

            types         = types.OrderBy(t => t, typeComparer).ToList();
            publicTypes   = publicTypes.OrderBy(t => t, typeComparer).ToList();
            internalTypes = internalTypes.OrderBy(t => t, typeComparer).ToList();

            bool initialIndent = false;

            if (string.IsNullOrEmpty(Options.ScriptInfo.Template) == false)
            {
                int scriptIndex = Options.ScriptInfo.Template.IndexOf("{script}");

                if (scriptIndex > 0 && Options.ScriptInfo.Template[scriptIndex - 1] == ' ')
                {
                    // Heuristic to turn on initial indent:
                    // The script template has a space prior to {script}, i.e. {script} is not the
                    // first thing on a line within the template.

                    initialIndent = true;
                }
            }

            if (initialIndent)
            {
                Writer.Indent++;
            }

            foreach (TypeSymbol type in types)
            {
                TypeGenerator.GenerateScript(this, type);
            }

            bool generateModule = publicTypes.Count != 0 ||
                                  internalTypes.Count != 0 && hasNonModuleInternalTypes;

            if (generateModule)
            {
                Writer.Write($"var $exports = {DSharpStringResources.ScriptExportMember("module")}('");
                Writer.Write(symbolSet.ScriptName);
                Writer.Write("',");

                if (internalTypes.Count != 0 && hasNonModuleInternalTypes)
                {
                    Writer.WriteLine();
                    Writer.Indent++;
                    Writer.WriteLine("{");
                    Writer.Indent++;
                    bool firstType = true;

                    foreach (TypeSymbol type in internalTypes)
                    {
                        if (type.Type == SymbolType.Class &&
                            (((ClassSymbol)type).IsExtenderClass || ((ClassSymbol)type).IsModuleClass))
                        {
                            continue;
                        }

                        if (type.Type == SymbolType.Record &&
                            ((RecordSymbol)type).Constructor == null)
                        {
                            continue;
                        }

                        if (firstType == false)
                        {
                            Writer.WriteLine(",");
                        }

                        TypeGenerator.GenerateRegistrationScript(this, type);
                        firstType = false;
                    }

                    Writer.Indent--;
                    Writer.WriteLine();
                    Writer.Write("},");
                    Writer.Indent--;
                }
                else
                {
                    Writer.Write(" null,");
                }

                if (publicTypes.Count != 0)
                {
                    Writer.WriteLine();
                    Writer.Indent++;
                    Writer.WriteLine("{");
                    Writer.Indent++;
                    bool firstType = true;

                    foreach (TypeSymbol type in publicTypes)
                    {
                        if (type.Type == SymbolType.Class &&
                            ((ClassSymbol)type).IsExtenderClass)
                        {
                            continue;
                        }

                        if (firstType == false)
                        {
                            Writer.WriteLine(",");
                        }

                        TypeGenerator.GenerateRegistrationScript(this, type);
                        firstType = false;
                    }

                    Writer.Indent--;
                    Writer.WriteLine();
                    Writer.Write("}");
                    Writer.Indent--;
                }
                else
                {
                    Writer.Write(" null");
                }

                Writer.WriteLine(");");
                Writer.WriteLine();
            }

            foreach (TypeSymbol type in types)
            {
                if (type.Type == SymbolType.Class)
                {
                    TypeGenerator.GenerateClassConstructorScript(this, (ClassSymbol)type);
                }
            }

            if (initialIndent)
            {
                Writer.Indent--;
            }
        }
Ejemplo n.º 23
0
        private static void GenerateForInStatement(ScriptGenerator generator, MemberSymbol symbol,
                                                   ForInStatement statement)
        {
            ScriptTextWriter writer        = generator.Writer;
            TypeSymbol       evaluatedType = statement.CollectionExpression.EvaluatedType;

            if (statement.IsDictionaryEnumeration)
            {
                if (statement.DictionaryVariable != null)
                {
                    writer.Write("var ");
                    writer.Write(statement.DictionaryVariable.GeneratedName);
                    writer.Write(" = ");
                    ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                    writer.Write(";");
                    writer.WriteLine();
                }

                writer.Write("for (var ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(" in ");

                if (statement.DictionaryVariable != null)
                {
                    writer.Write(statement.DictionaryVariable.GeneratedName);
                }
                else
                {
                    ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                }

                writer.WriteLine(") {");
                writer.Indent++;
                writer.Write("var ");
                writer.Write(statement.ItemVariable.GeneratedName);
                writer.Write(" = { key: ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(", value: ");

                if (statement.DictionaryVariable != null)
                {
                    writer.Write(statement.DictionaryVariable.GeneratedName);
                }
                else
                {
                    ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                }

                writer.Write("[");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.WriteLine("] };");
                GenerateStatement(generator, symbol, statement.Body);
                writer.Indent--;
                writer.WriteLine("}");
            }
            else if (evaluatedType.IsNativeArray || evaluatedType.IsListType())
            {
                string dataSourceVariableName = statement.LoopVariable.GeneratedName;
                string indexVariableName      = dataSourceVariableName + "_index";

                // var $$ = ({CollectionExpression});
                writer.Write("var " + dataSourceVariableName + " = (");
                ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                writer.WriteLine(");");

                // for(var items_index = 0; items_index < items.length; ++items_index) {
                writer.WriteLine("for(var " + indexVariableName + " = 0; " + indexVariableName + " < " + dataSourceVariableName + ".length; ++" + indexVariableName + ") {");

                ++writer.Indent;

                if (evaluatedType.IsNativeArray)
                {
                    // var i = items[items_index];
                    writer.WriteLine("var " + statement.ItemVariable.GeneratedName + " = " + dataSourceVariableName + "[" + indexVariableName + "];");
                }
                else
                {
                    // var i = ss.getItem(items, items_index);
                    writer.WriteLine("var " + statement.ItemVariable.GeneratedName + " = ss.getItem(" + dataSourceVariableName + ", " + indexVariableName + ");");
                }

                GenerateStatement(generator, symbol, statement.Body);

                --writer.Indent;
                writer.WriteLine("}");
            }
            else
            {
                writer.Write("var ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(" = ");

                writer.Write($"{DSharpStringResources.ScriptExportMember("enumerate")}(");
                ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                writer.Write(");");

                writer.WriteLine();

                writer.Write("while (");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.WriteLine(".moveNext()) {");
                writer.Indent++;

                writer.Write("var ");
                writer.Write(statement.ItemVariable.GeneratedName);
                writer.Write(" = ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(".current;");
                writer.WriteLine();

                GenerateStatement(generator, symbol, statement.Body);

                writer.Indent--;
                writer.Write("}");
                writer.WriteLine();
            }
        }
Ejemplo n.º 24
0
        //TODO: Investigate removing these.
        private void ImportPseudoMembers(PseudoClassMembers memberSet, ClassSymbol classSymbol)
        {
            // Import pseudo members that go on the class but aren't defined in mscorlib.dll
            // These are meant to be used by internal compiler-generated transformations etc.
            // and aren't meant to be referenced directly in C# code.

            if (memberSet == PseudoClassMembers.Script)
            {
                TypeSymbol objectType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol("Object", null,
                                                                                   SymbolFilter.Types);
                Debug.Assert(objectType != null);

                TypeSymbol stringType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol("String", null,
                                                                                   SymbolFilter.Types);
                Debug.Assert(stringType != null);

                TypeSymbol boolType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol("Boolean", null,
                                                                                   SymbolFilter.Types);
                Debug.Assert(boolType != null);

                TypeSymbol dateType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol("Date", null, SymbolFilter.Types);
                Debug.Assert(dateType != null);

                // Enumerate - IEnumerable.GetEnumerator gets mapped to this

                MethodSymbol enumerateMethod = new MethodSymbol("Enumerate", classSymbol, objectType,
                                                                MemberVisibility.Public | MemberVisibility.Static);
                enumerateMethod.SetTransformName(DSharpStringResources.ScriptExportMember("enumerate"));
                enumerateMethod.AddParameter(new ParameterSymbol("obj", enumerateMethod, objectType, ParameterMode.In));
                classSymbol.AddMember(enumerateMethod);

                // TypeName - Type.Name gets mapped to this

                MethodSymbol typeNameMethod = new MethodSymbol("GetTypeName", classSymbol, stringType,
                                                               MemberVisibility.Public | MemberVisibility.Static);
                typeNameMethod.SetTransformName(DSharpStringResources.ScriptExportMember("typeName"));
                typeNameMethod.AddParameter(new ParameterSymbol("obj", typeNameMethod, objectType, ParameterMode.In));
                classSymbol.AddMember(typeNameMethod);

                // CompareDates - Date equality checks get converted to call to compareDates

                MethodSymbol compareDatesMethod = new MethodSymbol("CompareDates", classSymbol, boolType,
                                                                   MemberVisibility.Public | MemberVisibility.Static);
                compareDatesMethod.SetTransformName(DSharpStringResources.ScriptExportMember("compareDates"));
                compareDatesMethod.AddParameter(new ParameterSymbol("d1", compareDatesMethod, dateType,
                                                                    ParameterMode.In));
                compareDatesMethod.AddParameter(new ParameterSymbol("d2", compareDatesMethod, dateType,
                                                                    ParameterMode.In));
                classSymbol.AddMember(compareDatesMethod);

                return;
            }

            if (memberSet == PseudoClassMembers.Arguments)
            {
                TypeSymbol objectType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Object), null,
                                                                                   SymbolFilter.Types);
                Debug.Assert(objectType != null);

                IndexerSymbol indexer = new IndexerSymbol(classSymbol, objectType,
                                                          MemberVisibility.Public | MemberVisibility.Static);
                indexer.SetScriptIndexer();
                classSymbol.AddMember(indexer);

                return;
            }

            if (memberSet == PseudoClassMembers.Dictionary)
            {
                TypeSymbol intType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Int32), null, SymbolFilter.Types);
                Debug.Assert(intType != null);

                TypeSymbol stringType =
                    (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(String), null,
                                                                                   SymbolFilter.Types);
                Debug.Assert(stringType != null);

                // Define Dictionary.Keys
                MethodSymbol getKeysMethod = new MethodSymbol("GetKeys", classSymbol,
                                                              symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static);
                getKeysMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keys"));
                classSymbol.AddMember(getKeysMethod);

                // Define Dictionary.Values
                MethodSymbol getValuesMethod = new MethodSymbol("GetValues", classSymbol,
                                                                symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static);
                getValuesMethod.SetTransformName(DSharpStringResources.ScriptExportMember("values"));
                classSymbol.AddMember(getValuesMethod);

                // Define Dictionary.GetCount
                MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType,
                                                            MemberVisibility.Public | MemberVisibility.Static);
                countMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keyCount"));
                classSymbol.AddMember(countMethod);
            }
        }