예제 #1
0
        private void DumpClass(ClassSymbol classSymbol) {
            _writer.Write("Global Methods: ");
            _writer.WriteLine(classSymbol.HasGlobalMethods);

            if (classSymbol.BaseClass != null) {
                _writer.Write("BaseClass: ");
                _writer.WriteLine(classSymbol.BaseClass.FullName);
            }
            if (classSymbol.Interfaces != null) {
                _writer.WriteLine("Interfaces:");
                _writer.Indent++;
                foreach (InterfaceSymbol interfaceSymbol in classSymbol.Interfaces) {
                    _writer.WriteLine(interfaceSymbol.FullName);
                }
                _writer.Indent--;
            }
            if (classSymbol.Constructor != null) {
                _writer.WriteLine("Constructor:");
                _writer.Indent++;
                DumpSymbol(classSymbol.Constructor);
                _writer.Indent--;
            }
            if (classSymbol.StaticConstructor != null) {
                _writer.WriteLine("StaticConstructor:");
                _writer.Indent++;
                DumpSymbol(classSymbol.StaticConstructor);
                _writer.Indent--;
            }
            if (classSymbol.Indexer != null) {
                _writer.WriteLine("Indexer:");
                _writer.Indent++;
                DumpSymbol(classSymbol.Indexer);
                _writer.Indent--;
            }
        }
예제 #2
0
        public static void GenerateClassConstructorScript(ScriptGenerator generator, ClassSymbol classSymbol)
        {
            // NOTE: This is emitted last in the script file, and separate from the initial class definition
            //       because it needs to be emitted after the class registration.

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                if ((memberSymbol.Type == SymbolType.Field) &&
                    ((memberSymbol.Visibility & MemberVisibility.Static) != 0)) {
                    if (((FieldSymbol)memberSymbol).IsConstant &&
                        ((memberSymbol.Visibility & (MemberVisibility.Public | MemberVisibility.Protected)) == 0)) {
                        // PrivateInstance/Internal constant fields are omitted since they have been inlined
                        continue;
                    }

                    MemberGenerator.GenerateScript(generator, memberSymbol);
                }
            }

            if (classSymbol.StaticConstructor != null) {
                ScriptTextWriter writer = generator.Writer;

                writer.Write("(function");
                writer.WriteTrimmed(" () ");
                writer.Write("{");
                writer.WriteNewLine();
                writer.Indent++;
                CodeGenerator.GenerateScript(generator, classSymbol.StaticConstructor);
                writer.Indent--;
                writer.Write("})();");
                writer.WriteSignificantNewLine();
            }
        }
예제 #3
0
        private void BuildCode(ClassSymbol classSymbol)
        {
            if (classSymbol.Constructor != null) {
                BuildCode(classSymbol.Constructor);
            }

            if (classSymbol.StaticConstructor != null) {
                BuildCode(classSymbol.StaticConstructor);
            }

            if (classSymbol.Indexer != null) {
                BuildCode(classSymbol.Indexer);
            }

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                switch (memberSymbol.Type) {
                    case SymbolType.Event:
                        BuildCode((EventSymbol)memberSymbol);
                        break;
                    case SymbolType.Field:
                        BuildCode((FieldSymbol)memberSymbol);
                        break;
                    case SymbolType.Method:
                        BuildCode((MethodSymbol)memberSymbol);
                        break;
                    case SymbolType.Property:
                        BuildCode((PropertySymbol)memberSymbol);
                        break;
                }
            }
        }
예제 #4
0
 public ExpressionBuilder(ILocalSymbolTable symbolTable, FieldSymbol fieldContext, IErrorHandler errorHandler, CompilerOptions options) {
     _symbolTable = symbolTable;
     _symbolContext = fieldContext;
     _classContext = ((ClassSymbol)fieldContext.Parent).PrimaryPartialClass;
     _symbolSet = fieldContext.SymbolSet;
     _errorHandler = errorHandler;
     _options = options;
 }
예제 #5
0
        private void GenerateClassRegistration(ClassSymbol classSymbol, List<ClassSymbol> generatedClasses) {
            Debug.Assert(classSymbol != null);

            if (generatedClasses.Contains(classSymbol)) {
                return;
            }

            ClassSymbol baseClass = classSymbol.BaseClass;
            if ((baseClass != null) && baseClass.IsApplicationType) {
                GenerateClassRegistration(baseClass, generatedClasses);
            }

            TypeGenerator.GenerateClassRegistrationScript(this, classSymbol);
            generatedClasses.Add(classSymbol);
        }
예제 #6
0
        private static void GenerateClassComment(ScriptTextWriter writer, ClassSymbol classSymbol) {
            GenerateSummaryComment(writer, classSymbol);

            if ((classSymbol.Constructor != null) &&
                (classSymbol.Constructor.Parameters != null)) {
                foreach (ParameterSymbol parameterSymbol in classSymbol.Constructor.Parameters) {
                    GenerateParameterComment(writer, parameterSymbol);
                }
            }

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                FieldSymbol fieldSymbol = memberSymbol as FieldSymbol;
                if (fieldSymbol != null) {
                    GenerateFieldComment(writer, fieldSymbol);
                }
            }
        }
예제 #7
0
        public static void GenerateClassRegistrationScript(ScriptGenerator generator, ClassSymbol classSymbol)
        {
            // NOTE: This is emitted towards the end of the script file as opposed to immediately after the
            //       class definition, because it allows us to reference other class (base class, interfaces)
            //       without having to do a manual topological sort to get the ordering of class definitions
            //       that would be needed otherwise.

            ScriptTextWriter writer = generator.Writer;
            string name = classSymbol.FullGeneratedName;

            writer.Write(name);
            writer.Write(".registerClass('");
            writer.Write(generator.Options.AssemblyName);
            writer.Write("', '");
            writer.Write(name);
            writer.Write("'");

            // TODO: We need to introduce the notion of a base class that only exists in the metadata
            //       and not at runtime. At that point this check of IsTestClass can be generalized.
            if (classSymbol.IsTestClass) {
                writer.Write(");");
                writer.WriteNewLine();

                return;
            }

            if (classSymbol.BaseClass != null) {
                writer.WriteTrimmed(", ");
                writer.Write(classSymbol.BaseClass.FullGeneratedName);
            }

            if (classSymbol.Interfaces != null) {
                if (classSymbol.BaseClass == null) {
                    writer.WriteTrimmed(", ");
                    writer.Write("null");
                }
                foreach (InterfaceSymbol interfaceSymbol in classSymbol.Interfaces) {
                    writer.WriteTrimmed(", ");
                    writer.Write(interfaceSymbol.FullGeneratedName);
                }
            }

            writer.Write(");");
            writer.WriteNewLine();
        }
예제 #8
0
        private void DumpClass(ClassSymbol classSymbol)
        {
            _writer.Write("Extension Methods: ");
            _writer.WriteLine(classSymbol.IsExtenderClass);

            if (classSymbol.BaseClass != null)
            {
                _writer.Write("BaseClass: ");
                _writer.WriteLine(classSymbol.BaseClass.Name);
            }
            if (classSymbol.Interfaces != null)
            {
                _writer.WriteLine("Interfaces:");
                _writer.Indent++;
                foreach (InterfaceSymbol interfaceSymbol in classSymbol.Interfaces)
                {
                    _writer.WriteLine(interfaceSymbol.Name);
                }
                _writer.Indent--;
            }
            if (classSymbol.Constructor != null)
            {
                _writer.WriteLine("Constructor:");
                _writer.Indent++;
                DumpSymbol(classSymbol.Constructor);
                _writer.Indent--;
            }
            if (classSymbol.StaticConstructor != null)
            {
                _writer.WriteLine("StaticConstructor:");
                _writer.Indent++;
                DumpSymbol(classSymbol.StaticConstructor);
                _writer.Indent--;
            }
            if (classSymbol.Indexer != null)
            {
                _writer.WriteLine("Indexer:");
                _writer.Indent++;
                DumpSymbol(classSymbol.Indexer);
                _writer.Indent--;
            }
        }
예제 #9
0
        public static void GenerateClassConstructorScript(ScriptGenerator generator, ClassSymbol classSymbol)
        {
            // NOTE: This is emitted last in the script file, and separate from the initial class definition
            //       because it needs to be emitted after the class registration.

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                if ((memberSymbol.Type == SymbolType.Field) &&
                    ((memberSymbol.Visibility & MemberVisibility.Static) != 0)) {
                    FieldSymbol fieldSymbol = (FieldSymbol)memberSymbol;

                    if (fieldSymbol.IsConstant &&
                        ((memberSymbol.Visibility & (MemberVisibility.Public | MemberVisibility.Protected)) == 0)) {
                        // PrivateInstance/Internal constant fields are omitted since they have been inlined
                        continue;
                    }

                    if (fieldSymbol.HasInitializer) {
                        MemberGenerator.GenerateScript(generator, memberSymbol);
                    }
                }
            }

            if (classSymbol.StaticConstructor != null) {
                ScriptTextWriter writer = generator.Writer;

                SymbolImplementation implementation = classSymbol.StaticConstructor.Implementation;
                bool requiresFunctionScope = implementation.DeclaresVariables;

                if (requiresFunctionScope) {
                    writer.WriteLine("(function() {");
                    writer.Indent++;
                }
                CodeGenerator.GenerateScript(generator, classSymbol.StaticConstructor);
                if (requiresFunctionScope) {
                    writer.Indent--;
                    writer.Write("})();");
                    writer.WriteLine();
                }
            }
        }
예제 #10
0
        public IndexerSymbol GetIndexer()
        {
            if (_primaryPartialClass != null)
            {
                return(_primaryPartialClass.GetIndexer());
            }

            ClassSymbol   classSymbol = this;
            IndexerSymbol indexer     = classSymbol.Indexer;

            while (indexer == null)
            {
                classSymbol = (ClassSymbol)classSymbol.GetBaseType();
                if (classSymbol == null)
                {
                    break;
                }

                indexer = classSymbol.Indexer;
            }

            return(indexer);
        }
예제 #11
0
        private TypeSymbol CreateArrayTypeCore(TypeSymbol itemTypeSymbol)
        {
            TypeSymbol arrayTypeSymbol =
                (TypeSymbol)((ISymbolTable)_systemNamespace).FindSymbol("Array", null, SymbolFilter.Types);

            Debug.Assert(arrayTypeSymbol != null);

            TypeSymbol specificArrayTypeSymbol = new ClassSymbol("Array", _systemNamespace);

            foreach (MemberSymbol memberSymbol in arrayTypeSymbol.Members)
            {
                specificArrayTypeSymbol.AddMember(memberSymbol);
            }

            IndexerSymbol indexerSymbol = new IndexerSymbol(specificArrayTypeSymbol, itemTypeSymbol,
                                                            MemberVisibility.Public);

            indexerSymbol.SetScriptIndexer();
            specificArrayTypeSymbol.AddMember(indexerSymbol);
            specificArrayTypeSymbol.SetIgnoreNamespace();
            specificArrayTypeSymbol.SetArray();

            return(specificArrayTypeSymbol);
        }
예제 #12
0
        private void ImportType(MetadataSource mdSource, TypeDefinition type, bool inScriptCoreAssembly, string assemblyScriptNamespace, string assemblyScriptName)
        {
            if (type.IsPublic == false) {
                return;
            }
            if (inScriptCoreAssembly && (MetadataHelpers.ShouldImportScriptCoreType(type) == false)) {
                return;
            }

            string name = type.Name;
            string namespaceName = type.Namespace;
            string scriptNamespace = MetadataHelpers.GetScriptNamespace(type);
            string scriptName = MetadataHelpers.GetScriptName(type);

            if (String.IsNullOrEmpty(scriptNamespace) && (String.IsNullOrEmpty(assemblyScriptNamespace) == false)) {
                scriptNamespace = assemblyScriptNamespace;
            }

            NamespaceSymbol namespaceSymbol = _symbols.GetNamespace(namespaceName);
            TypeSymbol typeSymbol = null;

            if (type.IsInterface) {
                typeSymbol = new InterfaceSymbol(name, namespaceSymbol);
            }
            else if (MetadataHelpers.IsEnum(type)) {
                // NOTE: We don't care about the flags bit on imported enums
                //       because this is only consumed by the generation logic.
                typeSymbol = new EnumerationSymbol(name, namespaceSymbol, /* flags */ false);
                if (MetadataHelpers.ShouldUseEnumNames(type)) {
                    ((EnumerationSymbol)typeSymbol).SetNamedValues();
                }
                else if (MetadataHelpers.ShouldUseEnumValues(type)) {
                    ((EnumerationSymbol)typeSymbol).SetNumericValues();
                }
            }
            else if (MetadataHelpers.IsDelegate(type)) {
                typeSymbol = new DelegateSymbol(name, namespaceSymbol);
                typeSymbol.SetTransformedName("Function");
            }
            else {
                if (MetadataHelpers.ShouldTreatAsRecordType(type)) {
                    typeSymbol = new RecordSymbol(name, namespaceSymbol);
                }
                else {
                    typeSymbol = new ClassSymbol(name, namespaceSymbol);

                    string mixinRoot;
                    if (MetadataHelpers.ShouldGlobalizeMembers(type, out mixinRoot)) {
                        ((ClassSymbol)typeSymbol).SetGlobalMethods(mixinRoot);
                    }
                }
            }

            if (typeSymbol != null) {
                if (type.HasGenericParameters) {
                    List<GenericParameterSymbol> genericArguments = new List<GenericParameterSymbol>();
                    foreach (GenericParameter genericParameter in type.GenericParameters) {
                        GenericParameterSymbol arg =
                            new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                      /* typeArgument */ true,
                                                      _symbols.GlobalNamespace);
                        genericArguments.Add(arg);
                    }

                    typeSymbol.AddGenericParameters(genericArguments);
                }

                typeSymbol.SetImported(assemblyScriptName);
                typeSymbol.SetMetadataToken(type, inScriptCoreAssembly);

                bool ignoreNamespace = MetadataHelpers.ShouldIgnoreNamespace(type);
                if (ignoreNamespace) {
                    typeSymbol.SetIgnoreNamespace();
                }
                typeSymbol.SetPublic();

                if (String.IsNullOrEmpty(scriptNamespace) == false) {
                    typeSymbol.ScriptNamespace = scriptNamespace;
                }

                if (String.IsNullOrEmpty(scriptName) == false) {
                    typeSymbol.SetTransformedName(scriptName);
                }

                namespaceSymbol.AddType(typeSymbol);
                _importedTypes.Add(typeSymbol);
            }
        }
예제 #13
0
        public void SetInheritance(ClassSymbol baseClass, ICollection<InterfaceSymbol> interfaces)
        {
            // Inheritance should only be assigned to a primary partial class.
            Debug.Assert(_primaryPartialClass == null);

            _baseClass = baseClass;
            _interfaces = interfaces;
        }
예제 #14
0
 public void AddGeneratedClass(ClassSymbol classSymbol) {
     Debug.Assert(classSymbol != null);
     _classes.Add(classSymbol);
 }
예제 #15
0
 public ThisExpression(ClassSymbol classSymbol, bool explicitReference)
     : base(ExpressionType.This, classSymbol, SymbolFilter.Public | SymbolFilter.Protected | SymbolFilter.Private | SymbolFilter.InstanceMembers)
 {
     _explicitReference = explicitReference;
 }
예제 #16
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");
            }
        }
예제 #17
0
        private static void GenerateClass(ScriptGenerator generator, ClassSymbol classSymbol) {
            if (classSymbol.HasGlobalMethods) {
                GenerateGlobalMethods(generator, classSymbol);
                generator.AddGeneratedClass(classSymbol);
                return;
            }

            ScriptTextWriter writer = generator.Writer;
            string name = classSymbol.FullGeneratedName;

            if (classSymbol.Namespace.Length == 0) {
                writer.Write("window.");
            }

            writer.Write(name);
            writer.WriteTrimmed(" = ");
            writer.Write("function");
            if (generator.Options.DebugFlavor) {
                writer.Write(" ");
                writer.Write(name.Replace(".", "_"));
            }
            writer.Write("(");
            if ((classSymbol.Constructor != null) && (classSymbol.Constructor.Parameters != null)) {
                bool firstParameter = true;
                foreach (ParameterSymbol parameterSymbol in classSymbol.Constructor.Parameters) {
                    if (firstParameter == false) {
                        writer.WriteTrimmed(", ");
                    }
                    writer.Write(parameterSymbol.GeneratedName);
                    firstParameter = false;
                }
            }
            writer.WriteTrimmed(") ");
            writer.Write("{");
            writer.WriteNewLine();
            writer.Indent++;

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

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                if ((memberSymbol.Type == SymbolType.Field) &&
                    (memberSymbol.Visibility & MemberVisibility.Static) == 0) {
                    FieldSymbol fieldSymbol = (FieldSymbol)memberSymbol;
                    if (fieldSymbol.HasInitializer) {
                        writer.Write("this.");
                        writer.Write(fieldSymbol.GeneratedName);
                        writer.WriteTrimmed(" = ");
                        CodeGenerator.GenerateScript(generator, fieldSymbol);
                        writer.Write(";");
                        writer.WriteNewLine();
                    }
                }
            }
            if (classSymbol.Constructor != null) {
                CodeGenerator.GenerateScript(generator, classSymbol.Constructor);
            }
            else if (classSymbol.BaseClass != null) {
                writer.Write(classSymbol.FullGeneratedName);
                writer.Write(".initializeBase(this);");
                writer.WriteNewLine();
            }
            writer.Indent--;
            writer.Write("}");
            writer.WriteSignificantNewLine();

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                if ((memberSymbol.Type != SymbolType.Field) &&
                    (memberSymbol.Visibility & MemberVisibility.Static) != 0) {
                    MemberGenerator.GenerateScript(generator, memberSymbol);
                }
            }

            bool hasPrototypeMembers = false;
            bool firstMember = true;
            bool lastMemberWasField = true;
            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                if ((memberSymbol.Visibility & MemberVisibility.Static) == 0) {
                    if ((memberSymbol.Type == SymbolType.Field) &&
                        ((FieldSymbol)memberSymbol).HasInitializer) {
                        continue;
                    }

                    if ((memberSymbol is CodeMemberSymbol) &&
                        ((CodeMemberSymbol)memberSymbol).IsAbstract) {
                        continue;
                    }

                    if (hasPrototypeMembers == false) {
                        hasPrototypeMembers = true;

                        writer.Write(name);
                        writer.Write(".prototype");
                        writer.WriteTrimmed(" = ");
                        writer.Write("{");
                        writer.WriteNewLine();
                        writer.Indent++;
                    }

                    if (firstMember == false) {
                        writer.Write(",");
                        writer.WriteNewLine();
                    }
                    if ((lastMemberWasField == false) || !(memberSymbol is FieldSymbol)) {
                        writer.WriteNewLine();
                    }

                    MemberGenerator.GenerateScript(generator, memberSymbol);
                    lastMemberWasField = (memberSymbol is FieldSymbol);
                    firstMember = false;
                }
            }

            if (classSymbol.Indexer != null) {
                if (hasPrototypeMembers == false) {
                    hasPrototypeMembers = true;

                    writer.Write(name);
                    writer.Write(".prototype");
                    writer.WriteTrimmed(" = ");
                    writer.Write("{");
                    writer.WriteNewLine();
                    writer.Indent++;
                
                }
                if (firstMember == false) {
                    writer.Write(",");
                    writer.WriteNewLine();
                }

                MemberGenerator.GenerateScript(generator, classSymbol.Indexer);
            }

            if (hasPrototypeMembers) {
                writer.Indent--;
                writer.WriteNewLine();
                writer.Write("}");
                writer.WriteSignificantNewLine();
            }

            generator.AddGeneratedClass(classSymbol);
        }
예제 #18
0
        private void BuildInterfaceAssociations(ClassSymbol classSymbol) {
            if (classSymbol.PrimaryPartialClass != classSymbol) {
                // Don't build interface associations for non-primary partial classes.
                return;
            }

            ICollection<InterfaceSymbol> interfaces = classSymbol.Interfaces;
            if ((interfaces != null) && (interfaces.Count != 0)) {
                foreach (InterfaceSymbol interfaceSymbol in interfaces) {
                    foreach (MemberSymbol memberSymbol in interfaceSymbol.Members) {
                        MemberSymbol associatedSymbol = classSymbol.GetMember(memberSymbol.Name);
                        if (associatedSymbol != null) {
                            associatedSymbol.SetInterfaceMember(memberSymbol);
                        }
                    }
                }
            }
        }
예제 #19
0
        private void BuildTypeInheritance(ClassSymbol classSymbol) {
            if (classSymbol.PrimaryPartialClass != classSymbol) {
                // Don't build type inheritance for non-primary partial classes.
                return;
            }

            CustomTypeNode customTypeNode = (CustomTypeNode)classSymbol.ParseContext;

            if ((customTypeNode.BaseTypes != null) && (customTypeNode.BaseTypes.Count != 0)) {
                ClassSymbol baseClass = null;
                List<InterfaceSymbol> interfaces = null;

                foreach (NameNode node in customTypeNode.BaseTypes) {
                    TypeSymbol baseTypeSymbol = (TypeSymbol)_symbolTable.FindSymbol(node.Name, classSymbol, SymbolFilter.Types);
                    Debug.Assert(baseTypeSymbol != null);

                    if (baseTypeSymbol.Type == SymbolType.Class) {
                        Debug.Assert(baseClass == null);
                        baseClass = (ClassSymbol)baseTypeSymbol;
                    }
                    else {
                        Debug.Assert(baseTypeSymbol.Type == SymbolType.Interface);

                        if (interfaces == null) {
                            interfaces = new List<InterfaceSymbol>();
                        }
                        interfaces.Add((InterfaceSymbol)baseTypeSymbol);
                    }
                }

                if ((baseClass != null) || (interfaces != null)) {
                    classSymbol.SetInheritance(baseClass, interfaces);
                }
            }
        }
예제 #20
0
        public void SetPrimaryPartialClass(ClassSymbol primaryPartialClass)
        {
            Debug.Assert(_primaryPartialClass == null);
            Debug.Assert(primaryPartialClass != null);

            _primaryPartialClass = primaryPartialClass;
        }
예제 #21
0
        private TypeSymbol CreateGenericTypeCore(TypeSymbol templateType, IList<TypeSymbol> typeArguments)
        {
            if (templateType.Type == SymbolType.Class) {
                ClassSymbol genericClass = (ClassSymbol)templateType;
                ClassSymbol instanceClass = new ClassSymbol(genericClass.Name, (NamespaceSymbol)genericClass.Parent);
                instanceClass.SetInheritance(genericClass.BaseClass, genericClass.Interfaces);
                instanceClass.SetImported(genericClass.Dependency);
                if (genericClass.IgnoreNamespace) {
                    instanceClass.SetIgnoreNamespace();
                }
                instanceClass.ScriptNamespace = genericClass.ScriptNamespace;
                if (genericClass.IsTransformed) {
                    instanceClass.SetTransformedName(genericClass.GeneratedName);
                }
                else if (genericClass.IsTransformAllowed == false) {
                    instanceClass.DisableNameTransformation();
                }
                if (genericClass.IsArray) {
                    instanceClass.SetArray();
                }

                instanceClass.AddGenericParameters(genericClass.GenericParameters);
                instanceClass.AddGenericArguments(genericClass, typeArguments);

                CreateGenericTypeMembers(genericClass, instanceClass, typeArguments);

                return instanceClass;
            }
            else if (templateType.Type == SymbolType.Interface) {
                InterfaceSymbol genericInterface = (InterfaceSymbol)templateType;
                InterfaceSymbol instanceInterface = new InterfaceSymbol(genericInterface.Name, (NamespaceSymbol)genericInterface.Parent);

                instanceInterface.SetImported(genericInterface.Dependency);
                if (genericInterface.IgnoreNamespace) {
                    instanceInterface.SetIgnoreNamespace();
                }
                if (genericInterface.IsTransformed) {
                    instanceInterface.SetTransformedName(genericInterface.GeneratedName);
                }
                else if (genericInterface.IsTransformAllowed == false) {
                    instanceInterface.DisableNameTransformation();
                }

                instanceInterface.AddGenericParameters(genericInterface.GenericParameters);
                instanceInterface.AddGenericArguments(genericInterface, typeArguments);

                CreateGenericTypeMembers(genericInterface, instanceInterface, typeArguments);

                return instanceInterface;
            }
            else if (templateType.Type == SymbolType.Delegate) {
                DelegateSymbol genericDelegate = (DelegateSymbol)templateType;
                DelegateSymbol instanceDelegate = new DelegateSymbol(genericDelegate.Name, (NamespaceSymbol)genericDelegate.Parent);

                instanceDelegate.AddGenericParameters(genericDelegate.GenericParameters);
                instanceDelegate.AddGenericArguments(genericDelegate, typeArguments);

                CreateGenericTypeMembers(genericDelegate, instanceDelegate, typeArguments);

                return instanceDelegate;
            }

            return null;
        }
예제 #22
0
        private TypeSymbol CreateArrayTypeCore(TypeSymbol itemTypeSymbol)
        {
            TypeSymbol arrayTypeSymbol =
                (TypeSymbol)((ISymbolTable)_systemNamespace).FindSymbol("Array", null, SymbolFilter.Types);
            Debug.Assert(arrayTypeSymbol != null);

            TypeSymbol specificArrayTypeSymbol = new ClassSymbol("Array", _systemNamespace);
            foreach (MemberSymbol memberSymbol in arrayTypeSymbol.Members) {
                specificArrayTypeSymbol.AddMember(memberSymbol);
            }

            IndexerSymbol indexerSymbol = new IndexerSymbol(specificArrayTypeSymbol, itemTypeSymbol,
                                                            MemberVisibility.Public);
            indexerSymbol.SetScriptIndexer();
            specificArrayTypeSymbol.AddMember(indexerSymbol);
            specificArrayTypeSymbol.SetIgnoreNamespace();
            specificArrayTypeSymbol.SetArray();

            return specificArrayTypeSymbol;
        }
예제 #23
0
        private string TransformMember(MemberSymbol memberSymbol)
        {
            if ((memberSymbol.InterfaceMember != null) ||
                (memberSymbol.Name.Length < 3) ||
                (memberSymbol.IsTransformAllowed == false))
            {
                // Interface members do get obfuscated

                // Also members with already short names do not get
                // obfuscated, as doing so might infact increase the name size
                return(null);
            }

            TypeSymbol type = (TypeSymbol)memberSymbol.Parent;

            if (memberSymbol.IsPublic == false)
            {
                if ((memberSymbol is CodeMemberSymbol) &&
                    ((CodeMemberSymbol)memberSymbol).IsOverride)
                {
                    ClassSymbol baseType = ((ClassSymbol)type).BaseClass;

                    if (baseType == null)
                    {
                        baseType = (ClassSymbol)((ISymbolTable)memberSymbol.SymbolSet.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types);
                        Debug.Assert(baseType != null);
                    }

                    MemberSymbol baseMember =
                        (MemberSymbol)((ISymbolTable)baseType).FindSymbol(memberSymbol.Name, type, SymbolFilter.Members);
                    Debug.Assert(baseMember != null);

                    return(baseMember.GeneratedName);
                }
                else
                {
                    int minimizationDepth = 0;
                    int currentCount      = -1;

                    if (type is ClassSymbol)
                    {
                        currentCount = ((ClassSymbol)type).TransformationCookie;
                    }
                    else if (type is EnumerationSymbol)
                    {
                        currentCount = ((EnumerationSymbol)type).TransformationCookie;
                    }

                    if (type is ClassSymbol)
                    {
                        minimizationDepth = ((ClassSymbol)type).MinimizationDepth;

                        if (currentCount == -1)
                        {
                            ClassSymbol baseClass = ((ClassSymbol)type).BaseClass;
                            if ((baseClass != null) && baseClass.IsApplicationType)
                            {
                                // Set current count to the base classes transformation
                                // cookie, so the generated one will the next one in
                                // sequence
                                currentCount = baseClass.TransformationCookie;
                            }
                        }
                    }

                    currentCount++;
                    if (type is ClassSymbol)
                    {
                        ((ClassSymbol)type).TransformationCookie = currentCount;
                    }
                    else if (type is EnumerationSymbol)
                    {
                        ((EnumerationSymbol)type).TransformationCookie = currentCount;
                    }

                    return(GenerateName(currentCount, minimizationDepth));
                }
            }

            return(null);
        }
예제 #24
0
 public BaseExpression(ClassSymbol classSymbol)
     : base(ExpressionType.Base, classSymbol, SymbolFilter.Public | SymbolFilter.Protected | SymbolFilter.InstanceMembers) {
 }
예제 #25
0
 public ThisExpression(ClassSymbol classSymbol, bool explicitReference)
     : base(ExpressionType.This, classSymbol, SymbolFilter.Public | SymbolFilter.Protected | SymbolFilter.Private | SymbolFilter.InstanceMembers)
 {
     _explicitReference = explicitReference;
 }
예제 #26
0
 public BaseExpression(ClassSymbol classSymbol)
     : base(ExpressionType.Base, classSymbol, SymbolFilter.Public | SymbolFilter.Protected | SymbolFilter.InstanceMembers)
 {
 }
예제 #27
0
        private TypeSymbol BuildType(UserTypeNode typeNode, NamespaceSymbol namespaceSymbol) {
            Debug.Assert(typeNode != null);
            Debug.Assert(namespaceSymbol != null);

            TypeSymbol typeSymbol = null;
            ParseNodeList attributes = typeNode.Attributes;

            if (typeNode.Type == TokenType.Class) {
                CustomTypeNode customTypeNode = (CustomTypeNode)typeNode;
                Debug.Assert(customTypeNode != null);

                NameNode baseTypeNameNode = null;
                if (customTypeNode.BaseTypes.Count != 0) {
                    baseTypeNameNode = customTypeNode.BaseTypes[0] as NameNode;
                }

                if ((baseTypeNameNode != null) && (String.CompareOrdinal(baseTypeNameNode.Name, "Record") == 0)) {
                    typeSymbol = new RecordSymbol(typeNode.Name, namespaceSymbol);
                }
                else {
                    AttributeNode resourcesAttribute = AttributeNode.FindAttribute(attributes, "Resources");
                    if (resourcesAttribute != null) {
                        typeSymbol = new ResourcesSymbol(typeNode.Name, namespaceSymbol);
                    }
                    else {
                        typeSymbol = new ClassSymbol(typeNode.Name, namespaceSymbol);

                        if ((baseTypeNameNode != null) &&
                            (String.CompareOrdinal(baseTypeNameNode.Name, "TestClass") == 0)) {
                            ((ClassSymbol)typeSymbol).SetTestClass();
                        }
                    }
                }
            }
            else if (typeNode.Type == TokenType.Interface) {
                typeSymbol = new InterfaceSymbol(typeNode.Name, namespaceSymbol);
            }
            else if (typeNode.Type == TokenType.Enum) {
                bool flags = false;

                AttributeNode flagsAttribute = AttributeNode.FindAttribute(typeNode.Attributes, "Flags");
                if (flagsAttribute != null) {
                    flags = true;
                }

                typeSymbol = new EnumerationSymbol(typeNode.Name, namespaceSymbol, flags);
            }
            else if (typeNode.Type == TokenType.Delegate) {
                typeSymbol = new DelegateSymbol(typeNode.Name, namespaceSymbol);
                typeSymbol.SetTransformedName("Function");
                typeSymbol.SetIgnoreNamespace();
            }

            Debug.Assert(typeSymbol != null, "Unexpected type node " + typeNode.Type);
            if (typeSymbol != null) {
                if ((typeNode.Modifiers & Modifiers.Public) != 0) {
                    typeSymbol.SetPublic();
                }

                BuildType(typeSymbol, typeNode);

                if (namespaceSymbol.Name.EndsWith(_options.TestsSubnamespace, StringComparison.Ordinal)) {
                    typeSymbol.SetTestType();
                }
            }

            return typeSymbol;
        }
예제 #28
0
        private TypeSymbol CreateGenericTypeCore(TypeSymbol templateType, IList <TypeSymbol> typeArguments)
        {
            if (templateType.Type == SymbolType.Class)
            {
                ClassSymbol genericClass  = (ClassSymbol)templateType;
                ClassSymbol instanceClass = new ClassSymbol(genericClass.Name, (NamespaceSymbol)genericClass.Parent);
                instanceClass.SetInheritance(genericClass.BaseClass, genericClass.Interfaces);
                instanceClass.SetImported(genericClass.Dependency);
                if (genericClass.IgnoreNamespace)
                {
                    instanceClass.SetIgnoreNamespace();
                }
                instanceClass.ScriptNamespace = genericClass.ScriptNamespace;
                if (genericClass.IsTransformed)
                {
                    instanceClass.SetTransformedName(genericClass.GeneratedName);
                }
                else if (genericClass.IsTransformAllowed == false)
                {
                    instanceClass.DisableNameTransformation();
                }
                if (genericClass.IsArray)
                {
                    instanceClass.SetArray();
                }

                instanceClass.AddGenericParameters(genericClass.GenericParameters);
                instanceClass.AddGenericArguments(genericClass, typeArguments);

                CreateGenericTypeMembers(genericClass, instanceClass, typeArguments);

                return(instanceClass);
            }
            else if (templateType.Type == SymbolType.Interface)
            {
                InterfaceSymbol genericInterface  = (InterfaceSymbol)templateType;
                InterfaceSymbol instanceInterface = new InterfaceSymbol(genericInterface.Name, (NamespaceSymbol)genericInterface.Parent);

                instanceInterface.SetImported(genericInterface.Dependency);
                if (genericInterface.IgnoreNamespace)
                {
                    instanceInterface.SetIgnoreNamespace();
                }
                if (genericInterface.IsTransformed)
                {
                    instanceInterface.SetTransformedName(genericInterface.GeneratedName);
                }
                else if (genericInterface.IsTransformAllowed == false)
                {
                    instanceInterface.DisableNameTransformation();
                }

                instanceInterface.AddGenericParameters(genericInterface.GenericParameters);
                instanceInterface.AddGenericArguments(genericInterface, typeArguments);

                CreateGenericTypeMembers(genericInterface, instanceInterface, typeArguments);

                return(instanceInterface);
            }
            else if (templateType.Type == SymbolType.Delegate)
            {
                DelegateSymbol genericDelegate  = (DelegateSymbol)templateType;
                DelegateSymbol instanceDelegate = new DelegateSymbol(genericDelegate.Name, (NamespaceSymbol)genericDelegate.Parent);

                instanceDelegate.AddGenericParameters(genericDelegate.GenericParameters);
                instanceDelegate.AddGenericArguments(genericDelegate, typeArguments);

                CreateGenericTypeMembers(genericDelegate, instanceDelegate, typeArguments);

                return(instanceDelegate);
            }

            return(null);
        }
예제 #29
0
        private static void GenerateClass(ScriptGenerator generator, ClassSymbol classSymbol)
        {
            ScriptTextWriter writer = generator.Writer;
            string name = classSymbol.FullGeneratedName;

            writer.Write("function ");
            writer.Write(name);
            writer.Write("(");
            if ((classSymbol.Constructor != null) && (classSymbol.Constructor.Parameters != null)) {
                bool firstParameter = true;
                foreach (ParameterSymbol parameterSymbol in classSymbol.Constructor.Parameters) {
                    if (firstParameter == false) {
                        writer.Write(", ");
                    }
                    writer.Write(parameterSymbol.GeneratedName);
                    firstParameter = false;
                }
            }
            writer.WriteLine(") {");
            writer.Indent++;

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

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                if ((memberSymbol.Type == SymbolType.Field) &&
                    (memberSymbol.Visibility & MemberVisibility.Static) == 0) {
                    FieldSymbol fieldSymbol = (FieldSymbol)memberSymbol;
                    if (fieldSymbol.HasInitializer) {
                        writer.Write("this.");
                        writer.Write(fieldSymbol.GeneratedName);
                        writer.Write(" = ");
                        CodeGenerator.GenerateScript(generator, fieldSymbol);
                        writer.Write(";");
                        writer.WriteLine();
                    }
                }
            }
            if (classSymbol.Constructor != null) {
                CodeGenerator.GenerateScript(generator, classSymbol.Constructor);
            }
            else if ((classSymbol.BaseClass != null) && (classSymbol.IsTestClass == false)) {
                writer.Write(classSymbol.BaseClass.FullGeneratedName);
                writer.Write(".call(this);");
                writer.WriteLine();
            }
            writer.Indent--;
            writer.WriteLine("}");

            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                if ((memberSymbol.Type != SymbolType.Field) &&
                    (memberSymbol.Visibility & MemberVisibility.Static) != 0) {
                    MemberGenerator.GenerateScript(generator, memberSymbol);
                }
            }

            if (classSymbol.IsStaticClass == false) {
                writer.Write("var ");
                writer.Write(name);
                writer.WriteLine("$ = {");
                writer.Indent++;

                bool firstMember = true;
                foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                    if ((memberSymbol.Visibility & MemberVisibility.Static) == 0) {
                        if (memberSymbol.Type == SymbolType.Field) {
                            continue;
                        }

                        if ((memberSymbol is CodeMemberSymbol) &&
                            ((CodeMemberSymbol)memberSymbol).IsAbstract) {
                            continue;
                        }

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

                        MemberGenerator.GenerateScript(generator, memberSymbol);
                        firstMember = false;
                    }
                }

                if (classSymbol.Indexer != null) {
                    if (firstMember == false) {
                        writer.WriteLine(",");
                    }

                    MemberGenerator.GenerateScript(generator, classSymbol.Indexer);
                }

                writer.Indent--;
                writer.WriteLine();
                writer.Write("};");
                writer.WriteLine();
            }
        }
예제 #30
0
        private void ImportBaseType(ClassSymbol classSymbol)
        {
            TypeDefinition type = (TypeDefinition)classSymbol.MetadataReference;
            TypeReference baseType = type.BaseType;

            if (baseType != null) {
                ClassSymbol baseClassSymbol = ResolveType(baseType) as ClassSymbol;
                if ((baseClassSymbol != null) &&
                    (String.CompareOrdinal(baseClassSymbol.FullName, "Object") != 0)) {
                    classSymbol.SetInheritance(baseClassSymbol, /* interfaces */ null);
                }
            }
        }
예제 #31
0
        private static void GenerateExtensionMethods(ScriptGenerator generator, ClassSymbol classSymbol)
        {
            foreach (MemberSymbol memberSymbol in classSymbol.Members) {
                Debug.Assert(memberSymbol.Type == SymbolType.Method);
                Debug.Assert((memberSymbol.Visibility & MemberVisibility.Static) != 0);

                MemberGenerator.GenerateScript(generator, memberSymbol);
            }
        }
예제 #32
0
        public static void GenerateScript(ScriptGenerator generator, ClassSymbol testClassSymbol) {
            Debug.Assert(generator != null);

            List<MethodSymbol> testMethods = new List<MethodSymbol>();
            bool hasSetup = false;
            bool hasCleanup = false;

            foreach (MemberSymbol member in testClassSymbol.Members) {
                if (member.Type == SymbolType.Method) {
                    if (String.CompareOrdinal(member.Name, "Setup") == 0) {
                        hasSetup = true;
                    }
                    else if (String.CompareOrdinal(member.Name, "Cleanup") == 0) {
                        hasCleanup = true;
                    }
                    else if (member.Name.StartsWith("Test", StringComparison.Ordinal)) {
                        testMethods.Add((MethodSymbol)member);
                    }
                }
            }

            ScriptTextWriter writer = generator.Writer;

            writer.WriteLine();
            writer.Write("module('");
            writer.Write(testClassSymbol.GeneratedName);
            writer.WriteLine("', {");
            writer.Indent++;
            writer.WriteLine("setup: function() {");
            writer.Indent++;
            writer.Write("this.instance = new ");
            writer.Write(testClassSymbol.FullGeneratedName);
            writer.WriteLine("();");
            if (hasSetup) {
                writer.WriteLine("this.instance.setup();");
            }
            writer.Indent--;
            writer.WriteLine("},");
            writer.WriteLine("teardown: function() {");
            writer.Indent++;
            if (hasCleanup) {
                writer.WriteLine("this.instance.cleanup();");
            }
            writer.WriteLine("delete this.instance;");
            writer.Indent--;
            writer.WriteLine("}");
            writer.Indent--;
            writer.WriteLine("});");
            writer.WriteLine();

            foreach (MethodSymbol testMethod in testMethods) {
                writer.Write("test('");
                writer.Write(testMethod.GeneratedName);
                writer.WriteLine("', function() {");
                writer.Indent++;
                writer.Write("this.instance.");
                writer.Write(testMethod.GeneratedName);
                writer.WriteLine("();");
                writer.Indent--;
                writer.WriteLine("});");
            }
        }