示例#1
0
        public ICollection<SymbolImplementation> BuildCode(SymbolSet symbols)
        {
            _implementations = new List<SymbolImplementation>();

            foreach (NamespaceSymbol namespaceSymbol in symbols.Namespaces) {
                if (namespaceSymbol.HasApplicationTypes == false) {
                    continue;
                }

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

                    if (type.IsTestType && !_options.IncludeTests) {
                        // Ignore test types, if tests are not to be compiled
                        continue;
                    }

                    switch (type.Type) {
                        case SymbolType.Class:
                            BuildCode((ClassSymbol)type);
                            break;
                        case SymbolType.Record:
                            if (((RecordSymbol)type).Constructor != null) {
                                BuildCode(((RecordSymbol)type).Constructor);
                            }
                            break;
                    }
                }
            }

            return _implementations;
        }
示例#2
0
        public void GenerateScript(SymbolSet symbolSet) {
            Debug.Assert(symbolSet != null);

            Dictionary<string, bool> generatedNamespaces = new Dictionary<string, bool>();
            foreach (NamespaceSymbol namespaceSymbol in symbolSet.Namespaces) {
                if (namespaceSymbol.HasApplicationTypes) {
                    NamespaceGenerator.GenerateScript(this, namespaceSymbol, generatedNamespaces);
                }
            }

            List<ClassSymbol> generatedClasses = new List<ClassSymbol>(_classes.Count);
            foreach (ClassSymbol generatedClass in _classes) {
                if (generatedClass.HasGlobalMethods == false) {
                    GenerateClassRegistration(generatedClass, generatedClasses);
                }
            }

            // TODO: Couple of line-breaks would be nice here
            //       but only if there are any classes with static
            //       ctors or members

            foreach (ClassSymbol generatedClass in _classes) {
                TypeGenerator.GenerateClassConstructorScript(this, generatedClass);
            }

            if (Options.IncludeTests) {
                foreach (ClassSymbol generatedClass in _classes) {
                    if (generatedClass.IsTestClass) {
                        TestGenerator.GenerateScript(this, generatedClass);
                    }
                }
            }
        }
示例#3
0
 public NamespaceSymbol(string name, SymbolSet symbolSet)
     : base(SymbolType.Namespace, name, null)
 {
     _symbolSet = symbolSet;
     _types = new List<TypeSymbol>();
     _typeMap = new Dictionary<string, TypeSymbol>();
 }
示例#4
0
        public StatementBuilder(ILocalSymbolTable symbolTable, CodeMemberSymbol memberContext, IErrorHandler errorHandler, CompilerOptions options) {
            _symbolTable = symbolTable;
            _memberContext = memberContext;
            _symbolSet = memberContext.SymbolSet;
            _errorHandler = errorHandler;

            _expressionBuilder = new ExpressionBuilder(symbolTable, memberContext, errorHandler, options);
        }
示例#5
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;
 }
示例#6
0
        public void DumpSymbols(SymbolSet symbols)
        {
            ArrayList namespaces = new ArrayList(symbols.Namespaces.Count);
            foreach (NamespaceSymbol ns in symbols.Namespaces) {
                namespaces.Add(ns);
            }
            namespaces.Sort(new SymbolComparer());

            foreach (NamespaceSymbol ns in namespaces) {
                DumpSymbol(ns);
                _writer.WriteLine();
            }
        }
示例#7
0
        public bool Compile(CompilerOptions options)
        {
            if (options == null) {
                throw new ArgumentNullException("options");
            }
            _options = options;

            _hasErrors = false;
            _symbols = new SymbolSet();

            ImportMetadata();
            if (_hasErrors) {
                return false;
            }

            BuildCodeModel();
            if (_hasErrors) {
                return false;
            }

            BuildMetadata();
            if (_hasErrors) {
                return false;
            }

            BuildImplementation();
            if (_hasErrors) {
                return false;
            }

            GenerateScript();
            if (_hasErrors) {
                return false;
            }

            return true;
        }
示例#8
0
        public ICollection<TypeSymbol> BuildMetadata(ParseNodeList compilationUnits, SymbolSet symbols, CompilerOptions options) {
            Debug.Assert(compilationUnits != null);
            Debug.Assert(symbols != null);

            _symbols = symbols;
            _symbolTable = symbols;
            _options = options;

            string scriptName = GetAssemblyScriptName(compilationUnits);
            if (String.IsNullOrEmpty(scriptName)) {
                _errorHandler.ReportError("You must declare a ScriptAssembly attribute.", String.Empty);
            }
            else if (Utility.IsValidScriptName(scriptName) == false) {
                string errorMessage = "The ScriptAssembly attribute referenced an invalid name '{0}'. Script names must only contain letters, numbers, dots or underscores.";
                _errorHandler.ReportError(String.Format(errorMessage, scriptName), String.Empty);
            }
            symbols.ScriptName = scriptName;

            string scriptPrefix = GetAssemblyScriptPrefix(compilationUnits);
            if (String.IsNullOrEmpty(scriptPrefix) == false) {
                if (Utility.IsValidIdentifier(scriptPrefix) == false) {
                    string errorMessage = "The ScriptQualifier attribute referenced an invalid prefix '{0}'. Script prefix must be valid identifiers.";
                    _errorHandler.ReportError(String.Format(errorMessage, scriptPrefix), String.Empty);
                }
            }
            else {
                scriptPrefix = scriptName.Replace(".", String.Empty);
            }
            symbols.ScriptPrefix = scriptPrefix;

            string assemblyScriptNamespace = GetAssemblyScriptNamespace(compilationUnits);
            List<TypeSymbol> types = new List<TypeSymbol>();

            // Build all the types first.
            // Types need to be loaded upfront so that they can be used in resolving types associated
            // with members.
            foreach (CompilationUnitNode compilationUnit in compilationUnits) {
                foreach (NamespaceNode namespaceNode in compilationUnit.Members) {
                    string namespaceName = namespaceNode.Name;

                    NamespaceSymbol namespaceSymbol = symbols.GetNamespace(namespaceName);

                    List<string> imports = null;
                    Dictionary<string, string> aliases = null;

                    ParseNodeList usingClauses = namespaceNode.UsingClauses;
                    if ((usingClauses != null) && (usingClauses.Count != 0)) {
                        foreach (ParseNode usingNode in namespaceNode.UsingClauses) {
                            if (usingNode is UsingNamespaceNode) {
                                if (imports == null) {
                                    imports = new List<string>(usingClauses.Count);
                                }

                                string referencedNamespace = ((UsingNamespaceNode)usingNode).ReferencedNamespace;
                                if (imports.Contains(referencedNamespace) == false) {
                                    imports.Add(referencedNamespace);
                                }
                            }
                            else {
                                Debug.Assert(usingNode is UsingAliasNode);
                                if (aliases == null) {
                                    aliases = new Dictionary<string, string>();
                                }
                                UsingAliasNode aliasNode = (UsingAliasNode)usingNode;
                                aliases[aliasNode.Alias] = aliasNode.TypeName;
                            }
                        }
                    }

                    // Add parent namespaces as imports in reverse order since they
                    // are searched in that fashion.
                    string[] namespaceParts = namespaceName.Split('.');
                    for (int i = namespaceParts.Length - 2; i >= 0; i--) {
                        string partialNamespace;
                        if (i == 0) {
                            partialNamespace = namespaceParts[0];
                        }
                        else {
                            partialNamespace = String.Join(".", namespaceParts, 0, i + 1);
                        }

                        if (imports == null) {
                            imports = new List<string>();
                        }

                        if (imports.Contains(partialNamespace) == false) {
                            imports.Add(partialNamespace);
                        }
                    }

                    // Build type symbols for all user-defined types
                    foreach (TypeNode typeNode in namespaceNode.Members) {
                        UserTypeNode userTypeNode = typeNode as UserTypeNode;
                        if (userTypeNode == null) {
                            continue;
                        }

                        // Check if we have overriding script namespace for this type.
                        string typeScriptNamespace = GetScriptNamespace(userTypeNode.Attributes);
                        if (String.IsNullOrEmpty(typeScriptNamespace)) {
                            typeScriptNamespace = assemblyScriptNamespace;
                        }
                        
                        ClassSymbol partialTypeSymbol = null;
                        bool isPartial = false;

                        if ((userTypeNode.Modifiers & Modifiers.Partial) != 0) {
                            partialTypeSymbol = (ClassSymbol)((ISymbolTable)namespaceSymbol).FindSymbol(userTypeNode.Name, /* context */ null, SymbolFilter.Types);
                            if ((partialTypeSymbol != null) && partialTypeSymbol.IsApplicationType) {
                                // This class will be considered as a partial class
                                isPartial = true;

                                // Merge code model information for the partial class onto the code model node
                                // for the primary partial class. Interesting bits of information include things
                                // such as base class etc. that is yet to be processed.
                                CustomTypeNode partialTypeNode = (CustomTypeNode)partialTypeSymbol.ParseContext;
                                partialTypeNode.MergePartialType((CustomTypeNode)userTypeNode);

                                // Merge interesting bits of information onto the primary type symbol as well
                                // representing this partial class
                                BuildType(partialTypeSymbol, userTypeNode);

                                if (String.IsNullOrEmpty(typeScriptNamespace) == false) {
                                    partialTypeSymbol.ScriptNamespace = typeScriptNamespace;
                                }
                            }
                        }

                        TypeSymbol typeSymbol = BuildType(userTypeNode, namespaceSymbol);
                        if (typeSymbol != null) {
                            typeSymbol.SetParseContext(userTypeNode);
                            typeSymbol.SetParentSymbolTable(symbols);
                            if (imports != null) {
                                typeSymbol.SetImports(imports);
                            }
                            if (aliases != null) {
                                typeSymbol.SetAliases(aliases);
                            }

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

                            if (isPartial == false) {
                                namespaceSymbol.AddType(typeSymbol);
                            }
                            else {
                                // Partial types don't get added to the namespace, so we don't have
                                // duplicated named items. However, they still do get instantiated
                                // and processed as usual.
                                //
                                // The members within partial classes refer to the partial type as their parent,
                                // and hence derive context such as the list of imports scoped to the
                                // particular type.
                                // However, the members will get added to the primary partial type's list of
                                // members so they can be found.
                                // Effectively the partial class here gets created just to hold
                                // context of type-symbol level bits of information such as the list of
                                // imports, that are consumed when generating code for the members defined
                                // within a specific partial class.
                                ((ClassSymbol)typeSymbol).SetPrimaryPartialClass(partialTypeSymbol);
                            }

                            types.Add(typeSymbol);
                        }
                    }
                }
            }

            // Build inheritance chains
            foreach (TypeSymbol typeSymbol in types) {
                if (typeSymbol.Type == SymbolType.Class) {
                    BuildTypeInheritance((ClassSymbol)typeSymbol);
                }
            }

            // Import members
            foreach (TypeSymbol typeSymbol in types) {
                BuildMembers(typeSymbol);
            }

            // Associate interface members with interface member symbols
            foreach (TypeSymbol typeSymbol in types) {
                if (typeSymbol.Type == SymbolType.Class) {
                    BuildInterfaceAssociations((ClassSymbol)typeSymbol);
                }
            }

            // Load resource values
            if (_symbols.HasResources) {
                foreach (TypeSymbol typeSymbol in types) {
                    if (typeSymbol.Type == SymbolType.Resources) {
                        BuildResources((ResourcesSymbol)typeSymbol);
                    }
                }
            }

            // Load documentation
            if (_options.EnableDocComments) {
                Stream docCommentsStream = options.DocCommentFile.GetStream();
                if (docCommentsStream != null) {
                    try {
                        XmlDocument docComments = new XmlDocument();
                        docComments.Load(docCommentsStream);

                        symbols.SetComments(docComments);
                    }
                    finally {
                        options.DocCommentFile.CloseStream(docCommentsStream);
                    }
                }
            }

            return types;
        }
示例#9
0
 public ResourcesBuilder(SymbolSet symbols) {
     _symbols = symbols;
 }
示例#10
0
 public SignatureParser(SymbolSet symbols, ICompilerErrorHandler errorHandler) {
     _symbols = symbols;
     _errorHandler = errorHandler;
 }
示例#11
0
        public ICollection<TypeSymbol> ImportMetadata(ICollection<string> references, SymbolSet symbols)
        {
            Debug.Assert(references != null);
            Debug.Assert(symbols != null);

            _symbols = symbols;

            MetadataSource mdSource = new MetadataSource();
            bool hasLoadErrors = mdSource.LoadReferences(references, _errorHandler);

            ICollection<TypeSymbol> importedTypes = null;
            if (hasLoadErrors == false) {
                importedTypes = ImportAssemblies(mdSource);
            }

            if (_resolveError) {
                return null;
            }

            #if STATIC_ARRAY_EXTENSIONS
                // Update instance members that need to be generated as static methods
                ConvertInstanceMembersToStaticMembers();
            #endif // STATIC_ARRAY_EXTENSIONS

            return importedTypes;
        }