예제 #1
0
        private Platform.LibraryForExport CreateLibraryForExport(
            string libraryName,
            string libraryVersion,
            Pastel.PastelCompiler compilation,
            LibraryResourceDatabase libResDb)
        {
            using (new PerformanceSection("VmGenerator.CreateLibraryForExport"))
            {
                Multimap <string, Platform.ExportEntity> exportEntities = libResDb.ExportEntities;
                FunctionDefinition manifestFunction = null;
                Dictionary <string, FunctionDefinition> otherFunctions = new Dictionary <string, FunctionDefinition>();
                foreach (FunctionDefinition functionDefinition in compilation.FunctionDefinitions.Values)
                {
                    string functionName = functionDefinition.NameToken.Value;
                    if (functionName == "lib_manifest_RegisterFunctions")
                    {
                        manifestFunction = functionDefinition;
                    }
                    else
                    {
                        otherFunctions[functionName] = functionDefinition;
                    }
                }

                string[]             names      = otherFunctions.Keys.OrderBy(s => s).ToArray();
                FunctionDefinition[] functions  = names.Select(n => otherFunctions[n]).ToArray();
                string[]             dotNetLibs = libResDb.DotNetLibs.OrderBy(s => s.ToLower()).ToArray();

                return(new Platform.LibraryForExport()
                {
                    Name = libraryName,
                    Version = libraryVersion,
                    FunctionRegisteredNamesOrNulls = names,
                    Functions = functions,
                    ManifestFunction = manifestFunction,
                    ExportEntities = exportEntities,
                    DotNetLibs = dotNetLibs,
                    LibProjectNamesAndGuids = libResDb.ProjectReferenceToGuid,
                });
            }
        }
예제 #2
0
        public Library(string name, string libraryManifestPath, Platform.AbstractPlatform nullablePlatform)
        {
            TODO.LibrariesNeedVersionNumber();

            this.platformName = nullablePlatform == null ? null : nullablePlatform.Name;

            this.Resources = new LibraryResourceDatabase(this, nullablePlatform);

            this.Name          = name;
            this.RootDirectory = System.IO.Path.GetDirectoryName(libraryManifestPath);
            string[] manifest = System.IO.File.ReadAllText(libraryManifestPath).Split('\n');
            Dictionary <string, string> values     = new Dictionary <string, string>();
            Dictionary <string, bool>   flagValues = new Dictionary <string, bool>();

            string platformPrefix = "[" + this.platformName + "]";

            foreach (string line in manifest)
            {
                string trimmedLine = line.Trim();
                if (trimmedLine.Length > 0 && line[0] != '#')
                {
                    string[] parts = trimmedLine.Split(':');
                    if (parts.Length >= 2)
                    {
                        string key   = parts[0].Trim();
                        string value = parts[1];
                        for (int i = 2; i < parts.Length; ++i)
                        {
                            value += ":" + parts[i];
                        }

                        if (key.StartsWith("["))
                        {
                            if (key.StartsWith(platformPrefix))
                            {
                                key = key.Substring(platformPrefix.Length).Trim();
                            }
                            else
                            {
                                continue;
                            }
                        }

                        if (key == "BOOL_FLAG")
                        {
                            // TODO: parse bool flag value
                            parts = value.Split(':');
                            if (parts.Length == 2)
                            {
                                key = parts[0].Trim();
                                bool boolValue = parts[1].Trim().ToLowerInvariant() == "true";
                                flagValues[key] = boolValue;
                            }
                            else
                            {
                                throw new ParserException(null, "Library '" + name + "' has a syntax error in a boolean flag.");
                            }
                        }
                        else
                        {
                            values[key] = value;
                        }
                    }
                    else if (parts.Length == 1 && parts[0].Length != 0)
                    {
                        throw new ParserException(null, "Library '" + name + "' has a syntax error in its manifest.");
                    }
                }
            }

            this.CompileTimeConstants = new Dictionary <string, object>();
            foreach (string key in flagValues.Keys)
            {
                this.CompileTimeConstants[key] = flagValues[key];
            }
            foreach (string key in values.Keys)
            {
                this.CompileTimeConstants[key] = values[key];
            }

            this.filepathsByFunctionName = new Dictionary <string, string>();
            // Build a lookup dictionary of all file names that are simple function names e.g. "foo.cry"
            // Then go through and look up all the file names that contain . prefixes with the platform name and
            // overwrite the lookup value for that entry with the more specific path.
            // myFunction.cry
            // android.myFunction.cry
            // on Python, myFunction will be included for lib_foo_myFunction(), but on Android, android.myFunction.cry will be included instead.

            string[] files = new string[0];
            if (FileUtil.DirectoryExists(this.RootDirectory + "/translate"))
            {
                files = System.IO.Directory.GetFiles(System.IO.Path.Combine(this.RootDirectory, "translate"));
            }
            Dictionary <string, string> moreSpecificFiles = new Dictionary <string, string>();

            foreach (string fileWithDirectory in files)
            {
                string file = System.IO.Path.GetFileName(fileWithDirectory);
                if (file.EndsWith(".pst"))
                {
                    string functionName = file.Substring(0, file.Length - ".pst".Length);
                    if (functionName.Contains('.'))
                    {
                        // Add this file to the more specific lookup, but only if it contains the current platform.
                        if (functionName.StartsWith(platformName + ".") ||
                            functionName.Contains("." + platformName + "."))
                        {
                            string[] parts = functionName.Split('.');
                            moreSpecificFiles[parts[parts.Length - 1]] = file;
                        }
                        else
                        {
                            // just let it get filtered away.
                        }
                    }
                    else
                    {
                        this.filepathsByFunctionName[functionName] = file;
                    }
                }
            }

            foreach (string functionName in moreSpecificFiles.Keys)
            {
                this.filepathsByFunctionName[functionName] = moreSpecificFiles[functionName];
            }

            if (values.ContainsKey("ONLY_ALLOW_IMPORT_FROM"))
            {
                this.onlyImportableFrom = new HashSet <string>();
                foreach (string onlyImportFrom in values["ONLY_ALLOW_IMPORT_FROM"].Split(','))
                {
                    string libraryName = onlyImportFrom.Trim();
                    this.onlyImportableFrom.Add(libraryName);
                }
            }
        }