Module: dfmc-environment-database Synopsis: DFM compiler library information Author: Andy Armstrong, Chris Page, Roman Budzianowski Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Import/export types for dfmc-browser-support define constant = one-of(#"internal", #"exported"); /// Library object define sealed method library-definition (library :: ) => (definition :: ) let project = library.library-compiler-project; let context = project.project-browsing-context; let definition = context & context.project-library-definition; assert(definition, "Library %s is missing its definition", name-to-string(project.project-library-name)); definition end method library-definition; define sealed method library-compiler-project (library :: ) => (project :: ) library.compiler-object-proxy end method library-compiler-project; // Return the primitive name of a library define sealed method get-environment-object-primitive-name (server :: , library :: ) => (name :: false-or()) let project = library-compiler-project(library); name-to-string(project.project-library-name) end method get-environment-object-primitive-name; // Search for a library by name define sealed method find-library (server :: , name :: ) => (library :: false-or()) let library-name = as(, name); let project = find-project-for-library-name(server, library-name, error?: #f); if (project) make-environment-object(, project: server.server-project, compiler-object-proxy: project) end end method find-library; define method project-executable-pathname (server :: , project :: , #key type, full-path?) => (name :: ) let library-name :: = project.project-library-name; let merged-name :: = merged-project-name(library-name); let dll-project :: = if (merged-name = library-name) project else let project-object = server.server-project; let database = project-object.project-compiler-database; //---*** How can we close the project opened through //---*** lookup-named-project again without accidentally //---*** closing it if the user already had it open? if (database) find-project-for-library-name(database, merged-name, error?: #f) end | lookup-named-project(merged-name) end; let base = dll-project.project-executable-name; let extension = select (type | dll-project.project-target-type) #"dll" => "dll"; #"executable" => "exe"; end; let filename = make(, base: base, extension: extension); if (full-path?) let directory = if (project.project-read-only?) as(, release-runtime-directory()) else project.project-build-location end; merge-locators(filename, directory) else filename end end method project-executable-pathname; // return the DLL/EXE filename for the specified library define sealed method library-filename (server :: , library :: ) => (filename :: ) let project-object = server.server-project; let main-library = project-object.project-library; let main-library? = main-library == library; let project = library.library-compiler-project; as(, project-executable-pathname (server, project, type: unless (main-library?) #"dll" end, full-path?: #t)) end method library-filename; define sealed method library-project-filename (server :: , library :: ) => (filename :: ) library.library-compiler-project.project-location end method library-project-filename; define sealed method library-interactive? (server :: , library :: ) => (interactive? :: ) let project = library.library-compiler-project; project.project-interaction-allowed? end method library-interactive?; define sealed method library-read-only? (server :: , library :: ) => (read-only? :: ) let project = library.library-compiler-project; project.project-read-only? end method library-read-only?; define sealed method library-read-only?-setter (read-only? :: , server :: , library :: ) => (read-only? :: ); let project = library.library-compiler-project; project.project-read-only? := read-only? end method library-read-only?-setter; // Do all visible module names in a library define sealed method do-namespace-names (function :: , server :: , library :: , #key client, imported? = #t) => () let context = browsing-context(server, library.library-compiler-project); local method do-module (name :: , export-kind :: ) => () unless (name == #"dylan-user") let environment-name = %make-module-name(server, library, name); function(environment-name) end end method; dfmc/do-library-modules(context, do-module, inherited?: imported?, internal?: #t); end method do-namespace-names; define sealed method source-form-uses-definitions? (server :: , library :: , #key modules, libraries, client) => (uses-definitions? :: ) ignore(modules, libraries, client); let definition = library.library-definition; ~empty?(definition.library-definition-used-libraries) end method source-form-uses-definitions?; define sealed method do-used-definitions (function :: , server :: , library :: , #key modules, libraries, client) => () ignore(modules, libraries, client); let definition = library.library-definition; let used-libraries = definition.library-definition-used-libraries; for (library-name :: in used-libraries) let project = find-project-for-library-name(server, library-name); let library = make-environment-object(, project: server.server-project, compiler-object-proxy: project); function(library) end end method do-used-definitions; define sealed method source-form-has-clients? (server :: , library :: , #key modules, libraries, client) => (has-clients? :: ) let project = library.compiler-object-proxy; let context = browsing-context(server, project); let library-name :: = project.project-library-name; block (return) do-all-client-contexts (method (context :: ) let definition = context.project-library-definition; let used-libraries = definition.library-definition-used-libraries; if (member?(library-name, used-libraries)) return(#t) end end, server, context); #f end block; end method source-form-has-clients?; define sealed method do-client-source-forms (function :: , server :: , library :: , #key modules, libraries, client) => () let project = library.compiler-object-proxy; let context = browsing-context(server, project); let library-name :: = project.project-library-name; do-all-client-contexts (method (context :: ) let definition = context.project-library-definition; let used-libraries = definition.library-definition-used-libraries; if (member?(library-name, used-libraries)) let name = definition.library-definition-name; let project = find-project-for-library-name(server, name); let library = make-environment-object(, project: server.server-project, compiler-object-proxy: project); function(library) end end, server, context) end method do-client-source-forms; /// ID handling define sealed method find-compiler-database-proxy (server :: , id :: , #key imported? = #f) => (definition :: false-or()) ignore(imported?); block (return) let library-name = as(, id-name(id)); local method maybe-return-project (project :: ) => () if (project.project-library-name == library-name) let context = project.project-browsing-context; if (context & context.project-library-definition) return(project) end end end method maybe-return-project; //---*** andrewa: is there a more efficient way to do this? do-all-projects(maybe-return-project, server) end end method find-compiler-database-proxy; define sealed method compiler-database-proxy-id (server :: , project :: ) => (id :: ) make(, name: name-to-string(project.project-library-name)) end method compiler-database-proxy-id; /// Implement do-project-file-libraries define sealed method do-project-file-libraries (function :: , server :: , file :: ) => () let project = server.server-project; let library = project.project-library; local method do-library-file-libraries (library :: ) => () let project = library.library-compiler-project; let source-files = project.project-dylan-sources; for (source-file in source-files) when (file = source-file) let (record, modified?) = project-source-canonical-source-record(project, source-file); record & function(library, record) end end end method do-library-file-libraries; library & do-library-file-libraries(library); do-project-used-libraries(do-library-file-libraries, project, project) end method do-project-file-libraries; /// Library lookup define sealed method environment-object-library (server :: , library :: ) => (library :: ) library end method environment-object-library;