GemTalk / Rowan

a new project/package manager for Smalltalk that supports FileTree and Tonel repositories, and is independent of Monticello and Metacello
MIT License
14 stars 7 forks source link

[v3] performance problems when compiling a single method #913

Open dalehenrich opened 9 months ago

dalehenrich commented 9 months ago

Internal error "48991 Rowan performance problems when compiling a single method".

Since Rowan 1, the method RwPrjBrowserToolV2 >>#addOrUpdateMethod:dictionaries:inProtocol:forClassNamed:isMeta:inPackageNamed: has been used to compile a single method and the brute force technique that has been used involves making a copy of the entire project definition, then adding or updating a method definition for the changed method with the new source, then doing a compare of the copied project definition with the current project definition to produce a project modification consisting of the the change to the method ... this is incredibly expensive ... it should be much more efficient to directly create the project modification directly.

The following doit produces a project modification that contains a single methodModification:

| result beforeMethod afterMethod classDefinition before_source  after_source category 
    methodModification classModification theClass theClassName instanceMethodsModification
    packageDefinition thePackageName packageModification classesModification
    projectDefinition theProjectName projectModification packagesModification
|

category := 'issue 48991'.
theClassName := 'Issue48991'.
thePackageName := 'Issue48991-Core'.
theProjectName := 'Issue48991-Project'.

theClass := Object
    subclass: theClassName
    instVarNames: #()
    classVars: #()
    classInstVars: #()
    poolDictionaries: #()
    inDictionary: UserGlobals
    options: #().
theClass category: category.

before_source := 'issue48991 "comment" ^self '.
after_source := 'issue48991 ^ self'.

result := RwProjectSetModification new.
"result addElementModification:"

classDefinition := RwClassDefinition newForClassNamed: theClassName super: 'Object' category: category.

packageDefinition := RwPackageDefinition newNamed: thePackageName.

projectDefinition := (RwProjectDefinition new)
    projectName: theProjectName;
    yourself.

beforeMethod := RwMethodDefinition newForSource: before_source protocol: category.
afterMethod := RwMethodDefinition newForSource: after_source protocol: category.

projectModification := projectDefinition compareAgainstBase: projectDefinition.
packagesModification := RwPackagesModification new.
packageModification := packageDefinition compareAgainstBase: packageDefinition.
classesModification := RwClassesModification new.
classModification := classDefinition compareAgainstBase: classDefinition.
instanceMethodsModification := RwMethodsModification extendedClassName: theClassName.

methodModification :=  (afterMethod compareAgainstBase: beforeMethod)
    isMeta: false;
    classDefinition: classDefinition;
    yourself.

methodModification isEmpty
    ifFalse: [ instanceMethodsModification addElementModification: methodModification ].

instanceMethodsModification isEmpty
    ifFalse: [classModification instanceMethodsModification: instanceMethodsModification ].

classModification isEmpty
    ifFalse: [ classesModification addElementModification: classModification ].

classesModification isEmpty
    ifFalse: [ packageModification classesModification: classesModification ].

packageModification isEmpty
    ifFalse: [ packagesModification addElementModification: packageModification ].

projectModification packagesModification: packagesModification.

projectModification halt.

This doit should be massaged and used to replace the current RwPrjBrowserToolV2 >>#addOrUpdateMethod:dictionaries:inProtocol:forClassNamed:isMeta:inPackageNamed: implementation...