public SymbolImplementation BuildField(FieldSymbol fieldSymbol)
        {
            _rootScope = new SymbolScope((ISymbolTable)fieldSymbol.Parent);
            _currentScope = _rootScope;

            Expression initializerExpression;

            FieldDeclarationNode fieldDeclarationNode = (FieldDeclarationNode)fieldSymbol.ParseContext;
            Debug.Assert(fieldDeclarationNode != null);

            VariableInitializerNode initializerNode = (VariableInitializerNode)fieldDeclarationNode.Initializers[0];
            if (initializerNode.Value != null) {
                ExpressionBuilder expressionBuilder = new ExpressionBuilder(this, fieldSymbol, _errorHandler, _options);
                initializerExpression = expressionBuilder.BuildExpression(initializerNode.Value);
                if (initializerExpression is MemberExpression) {
                    initializerExpression =
                        expressionBuilder.TransformMemberExpression((MemberExpression)initializerExpression);
                }
            }
            else {
                object defaultValue = null;

                TypeSymbol fieldType = fieldSymbol.AssociatedType;
                SymbolSet symbolSet = fieldSymbol.SymbolSet;

                if (fieldType.Type == SymbolType.Enumeration) {
                    // The default for named values is null, so this only applies to
                    // regular enum types

                    EnumerationSymbol enumType = (EnumerationSymbol)fieldType;
                    if (enumType.UseNamedValues == false) {
                        defaultValue = 0;
                    }
                }
                else if ((fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Integer)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.UnsignedInteger)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Long)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.UnsignedLong)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Short)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.UnsignedShort)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Byte)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.SignedByte)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Double)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Single)) ||
                    (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Decimal))) {
                    defaultValue = 0;
                }
                else if (fieldType == symbolSet.ResolveIntrinsicType(IntrinsicType.Boolean)) {
                    defaultValue = false;
                }

                initializerExpression =
                    new LiteralExpression(symbolSet.ResolveIntrinsicType(IntrinsicType.Object),
                                          defaultValue);
            }

            List<Statement> statements = new List<Statement>();
            statements.Add(new ExpressionStatement(initializerExpression, /* isFragment */ true));

            return new SymbolImplementation(statements, null);
        }
예제 #2
0
        private Expression ProcessDotExpressionNode(BinaryExpressionNode node) {
            SymbolFilter filter = SymbolFilter.All;
            MemberSymbol memberSymbol = null;

            Expression objectExpression = ProcessDotExpressionNode(node, filter, out memberSymbol);
            if (objectExpression == null) {
                // We didn't successfully create an expression. The first pass attempted to
                // process the right child as an instance member of the left child expression.
                // We need to process the left child again as a type so we can process the
                // right child as a static member this time around.
                filter &= ~SymbolFilter.Members;
                objectExpression = ProcessDotExpressionNode(node, filter, out memberSymbol);
            }
            Debug.Assert(objectExpression != null);

            TypeSymbol dictionaryType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Dictionary);
            TypeSymbol genericDictionaryType = _symbolSet.ResolveIntrinsicType(IntrinsicType.GenericDictionary);
            TypeSymbol nullableType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Nullable);

            if (memberSymbol.Type == SymbolType.Property) {
                if ((memberSymbol.Parent == dictionaryType) ||
                    (memberSymbol.Parent == genericDictionaryType)) {
                    MethodSymbol methodSymbol = null;

                    if (String.CompareOrdinal(memberSymbol.Name, "Count") == 0) {
                        methodSymbol = (MethodSymbol)dictionaryType.GetMember("GetKeyCount");
                        Debug.Assert(methodSymbol != null);
                    }
                    else if (String.CompareOrdinal(memberSymbol.Name, "Keys") == 0) {
                        methodSymbol = (MethodSymbol)dictionaryType.GetMember("GetKeys");
                        Debug.Assert(methodSymbol != null);
                    }

                    if (methodSymbol != null) {
                        MethodExpression methodExpression =
                            new MethodExpression(new TypeExpression(dictionaryType, SymbolFilter.Public | SymbolFilter.StaticMembers),
                                                 methodSymbol);
                        methodExpression.AddParameterValue(objectExpression);
                        return methodExpression;
                    }
                }
                else if (memberSymbol.Parent == nullableType) {
                    if (String.CompareOrdinal(memberSymbol.Name, "Value") == 0) {
                        // Nullable<T>.Value becomes Nullable<T>

                        TypeSymbol underlyingType = objectExpression.EvaluatedType.GenericArguments.First();
                        objectExpression.Reevaluate(underlyingType);

                        return objectExpression;
                    }
                    else if (String.CompareOrdinal(memberSymbol.Name, "HasValue") == 0) {
                        // Nullable<T>.Value becomes Script.IsValue(Nullable<T>)

                        TypeSymbol scriptType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Script);
                        MethodSymbol isValueMethod = (MethodSymbol)scriptType.GetMember("IsValue");

                        MethodExpression methodExpression
                            = new MethodExpression(new TypeExpression(scriptType, SymbolFilter.Public | SymbolFilter.StaticMembers),
                                                   isValueMethod);
                        methodExpression.AddParameterValue(objectExpression);

                        return methodExpression;
                    }
                }
            }
            else if (memberSymbol.Type == SymbolType.Method) {
                if (memberSymbol.Parent == nullableType) {
                    // Nullable<T>.GetValueOrDefault() becomes Nullable<T> || 0|false

                    TypeSymbol underlyingType = objectExpression.EvaluatedType.GenericArguments.First();

                    object defaultValue = 0;
                    if (underlyingType == _symbolSet.ResolveIntrinsicType(IntrinsicType.Boolean)) {
                        defaultValue = false;
                    }
                    else if (underlyingType == _symbolSet.ResolveIntrinsicType(IntrinsicType.String)) {
                        defaultValue = String.Empty;
                    }

                    LiteralExpression literalExpression = new LiteralExpression(underlyingType, defaultValue);

                    BinaryExpression logicalOrExpression = new BinaryExpression(Operator.LogicalOr, objectExpression, literalExpression);
                    logicalOrExpression.Reevaluate(underlyingType);
                    logicalOrExpression.AddParenthesisHint();

                    return logicalOrExpression;
                }
            }

            string dependency = ((TypeSymbol)memberSymbol.Parent).DependencyName;
            if (String.IsNullOrEmpty(dependency) == false) {
                _options.AddExecutionDependency(dependency);
            }

            MemberExpression expression = new MemberExpression(objectExpression, memberSymbol);
            if ((memberSymbol.Type == SymbolType.Method) &&
                memberSymbol.AssociatedType.IsGeneric && (memberSymbol.AssociatedType.GenericArguments == null)) {
                Debug.Assert(node.RightChild.NodeType == ParseNodeType.GenericName);
                Debug.Assert(((GenericNameNode)node.RightChild).TypeArguments != null);

                List<TypeSymbol> typeArgs = new List<TypeSymbol>();
                foreach (ParseNode typeArgNode in ((GenericNameNode)node.RightChild).TypeArguments) {
                    typeArgs.Add(_symbolSet.ResolveType(typeArgNode, _symbolTable, _symbolContext));
                }

                TypeSymbol returnType = _symbolSet.CreateGenericTypeSymbol(memberSymbol.AssociatedType, typeArgs);
                if (returnType != null) {
                    MethodSymbol genericMethod = (MethodSymbol)memberSymbol;
                    MethodSymbol instanceMethod = new MethodSymbol(genericMethod.Name, (TypeSymbol)genericMethod.Parent, returnType);

                    if (genericMethod.IsTransformed) {
                        instanceMethod.SetTransformedName(genericMethod.GeneratedName);
                    }
                    instanceMethod.SetNameCasing(genericMethod.IsCasePreserved);

                    expression = new MemberExpression(objectExpression, instanceMethod);
                }
            }

            return expression;
        }
예제 #3
0
        private static void GenerateLiteralExpression(ScriptGenerator generator, MemberSymbol symbol, LiteralExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            object value = expression.Value;
            string textValue = null;

            if (value == null) {
                textValue = "null";
            }
            else {
                if (value is bool) {
                    if ((bool)value) {
                        textValue = "true";
                    }
                    else {
                        textValue = "false";
                    }
                }
                else if ((value is char) || (value is string)) {
                    textValue = Utility.QuoteString(value.ToString());
                }
                else if (value is TypeSymbol) {
                    textValue = ((TypeSymbol)value).FullGeneratedName;
                }
                else if (value is Expression[]) {
                    Expression[] values = (Expression[])value;
                    if (values.Length == 0) {
                        textValue = "[]";
                    }
                    else {
                        writer.WriteTrimmed("[ ");
                        GenerateExpressionList(generator, symbol, (Expression[])value);
                        writer.WriteTrimmed(" ]");
                    }
                }
                else {
                    textValue = Convert.ToString(value, CultureInfo.InvariantCulture);
                }
            }

            if (textValue != null) {
                writer.Write(textValue);
            }
        }
예제 #4
0
        private Expression ProcessAnonymousMethodNode(AnonymousMethodNode node) {
            TypeSymbol voidType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Void);
            Debug.Assert(voidType != null);

            bool createStaticDelegate = (_memberContext.Visibility & MemberVisibility.Static) != 0;

            AnonymousMethodSymbol methodSymbol =
                new AnonymousMethodSymbol(_memberContext, _symbolTable, voidType, createStaticDelegate);
            methodSymbol.SetParseContext(node);

            if ((node.Parameters != null) && (node.Parameters.Count != 0)) {
                foreach (ParameterNode parameterNode in node.Parameters) {
                    TypeSymbol parameterType = _symbolSet.ResolveType(parameterNode.Type, _symbolTable, _symbolContext);
                    Debug.Assert(parameterType != null);

                    ParameterSymbol paramSymbol =
                        new ParameterSymbol(parameterNode.Name, methodSymbol, parameterType, ParameterMode.In);
                    if (paramSymbol != null) {
                        paramSymbol.SetParseContext(parameterNode);
                        methodSymbol.AddParameter(paramSymbol);
                    }
                }
            }

            ImplementationBuilder implBuilder = new ImplementationBuilder(_options, _errorHandler);
            SymbolImplementation implementation = implBuilder.BuildMethod(methodSymbol);

            methodSymbol.AddImplementation(implementation);

            if ((createStaticDelegate == false) && (implementation.RequiresThisContext == false)) {
                methodSymbol.SetVisibility(methodSymbol.Visibility | MemberVisibility.Static);
                createStaticDelegate = true;
            }

            Expression objectExpression;
            if (createStaticDelegate) {
                TypeSymbol objectType = _symbolSet.ResolveIntrinsicType(IntrinsicType.Object);
                Debug.Assert(objectType != null);

                objectExpression = new LiteralExpression(objectType, null);
            }
            else {
                objectExpression = new ThisExpression(_classContext, /* explicitReference */ true);
            }

            return new DelegateExpression(objectExpression, methodSymbol);
        }