예제 #1
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);
            }
        }
예제 #2
0
        private BoundClassType BindClassDeclaration(ClassTypeSyntax declaration, Symbol parent)
        {
            ClassSymbol baseClass      = null;
            var         baseInterfaces = new List <InterfaceSymbol>();

            if (declaration.BaseList != null)
            {
                var baseType = Bind(declaration.BaseList.BaseType, x => BindType(x, parent));
                switch (baseType.TypeSymbol.Kind)
                {
                case SymbolKind.Class:
                    baseClass = (ClassSymbol)baseType.TypeSymbol;
                    break;

                case SymbolKind.Interface:
                    baseInterfaces.Add((InterfaceSymbol)baseType.TypeSymbol);
                    break;
                }
            }

            var classBinder = new Binder(_sharedBinderState, this);

            var classSymbol = new ClassSymbol(declaration, parent, baseClass, baseInterfaces.ToImmutableArray(), classBinder);

            AddSymbol(classSymbol, declaration.Name.Span);

            var members = new List <BoundNode>();

            foreach (var memberSyntax in declaration.Members)
            {
                switch (memberSyntax.Kind)
                {
                case SyntaxKind.VariableDeclarationStatement:
                    members.Add(classBinder.Bind((VariableDeclarationStatementSyntax)memberSyntax, x => classBinder.BindVariableDeclarationStatement(x, classSymbol)));
                    break;

                case SyntaxKind.FunctionDeclaration:
                    members.Add(classBinder.Bind((FunctionDeclarationSyntax)memberSyntax, x => classBinder.BindFunctionDeclaration(x, classSymbol)));
                    break;

                case SyntaxKind.FunctionDefinition:
                    members.Add(classBinder.Bind((FunctionDefinitionSyntax)memberSyntax, x => classBinder.BindFunctionDefinition(x, classSymbol)));
                    break;
                }
            }

            foreach (var member in classBinder.LocalSymbols.Values.SelectMany(x => x))
            {
                classSymbol.AddMember(member);
            }

            return(new BoundClassType(classSymbol, members.ToImmutableArray()));
        }
        private BoundClassType BindClassDeclaration(ClassTypeSyntax declaration, Symbol parent)
        {
            ClassOrStructSymbol    baseType;
            List <InterfaceSymbol> baseInterfaces;

            BindBaseList(declaration.BaseList, parent, out baseType, out baseInterfaces);

            var classBinder = new Binder(_sharedBinderState, this);

            var classSymbol = new ClassSymbol(declaration, parent, baseType, baseInterfaces.ToImmutableArray(), classBinder);

            AddSymbol(classSymbol, declaration.Name.SourceRange);

            var members = new List <BoundNode>();

            foreach (var memberSyntax in declaration.Members)
            {
                switch (memberSyntax.Kind)
                {
                case SyntaxKind.VariableDeclarationStatement:
                    members.Add(classBinder.Bind((VariableDeclarationStatementSyntax)memberSyntax, x => classBinder.BindField(x, classSymbol)));
                    break;

                case SyntaxKind.FunctionDeclaration:
                    members.Add(classBinder.Bind((FunctionDeclarationSyntax)memberSyntax, x => classBinder.BindFunctionDeclaration(x, classSymbol)));
                    break;

                case SyntaxKind.FunctionDefinition:
                    members.Add(classBinder.Bind((FunctionDefinitionSyntax)memberSyntax, x => classBinder.BindFunctionDefinition(x, classSymbol)));
                    break;
                }
            }

            foreach (var member in classBinder.LocalSymbols.Values.SelectMany(x => x))
            {
                classSymbol.AddMember(member);
            }

            return(new BoundClassType(classSymbol, members.ToImmutableArray()));
        }
예제 #4
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);
        }
예제 #5
0
        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.SetAlias("ss.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.SetAlias("ss.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.SetAlias("ss.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("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("Int32", null, SymbolFilter.Types);
                Debug.Assert(intType != null);

                TypeSymbol stringType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("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.SetAlias("ss.keys");
                classSymbol.AddMember(getKeysMethod);

                // Define Dictionary.GetCount
                MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType, MemberVisibility.Public | MemberVisibility.Static);
                countMethod.SetAlias("ss.keyCount");
                classSymbol.AddMember(countMethod);

                return;
            }
        }
예제 #6
0
        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 boolType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Boolean", null, SymbolFilter.Types);
                Debug.Assert(boolType != null);

                TypeSymbol intType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Int32", null, SymbolFilter.Types);
                Debug.Assert(intType != null);

                TypeSymbol floatType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Single", null, SymbolFilter.Types);
                Debug.Assert(floatType != null);

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

                // Define the Escape, Unescape, encodeURI, decodeURI, encodeURIComponent, decodeURIComponent methods
                MethodSymbol escapeMethod = new MethodSymbol("Escape", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static);
                classSymbol.AddMember(escapeMethod);

                MethodSymbol unescapeMethod = new MethodSymbol("Unescape", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static);
                classSymbol.AddMember(unescapeMethod);

                MethodSymbol encodeURIMethod = new MethodSymbol("EncodeUri", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static);
                encodeURIMethod.SetTransformedName("encodeURI");
                classSymbol.AddMember(encodeURIMethod);

                MethodSymbol decodeURIMethod = new MethodSymbol("DecodeUri", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static);
                decodeURIMethod.SetTransformedName("decodeURI");
                classSymbol.AddMember(decodeURIMethod);

                MethodSymbol encodeURIComponentMethod = new MethodSymbol("EncodeUriComponent", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static);
                encodeURIComponentMethod.SetTransformedName("encodeURIComponent");
                classSymbol.AddMember(encodeURIComponentMethod);

                MethodSymbol decodeURIComponentMethod = new MethodSymbol("DecodeUriComponent", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static);
                decodeURIComponentMethod.SetTransformedName("decodeURIComponent");
                classSymbol.AddMember(decodeURIComponentMethod);

                return;
            }

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

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

                return;
            }

            if (memberSet == PseudoClassMembers.Type)
            {
                // Define the Type.GetInstanceType static method which provides the functionality of
                // Object.GetType instance method. We don't extend Object.prototype in script to add
                // GetType, since we want to keep Object's protoype clean of any extensions.
                //
                // We create this symbol here, so that later the ExpressionBuilder can transform
                // calls to Object.GetType to this.
                TypeSymbol objectType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types);
                Debug.Assert(objectType != null);

                TypeSymbol typeType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Type", null, SymbolFilter.Types);
                Debug.Assert(objectType != null);

                MethodSymbol getTypeMethod = new MethodSymbol("GetInstanceType", classSymbol, typeType, MemberVisibility.Public | MemberVisibility.Static);
                getTypeMethod.AddParameter(new ParameterSymbol("instance", getTypeMethod, objectType, ParameterMode.In));
                classSymbol.AddMember(getTypeMethod);

                return;
            }

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

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

                TypeSymbol voidType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Void", null, SymbolFilter.Types);
                Debug.Assert(boolType != null);

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

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

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

                // Define Dictionary.ClearKeys
                MethodSymbol clearMethod = new MethodSymbol("ClearKeys", classSymbol, voidType, MemberVisibility.Public | MemberVisibility.Static);
                classSymbol.AddMember(clearMethod);

                // Define Dictionary.DeleteKey
                MethodSymbol deleteMethod = new MethodSymbol("DeleteKey", classSymbol, voidType, MemberVisibility.Public | MemberVisibility.Static);
                classSymbol.AddMember(deleteMethod);

                // Define Dictionary.KeyExists
                MethodSymbol existsMethod = new MethodSymbol("KeyExists", classSymbol, boolType, MemberVisibility.Public | MemberVisibility.Static);
                classSymbol.AddMember(existsMethod);

                return;
            }

            if (memberSet == PseudoClassMembers.String)
            {
                // In script, String.replace replaces only the first occurrence of a string
                // whereas in C# all occurrences are replaced.
                // Replace becomes replaceAll (a method we add) in generated script
                // ReplaceFirst becomes replace in generated script.
                // ReplaceRegex also becomes replace in generated script. (We added ReplaceRegex so
                //   it could be mapped to the native replace method, rather than out replaceAll
                //   extension)

                MethodSymbol replaceFirstMethod = (MethodSymbol)classSymbol.GetMember("ReplaceFirst");
                Debug.Assert(replaceFirstMethod != null);
                replaceFirstMethod.SetTransformedName("replace");

                MethodSymbol replaceMethod = (MethodSymbol)classSymbol.GetMember("Replace");
                Debug.Assert(replaceMethod != null);
                replaceMethod.SetTransformedName("replaceAll");

                MethodSymbol replaceRegexMethod = (MethodSymbol)classSymbol.GetMember("ReplaceRegex");
                Debug.Assert(replaceRegexMethod != null);
                replaceRegexMethod.SetTransformedName("replace");
            }
        }