Exemplo n.º 1
0
        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(")");
        }
Exemplo n.º 2
0
        private Expression ProcessOpenParenExpressionNode(BinaryExpressionNode node) {
            bool isDelegateInvoke = false;
            Expression leftExpression = BuildExpression(node.LeftChild);

            if (leftExpression is LocalExpression) {
                Debug.Assert(leftExpression.EvaluatedType.Type == SymbolType.Delegate);

                // Handle the implicit delegate invoke scenario by turning the expression
                // into an explicit call into the delegate's Invoke method

                MemberSymbol invokeMethodSymbol = leftExpression.EvaluatedType.GetMember("Invoke");
                Debug.Assert(invokeMethodSymbol != null);

                leftExpression = new MemberExpression(leftExpression, invokeMethodSymbol);
                isDelegateInvoke = true;
            }

            if (leftExpression.Type != ExpressionType.Member) {
                // A method call was evaluated into a non-member expression as part of building
                // the left node. For example, Nullable<T>.GetValueOrDefault() becomes a logical or expression.

                return leftExpression;
            }

            MemberExpression memberExpression = (MemberExpression)leftExpression;

            ExpressionListNode argNodes = null;
            List<Expression> args = null;
            if (node.RightChild != null) {
                Debug.Assert(node.RightChild is ExpressionListNode);

                argNodes = (ExpressionListNode)node.RightChild;
                args = BuildExpressionList(argNodes);
            }

            MethodExpression methodExpression = null;

            if (memberExpression.Member.Type != SymbolType.Method) {
                // A non-method member is being used in a method call; the member must be
                // a delegate...
                Debug.Assert(memberExpression.EvaluatedType.Type == SymbolType.Delegate);
                Expression instanceExpression = TransformMemberExpression(memberExpression);

                MethodSymbol invokeMethod =
                    (MethodSymbol)memberExpression.EvaluatedType.GetMember("Invoke");
                Debug.Assert(invokeMethod != null);

                methodExpression = new MethodExpression(instanceExpression, invokeMethod);
                isDelegateInvoke = true;
            }
            else {
                // The member being accessed is a method...

                // REVIEW: Uggh... this has become too complex over time with all the transformations
                //         added over time. Refactoring needed...

                MethodSymbol method = (MethodSymbol)memberExpression.Member;
                TypeSymbol objectType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Object);
                TypeSymbol typeType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Type);
                TypeSymbol dictionaryType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Dictionary);
                TypeSymbol genericDictionaryType = _symbolSet.ResolveIntrinsicType(IntrinsicType.GenericDictionary);
                TypeSymbol numberType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Number);
                TypeSymbol stringType = _symbolSet.ResolveIntrinsicType(IntrinsicType.String);
                TypeSymbol scriptType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Script);
                TypeSymbol argsType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Arguments);

                if ((method.Parent == objectType) &&
                    method.Name.Equals("GetType", StringComparison.Ordinal)) {
                    // Since we can't extend object's prototype, we need to transform the
                    // natural c# syntax into a static method.
                    // Object.GetType instance method becomes Type.GetInstanceType static method

                    TypeSymbol typeSymbol = typeType;

                    method = (MethodSymbol)typeSymbol.GetMember("GetInstanceType");
                    Debug.Assert(method != null);

                    methodExpression = new MethodExpression(new TypeExpression(typeSymbol, SymbolFilter.Public | SymbolFilter.StaticMembers),
                                                            method);
                    methodExpression.AddParameterValue(memberExpression.ObjectReference);
                    return methodExpression;
                }
                else if ((method.Parent == objectType) &&
                         (method.Name.Equals("ToString", StringComparison.Ordinal) ||
                          method.Name.Equals("ToLocaleString", StringComparison.Ordinal)) &&
                         (memberExpression.ObjectReference.EvaluatedType == stringType)) {
                    // No-op ToString calls on strings (this happens when performing a ToString
                    // on a named enum value.
                    return memberExpression.ObjectReference;
                }
                else if ((method.Parent == objectType) &&
                         (method.Name.Equals("ToString", StringComparison.Ordinal) ||
                          method.Name.Equals("ToLocaleString", StringComparison.Ordinal)) &&
                         (memberExpression.ObjectReference.EvaluatedType is EnumerationSymbol)) {
                    EnumerationSymbol enumSymbol = (EnumerationSymbol)memberExpression.ObjectReference.EvaluatedType;

                    if (enumSymbol.UseNamedValues) {
                        // If the enum value is a named enum, then it is already a string.
                        return memberExpression.ObjectReference;
                    }

                    return new MethodExpression(memberExpression.ObjectReference, method);
                }
                else if (((method.Parent == dictionaryType) || (method.Parent == genericDictionaryType)) &&
                         method.Name.Equals("ContainsKey", StringComparison.Ordinal)) {
                    // Switch the instance ContainsKey method on Dictionary to
                    // calls to the static KeyExists method.
                    Debug.Assert(args.Count == 1);

                    MethodSymbol keyExistsMethod = (MethodSymbol)dictionaryType.GetMember("KeyExists");
                    Debug.Assert(keyExistsMethod != null);

                    methodExpression = new MethodExpression(new TypeExpression(dictionaryType, SymbolFilter.Public | SymbolFilter.StaticMembers),
                                                            keyExistsMethod);
                    methodExpression.AddParameterValue(memberExpression.ObjectReference);
                    methodExpression.AddParameterValue(args[0]);

                    return methodExpression;
                }
                else if (((method.Parent == dictionaryType) || (method.Parent == genericDictionaryType)) &&
                         method.Name.Equals("Remove", StringComparison.Ordinal)) {
                    // Switch the instance Remove method on Dictionary to
                    // calls to the static DeleteKey method.
                    Debug.Assert(args.Count == 1);

                    return new LateBoundExpression(memberExpression.ObjectReference,
                                                   args[0], LateBoundOperation.DeleteField,
                                                   objectType);
                }
                else if (((method.Parent == dictionaryType) || (method.Parent == genericDictionaryType)) &&
                         method.Name.Equals("Clear")) {
                    // Switch the instance Clear method on Dictionary to
                    // calls to the static ClearKeys method.
                    MethodSymbol clearKeysMethod = (MethodSymbol)dictionaryType.GetMember("ClearKeys");
                    Debug.Assert(clearKeysMethod != null);

                    methodExpression = new MethodExpression(new TypeExpression(dictionaryType, SymbolFilter.Public | SymbolFilter.StaticMembers),
                                                            clearKeysMethod);
                    methodExpression.AddParameterValue(memberExpression.ObjectReference);
                    return methodExpression;
                }
                else if (((method.Parent == dictionaryType) || (((TypeSymbol)method.Parent).GenericType == genericDictionaryType)) &&
                         ((method.Visibility & MemberVisibility.Static) != 0) &&
                         method.Name.Equals("GetDictionary", StringComparison.Ordinal)) {
                    // Dictionary.GetDictionary is a no-op method; we're just interested
                    // in the object being passed in.
                    // However we'll re-evaluate the argument to be of dictionary type
                    // so that subsequent use of this expression sees it as a dictionary.
                    Debug.Assert(args.Count == 1);
                    args[0].Reevaluate((TypeSymbol)method.Parent);

                    return args[0];
                }
                else if ((method.Parent == stringType) &&
                         (method.Name.Equals("Escape", StringComparison.Ordinal) ||
                          method.Name.Equals("Unescape", StringComparison.Ordinal) ||
                          method.Name.Equals("EncodeUri", StringComparison.Ordinal) ||
                          method.Name.Equals("DecodeUri", StringComparison.Ordinal) ||
                          method.Name.Equals("EncodeUriComponent", StringComparison.Ordinal) ||
                          method.Name.Equals("DecodeUriComponent", StringComparison.Ordinal))) {
                    // String.<Method> becomes Script.<Method>, as its a global method in script
                    MethodSymbol scriptMethod = (MethodSymbol)scriptType.GetMember(method.Name);

                    methodExpression = new MethodExpression(new TypeExpression(scriptType, SymbolFilter.Public | SymbolFilter.StaticMembers),
                                                            scriptMethod);
                    methodExpression.AddParameterValue(memberExpression.ObjectReference);
                    return methodExpression;
                }
                else if ((method.Parent == scriptType) &&
                         method.Name.Equals("Literal", StringComparison.Ordinal)) {
                    // Convert a call to Script.Literal into a literal expression

                    Debug.Assert(args.Count >= 1);
                    string script = null;

                    if (args[0].Type == ExpressionType.Field) {
                        Debug.Assert(args[0].EvaluatedType == stringType);

                        FieldSymbol field = ((FieldExpression)args[0]).Field;
                        if (field.IsConstant) {
                            Debug.Assert(field.Value is string);
                            script = (string)field.Value;
                        }
                    }
                    else if (args[0].Type == ExpressionType.Literal) {
                        Debug.Assert(((LiteralExpression)args[0]).Value is string);
                        script = (string)((LiteralExpression)args[0]).Value;
                    }

                    if (script == null) {
                        // TODO: When we start raising errors at the expression level instead of the statement
                        //       level, we should return an ErrorExpression instead of a dummy expression.
                        Token argToken = argNodes.Expressions[0].Token;

                        _errorHandler.ReportError("The argument to Script.Literal must be a constant string.",
                                                  argToken.Location);
                        return new InlineScriptExpression("", objectType);
                    }

                    InlineScriptExpression scriptExpression = new InlineScriptExpression(script, objectType);
                    for (int i = 1; i < args.Count; i++) {
                        scriptExpression.AddParameterValue(args[i]);
                    }

                    return scriptExpression;
                }
                else if ((method.Parent == scriptType) &&
                         method.Name.Equals("Boolean", StringComparison.Ordinal)) {
                    Debug.Assert(args.Count == 1);

                    return new UnaryExpression(Operator.LogicalNot, new UnaryExpression(Operator.LogicalNot, args[0]));
                }
                else if ((method.Parent == scriptType) &&
                         method.Name.Equals("Value", StringComparison.Ordinal)) {
                    Debug.Assert(args.Count >= 2);

                    Expression expr = args[0];
                    for (int i = 1; i < args.Count; i++) {
                        expr = new BinaryExpression(Operator.LogicalOr, expr, args[i]);
                    }

                    expr.Reevaluate(args[0].EvaluatedType);
                    expr.AddParenthesisHint();

                    return expr;
                }
                else if (method.Parent == argsType) {
                    if (method.Name.Equals("GetArgument", StringComparison.Ordinal)) {
                        // Switch Arguments.GetArgument into Arguments[]
                        Debug.Assert(args.Count == 1);

                        IndexerExpression indexExpression =
                            new IndexerExpression(new LiteralExpression(typeType, method.Parent),
                                                  ((ClassSymbol)method.Parent).GetIndexer());
                        indexExpression.AddIndexParameterValue(args[0]);

                        return indexExpression;
                    }
                    else if (method.Name.Equals("ToArray", StringComparison.Ordinal)) {
                        // Switch Arguments.ToArray into Array.ToArray(arguments)

                        TypeSymbol arrayType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Array);
                        MethodSymbol toArrayMethod = (MethodSymbol)arrayType.GetMember("ToArray");

                        InlineScriptExpression argsExpression =
                            new InlineScriptExpression("arguments", objectType, /* parenthesize */ false);
                        MethodExpression toArrayExpression =
                            new MethodExpression(new TypeExpression(arrayType, SymbolFilter.Public | SymbolFilter.StaticMembers),
                                                 toArrayMethod);
                        toArrayExpression.AddParameterValue(argsExpression);

                        return toArrayExpression;
                    }
                }
                else {
                    bool lateBound = false;

                    if (method.Parent == scriptType) {
                        LateBoundOperation lateBoundOperation = LateBoundOperation.InvokeMethod;

                        if (method.Name.Equals("InvokeMethod", StringComparison.Ordinal)) {
                            lateBound = true;
                        }
                        else if (method.Name.Equals("DeleteField", StringComparison.Ordinal)) {
                            lateBound = true;
                            lateBoundOperation = LateBoundOperation.DeleteField;
                        }
                        else if (method.Name.Equals("GetField", StringComparison.Ordinal)) {
                            lateBound = true;
                            lateBoundOperation = LateBoundOperation.GetField;
                        }
                        else if (method.Name.Equals("SetField", StringComparison.Ordinal)) {
                            lateBound = true;
                            lateBoundOperation = LateBoundOperation.SetField;
                        }
                        else if (method.Name.Equals("GetScriptType", StringComparison.Ordinal)) {
                            lateBound = true;
                            lateBoundOperation = LateBoundOperation.GetScriptType;
                        }
                        else if (method.Name.Equals("HasField", StringComparison.Ordinal)) {
                            lateBound = true;
                            lateBoundOperation = LateBoundOperation.HasField;
                        }
                        else if (method.Name.Equals("HasMethod", StringComparison.Ordinal)) {
                            lateBound = true;
                            lateBoundOperation = LateBoundOperation.HasMethod;
                        }
                        else if (method.Name.Equals("CreateInstance", StringComparison.Ordinal)) {
                            Debug.Assert(args.Count >= 1);

                            if ((args[0].Type == ExpressionType.MethodInvoke) ||
                                (args[0].Type == ExpressionType.PropertyGet)) {
                                // When using the result of a method call/property access directly
                                // with Type.CreateInstance, the following script would be generated:
                                //
                                // new method()()
                                // which is invalid. Instead we need to generate the following:
                                // var type = method();
                                // new type()

                                _errorHandler.ReportError("You must store the type returned from a method or property into a local variable to use with Type.CreateInstance.",
                                                          node.Token.Location);
                            }

                            NewExpression newExpression = new NewExpression(args[0], objectType);
                            if (args.Count > 1) {
                                bool first = true;
                                foreach (Expression paramExpr in args) {
                                    if (first) {
                                        first = false;
                                        continue;
                                    }
                                    newExpression.AddParameterValue(paramExpr);
                                }
                            }
                            return newExpression;
                        }

                        if (lateBound) {
                            // Switch explicit late-bound calls into implicit late-bound expressions
                            // in script
                            Debug.Assert((args != null) &&
                                         (((lateBoundOperation == LateBoundOperation.GetScriptType) && (args.Count == 1)) ||
                                          (args.Count >= 2)));

                            LateBoundExpression lateBoundExpression = null;
                            Expression instanceExpression = null;
                            Expression nameExpression = null;

                            foreach (Expression paramExpr in args) {
                                if (instanceExpression == null) {
                                    instanceExpression = paramExpr;

                                    if (lateBoundOperation == LateBoundOperation.GetScriptType) {
                                        // GetScriptType only takes an instance
                                        return new LateBoundExpression(instanceExpression, null,
                                                                       lateBoundOperation, objectType);
                                    }
                                    continue;
                                }
                                if (nameExpression == null) {
                                    nameExpression = paramExpr;

                                    Expression objectExpression = instanceExpression;
                                    if (lateBoundOperation == LateBoundOperation.InvokeMethod) {
                                        if ((instanceExpression.Type == ExpressionType.Literal) &&
                                            (((LiteralExpression)instanceExpression).Value == null)) {
                                            objectExpression = null;

                                            LiteralExpression literalExpression = nameExpression as LiteralExpression;
                                            if (literalExpression == null) {
                                                _errorHandler.ReportError("The name of a global method must be a constant string known at compile time.",
                                                                          argNodes.Expressions[0].Token.Location);
                                            }
                                            else if (!Utility.IsValidIdentifier((string)literalExpression.Value)) {
                                                _errorHandler.ReportError("The name of a global method must be a valid identifer.",
                                                                          argNodes.Expressions[0].Token.Location);
                                            }
                                        }
                                    }

                                    lateBoundExpression = new LateBoundExpression(objectExpression, nameExpression,
                                                                                  lateBoundOperation, objectType);
                                    continue;
                                }

                                lateBoundExpression.AddParameterValue(paramExpr);
                            }

                            Debug.Assert(lateBoundExpression != null);
                            return lateBoundExpression;
                        }
                    }

                    if (!method.MatchesConditions(_options.Defines)) {
                        return null;
                    }

                    methodExpression = new MethodExpression(memberExpression.ObjectReference,
                                                            method);
                }
            }

            if (args != null) {
                foreach (Expression paramExpr in args) {
                    methodExpression.AddParameterValue(paramExpr);
                }
            }

            if (isDelegateInvoke) {
                return new DelegateInvokeExpression(methodExpression);
            }
            return methodExpression;
        }
Exemplo n.º 3
0
        private Expression ProcessArrayNewNode(ArrayNewNode node) {
            TypeSymbol itemTypeSymbol = _symbolSet.ResolveType(node.TypeReference, _symbolTable, _symbolContext);
            Debug.Assert(itemTypeSymbol != null);

            TypeSymbol arrayTypeSymbol = _symbolSet.CreateArrayTypeSymbol(itemTypeSymbol);

            if (node.InitializerExpression == null) {
                if (node.ExpressionList == null) {
                    return new LiteralExpression(arrayTypeSymbol, new Expression[0]);
                }
                else {
                    Debug.Assert(node.ExpressionList.NodeType == ParseNodeType.ExpressionList);
                    ExpressionListNode argsList = (ExpressionListNode)node.ExpressionList;

                    Debug.Assert(argsList.Expressions.Count == 1);
                    Expression sizeExpression = BuildExpression(argsList.Expressions[0]);
                    if (sizeExpression is MemberExpression) {
                        sizeExpression = TransformMemberExpression((MemberExpression)sizeExpression);
                    }

                    NewExpression newExpr = new NewExpression(arrayTypeSymbol);
                    newExpr.AddParameterValue(sizeExpression);

                    return newExpr;
                }
            }
            else {
                ArrayInitializerNode initializerNode = (ArrayInitializerNode)node.InitializerExpression;
                Expression[] values = new Expression[initializerNode.Values.Count];

                int i = 0;
                foreach (ParseNode valueNode in initializerNode.Values) {
                    values[i] = BuildExpression(valueNode);
                    if (values[i] is MemberExpression) {
                        values[i] = TransformMemberExpression((MemberExpression)values[i]);
                    }
                    i++;
                }

                return new LiteralExpression(arrayTypeSymbol, values);
            }
        }
Exemplo n.º 4
0
        private Expression ProcessNewNode(NewNode node) {
            TypeSymbol type = _symbolSet.ResolveType(node.TypeReference, _symbolTable, _symbolContext);
            Debug.Assert(type != null);

            if (type.Type == SymbolType.Delegate) {
                // If its an instantiation of a delegate, return the argument itself
                // which is already a delegate expression.
                // The delegate type itself does not have a runtime representation that
                // is instantiated.

                Debug.Assert(node.Arguments is ExpressionListNode);
                Debug.Assert(((ExpressionListNode)node.Arguments).Expressions.Count == 1);

                return BuildExpression(((ExpressionListNode)node.Arguments).Expressions[0]);
            }

            NewExpression newExpression = new NewExpression(type);
            if (node.Arguments != null) {
                Debug.Assert(node.Arguments is ExpressionListNode);
                List<Expression> args = BuildExpressionList((ExpressionListNode)node.Arguments);

                if ((type == _symbolSet.ResolveIntrinsicType(IntrinsicType.Function)) &&
                    (args.Count > 1)) {
                    // The function ctor in javascript takes parameters in
                    // reverse order, with the params array effectively at
                    // the start of the param list... in c# we must keep the params
                    // list at the end, so skip the first parameter, add the rest,
                    // and then add back the first parameter (the body of the
                    // function). Uggh!

                    Expression functionBodyParam = null;

                    foreach (Expression paramExpr in args) {
                        if (functionBodyParam == null) {
                            functionBodyParam = paramExpr;
                            continue;
                        }

                        newExpression.AddParameterValue(paramExpr);
                    }

                    newExpression.AddParameterValue(functionBodyParam);
                }
                else if (type.GenericType == _symbolSet.ResolveIntrinsicType(IntrinsicType.Nullable)) {
                    // Creating a new Nullable<T> ... if there is a value specified as a ctor param,
                    // just use the value; otherwise use undefined.
                    if (args.Count == 1) {
                        return args[0];
                    }
                    return new InlineScriptExpression("undefined", type);
                }
                else {
                    foreach (Expression paramExpr in args) {
                        newExpression.AddParameterValue(paramExpr);
                    }
                }
            }

            if (String.IsNullOrEmpty(type.DependencyName) == false) {
                _options.AddExecutionDependency(type.DependencyName);
            }

            return newExpression;
        }
        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(")");
        }