<> <> DIRECTORY AMModel, Atom, Graphs, Rope, VM, WorldVM; ModuleGraphs: CEDAR PROGRAM IMPORTS AMModel, Atom, Graphs, Rope, VM, WorldVM = BEGIN ROPE: TYPE = Rope.ROPE; vertexKey: ATOM _ Atom.MakeAtom["Spreitzer January 5, 1984 6:48 pm"]; worldContext: AMModel.Context; NewModuleVertex: PROC [moduleName: ROPE] RETURNS [vertex: Graphs.Vertex] = BEGIN atom: ATOM _ Atom.MakeAtom[moduleName]; IF (vertex _ NARROW[Atom.GetProp[atom: atom, prop: vertexKey]]) # NIL THEN RETURN; Atom.PutProp[ atom: atom, prop: vertexKey, val: vertex _ NEW [Graphs.VertexPrivate _ [ class: moduleVertexClass, rep: moduleName]] ]; END; ExpandModule: PROC [vertex: Graphs.Vertex, consume: Graphs.EdgeConsumer, filter: Graphs.EdgeFilter _ Graphs.all] --Graphs.ExpandProc-- = BEGIN moduleName: ROPE = NARROW[vertex.rep]; IF filter[Incoming] THEN ERROR Graphs.Cant; IF NOT filter[Outgoing] THEN RETURN; consume.proc[[Outgoing, "imports", NewImportsVertex[moduleName]], consume.data]; consume.proc[[Outgoing, "exports", NewExportsVertex[moduleName]], consume.data]; END; NewImportsVertex: PROC [moduleName: ROPE] RETURNS [vertex: Graphs.Vertex] = BEGIN vertex _ NEW [Graphs.VertexPrivate _ [ class: importsVertexClass, rep: moduleName]] END; NewExportsVertex: PROC [moduleName: ROPE] RETURNS [vertex: Graphs.Vertex] = BEGIN vertex _ NEW [Graphs.VertexPrivate _ [ class: exportsVertexClass, rep: moduleName]] END; ExpandImports: PROC [vertex: Graphs.Vertex, consume: Graphs.EdgeConsumer, filter: Graphs.EdgeFilter _ Graphs.all] --Graphs.ExpandProc-- = BEGIN moduleName: ROPE _ NARROW[vertex.rep]; context: AMModel.Context; imports: LIST OF AMModel.PartialInterfaceInstance; IF filter[Incoming] THEN ERROR Graphs.Cant; IF NOT filter[Outgoing] THEN RETURN; TRUSTED {context _ AMModel.MostRecentNamedContext[name: moduleName, context: worldContext]}; IF context = NIL THEN RETURN; TRUSTED {imports _ AMModel.Imports[context !VM.AddressFault => CONTINUE]}; FOR imports _ imports, imports.rest WHILE imports # NIL DO name: ROPE; TRUSTED {name _ AMModel.ContextName[imports.first.ir]}; consume.proc[[Outgoing, name, NewInterfaceVertex[name]], consume.data]; ENDLOOP; END; ExpandExports: PROC [vertex: Graphs.Vertex, consume: Graphs.EdgeConsumer, filter: Graphs.EdgeFilter _ Graphs.all] --Graphs.ExpandProc-- = BEGIN moduleName: ROPE _ NARROW[vertex.rep]; context: AMModel.Context; exports: LIST OF AMModel.PartialInterfaceInstance; IF filter[Incoming] THEN ERROR Graphs.Cant; IF NOT filter[Outgoing] THEN RETURN; TRUSTED {context _ AMModel.MostRecentNamedContext[name: moduleName, context: worldContext]}; IF context = NIL THEN RETURN; TRUSTED {exports _ AMModel.Exports[context !VM.AddressFault => CONTINUE]}; FOR exports _ exports, exports.rest WHILE exports # NIL DO name: ROPE; TRUSTED {name _ AMModel.ContextName[exports.first.ir]}; consume.proc[[Outgoing, name, NewInterfaceVertex[name]], consume.data]; ENDLOOP; END; NewInterfaceVertex: PROC [moduleName: ROPE] RETURNS [vertex: Graphs.Vertex] = BEGIN atom: ATOM _ Atom.MakeAtom[moduleName]; IF (vertex _ NARROW[Atom.GetProp[atom: atom, prop: vertexKey]]) # NIL THEN RETURN; Atom.PutProp[ atom: atom, prop: vertexKey, val: vertex _ NEW [Graphs.VertexPrivate _ [ class: interfaceVertexClass, rep: moduleName]] ]; END; ExpandInterface: PROC [vertex: Graphs.Vertex, consume: Graphs.EdgeConsumer, filter: Graphs.EdgeFilter _ Graphs.all] --Graphs.ExpandProc-- = BEGIN interfaceName: ROPE = NARROW[vertex.rep]; IF filter[Incoming] THEN ERROR Graphs.Cant; IF NOT filter[Outgoing] THEN RETURN; consume.proc[[Outgoing, "importedBy", NewImportedByVertex[interfaceName]], consume.data]; consume.proc[[Outgoing, "exportedBy", NewExportedByVertex[interfaceName]], consume.data]; END; NewImportedByVertex: PROC [moduleName: ROPE] RETURNS [vertex: Graphs.Vertex] = BEGIN vertex _ NEW [Graphs.VertexPrivate _ [ class: importedByVertexClass, rep: moduleName]] END; NewExportedByVertex: PROC [moduleName: ROPE] RETURNS [vertex: Graphs.Vertex] = BEGIN vertex _ NEW [Graphs.VertexPrivate _ [ class: exportedByVertexClass, rep: moduleName]] END; ExpandImportedBy: PROC [vertex: Graphs.Vertex, consume: Graphs.EdgeConsumer, filter: Graphs.EdgeFilter _ Graphs.all] --Graphs.ExpandProc-- = BEGIN interfaceName: ROPE _ NARROW[vertex.rep]; FindInterface: PROC [prog: AMModel.Context] RETURNS [stop: BOOLEAN] = BEGIN imports: LIST OF AMModel.PartialInterfaceInstance; TRUSTED {imports _ AMModel.Imports[prog !VM.AddressFault => CONTINUE]}; stop _ FALSE; FOR imports _ imports, imports.rest WHILE imports # NIL DO name: ROPE; TRUSTED {name _ AMModel.ContextName[imports.first.ir]}; IF name.Equal[interfaceName] THEN { consume.proc[[Outgoing, name, NewModuleVertex[name]], consume.data]; EXIT}; ENDLOOP; END; IF filter[Incoming] THEN ERROR Graphs.Cant; IF NOT filter[Outgoing] THEN RETURN; TRUSTED {[] _ AMModel.ContextChildren[context: worldContext, proc: FindInterface]}; END; ExpandExportedBy: PROC [vertex: Graphs.Vertex, consume: Graphs.EdgeConsumer, filter: Graphs.EdgeFilter _ Graphs.all] --Graphs.ExpandProc-- = BEGIN interfaceName: ROPE _ NARROW[vertex.rep]; FindInterface: PROC [prog: AMModel.Context] RETURNS [stop: BOOLEAN] = BEGIN exports: LIST OF AMModel.PartialInterfaceInstance; TRUSTED {exports _ AMModel.Exports[prog !VM.AddressFault => CONTINUE]}; stop _ FALSE; FOR exports _ exports, exports.rest WHILE exports # NIL DO name: ROPE; TRUSTED {name _ AMModel.ContextName[exports.first.ir]}; IF name.Equal[interfaceName] THEN { consume.proc[[Outgoing, name, NewModuleVertex[name]], consume.data]; EXIT}; ENDLOOP; END; IF filter[Incoming] THEN ERROR Graphs.Cant; IF NOT filter[Outgoing] THEN RETURN; TRUSTED {[] _ AMModel.ContextChildren[context: worldContext, proc: FindInterface]}; END; moduleVertexClass: Graphs.VertexClass _ Graphs.NewVertexClass[[ Expand: ExpandModule ]]; importsVertexClass: Graphs.VertexClass _ Graphs.NewVertexClass[[ Expand: ExpandImports ]]; exportsVertexClass: Graphs.VertexClass _ Graphs.NewVertexClass[[ Expand: ExpandExports ]]; interfaceVertexClass: Graphs.VertexClass _ Graphs.NewVertexClass[[ Expand: ExpandInterface ]]; importedByVertexClass: Graphs.VertexClass _ Graphs.NewVertexClass[[ Expand: ExpandImportedBy ]]; exportedByVertexClass: Graphs.VertexClass _ Graphs.NewVertexClass[[ Expand: ExpandExportedBy ]]; TRUSTED {worldContext _ AMModel.RootContext[WorldVM.LocalWorld[]]}; END. GraphBrowsers.Browse[vertex: ModuleGraphs.NewModuleVertex["ModuleGraphs"], browserClass: GraphBrowsers.basicBrowserClass, viewerInit: [name: "ModuleGraphs", iconic: FALSE]]