Print error silently with Transcript rather than destroy IDE usage with raised error when building menu with CustomMenuBuilder
--- a/CustomMenuBuilder.st Sun Feb 01 16:34:31 2015 +0100
+++ b/CustomMenuBuilder.st Sun Feb 01 20:31:27 2015 +0100
@@ -4,7 +4,8 @@
Object subclass:#CustomMenuBuilder
instanceVariableNames:'perspective menu submenuLabel afterMenuItemLabelled
- generatorOrRefactoringFilter resources navigationState manager'
+ generatorOrRefactoringFilter resources navigationState manager
+ errorPrinter'
classVariableNames:''
poolDictionaries:''
category:'Interface-Refactoring-Custom-UI'
@@ -58,6 +59,23 @@
"Modified (comment): / 28-12-2014 / 23:20:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!
+errorPrinter
+ "Returns printer (like Transcript) which should print/show errors while menu building.
+ Better to print errors silently than destroy IDE functionality with recurring errors."
+
+ ^ errorPrinter
+
+ "Modified (comment): / 01-02-2015 / 19:38:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+errorPrinter: aPrinter
+ "see errorPrinter"
+
+ errorPrinter := aPrinter.
+
+ "Modified (comment): / 01-02-2015 / 19:38:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
generatorOrRefactoringFilter
"Returns one argument block which is used to filter generators or refactorings"
@@ -228,9 +246,15 @@
submenu := Menu new.
generatorsAndRefactorings := manager generatorsAndRefactoringsSelect: [ :generatorOrRefactoring |
- (generatorOrRefactoring availableInPerspective: context perspective)
+ [ (generatorOrRefactoring availableInPerspective: context perspective)
and: [ filter value: generatorOrRefactoring ]
and: [ generatorOrRefactoring availableForProgrammingLanguagesInContext: context ]
+ and: [ generatorOrRefactoring label notNil ]
+ ] on: Error do: [ :error |
+ errorPrinter showCR: 'An error occured when selecting code generators/refactorings.'.
+ errorPrinter showCR: 'Class: ', generatorOrRefactoring name, ' Error: ', error asString.
+ false
+ ].
].
"/ Now, group them by group.
@@ -270,7 +294,7 @@
^ submenu
"Created: / 26-08-2014 / 10:13:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified (format): / 28-12-2014 / 23:19:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 20:18:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!
placeMenuItem: aMenuItem afterMenuItemLabeled: aLabel forMenu: aMenu
@@ -299,8 +323,9 @@
generatorOrRefactoringFilter := [ :generatorOrRefactoring | true ].
resources := self class classResources.
manager := CustomManager current.
+ errorPrinter := Transcript
- "Modified (format): / 29-12-2014 / 09:34:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 19:31:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
! !
!CustomMenuBuilder class methodsFor:'documentation'!
--- a/CustomMenuBuilderTests.st Sun Feb 01 16:34:31 2015 +0100
+++ b/CustomMenuBuilderTests.st Sun Feb 01 20:31:27 2015 +0100
@@ -33,14 +33,14 @@
generatorClassMock := mock mockClassOf: Object.
mock createMockGetters: generatorClassMock forSelectors: {
- 'label'. 'group'. 'isAbstract'. 'availableInContext:'.
+ 'label'. 'group'. 'name'. 'isAbstract'. 'availableInContext:'.
'availableInPerspective:'. 'availableForProgrammingLanguagesInContext:'
}.
resources := mock mockOf: Object.
resources compileMockMethod: 'string:aString ^ ''Translated '', aString'.
- "Modified: / 28-12-2014 / 22:50:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 20:00:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!
tearDown
@@ -61,6 +61,7 @@
generator := generatorClassMock new
objectAttributeAt: #isAbstract put: false;
objectAttributeAt: #label put: aLabel;
+ objectAttributeAt: #name put: 'Unknown class name';
objectAttributeAt: #group put: aGroup;
objectAttributeAt: #availableInContext: put: true;
objectAttributeAt: #availableInPerspective: put: true;
@@ -72,6 +73,7 @@
^ generator
"Created: / 28-12-2014 / 22:10:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 20:01:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!
menuItemLabels
@@ -263,6 +265,139 @@
"Created: / 04-01-2015 / 15:44:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
!
+test_build_menu_two_generators_with_nil_label
+ | expectedMenu actualMenu printer expectedError actualError |
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #().
+
+ provider last objectAttributeAt: #label put: nil.
+
+ printer := mock mockOf: Object.
+ printer compileMockMethod: 'showCR: message
+ (self objectAttributeAt: #showCR:) add: message';
+ objectAttributeAt: #showCR: put: OrderedCollection new.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ errorPrinter: printer;
+ buildMenu.
+
+ expectedError := OrderedCollection new.
+
+ actualError := printer objectAttributeAt: #showCR:.
+ self assert: expectedError = actualError.
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Label_03'.
+ 'BunchOfGenerators'.
+ {'Generator_01'}.
+ }.
+
+ actualMenu := self menuItemLabels.
+ self assert: expectedMenu = actualMenu.
+
+ "Created: / 01-02-2015 / 20:25:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_should_implement_error
+ | expectedMenu actualMenu printer expectedError actualError |
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #().
+
+ provider last compileMockMethod: 'availableInPerspective: perspective
+ self label = ''Generator_02'' ifTrue: [
+ self shouldImplement
+ ].
+ ^ true'.
+
+ printer := mock mockOf: Object.
+ printer compileMockMethod: 'showCR: message
+ (self objectAttributeAt: #showCR:) add: message';
+ objectAttributeAt: #showCR: put: OrderedCollection new.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ errorPrinter: printer;
+ buildMenu.
+
+ expectedError := OrderedCollection
+ with: 'An error occured when selecting code generators/refactorings.'
+ with: 'Class: Unknown class name Error: functionality has to be implemented: a ', provider last className, '>>availableInPerspective:'.
+
+ actualError := printer objectAttributeAt: #showCR:.
+ self assert: expectedError = actualError.
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Label_03'.
+ 'BunchOfGenerators'.
+ {'Generator_01'}.
+ }.
+
+ actualMenu := self menuItemLabels.
+ self assert: expectedMenu = actualMenu.
+
+ "Created: / 01-02-2015 / 20:19:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_subclass_responsibility_error
+ | expectedMenu actualMenu printer expectedError actualError |
+
+ self
+ addGenerator: 'Generator_01' group: #();
+ addGenerator: 'Generator_02' group: #().
+
+ provider last compileMockMethod: 'availableInPerspective: perspective
+ self label = ''Generator_02'' ifTrue: [
+ self subclassResponsibility
+ ].
+ ^ true'.
+
+ printer := mock mockOf: Object.
+ printer compileMockMethod: 'showCR: message
+ (self objectAttributeAt: #showCR:) add: message';
+ objectAttributeAt: #showCR: put: OrderedCollection new.
+
+ builder
+ perspective: CustomPerspective classPerspective;
+ menu: menu;
+ submenuLabel: 'BunchOfGenerators';
+ errorPrinter: printer;
+ buildMenu.
+
+ expectedError := OrderedCollection
+ with: 'An error occured when selecting code generators/refactorings.'
+ with: 'Class: Unknown class name Error: "availableInPerspective:" method must be reimplemented in subclass'.
+
+ actualError := printer objectAttributeAt: #showCR:.
+ self assert: expectedError = actualError.
+
+ expectedMenu := {
+ 'Label_01'.
+ 'Label_02'.
+ 'Label_03'.
+ 'BunchOfGenerators'.
+ {'Generator_01'}.
+ }.
+
+ actualMenu := self menuItemLabels.
+ self assert: expectedMenu = actualMenu.
+
+ "Created: / 01-02-2015 / 19:17:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+ "Modified: / 01-02-2015 / 20:17:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
test_build_menu_two_generators_without_filter
| expectedMenu actualMenu navigationState |
--- a/Make.proto Sun Feb 01 16:34:31 2015 +0100
+++ b/Make.proto Sun Feb 01 20:31:27 2015 +0100
@@ -166,6 +166,7 @@
$(OUTDIR)CustomAccessMethodsCodeGenerator.$(O) CustomAccessMethodsCodeGenerator.$(H): CustomAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGenerator.$(H) $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)CustomCodeSelectionRefactoring.$(O) CustomCodeSelectionRefactoring.$(H): CustomCodeSelectionRefactoring.st $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/jn/refactoring_custom/CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)CustomIsAbstractCodeGenerator.$(O) CustomIsAbstractCodeGenerator.$(H): CustomIsAbstractCodeGenerator.st $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGenerator.$(H) $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)CustomJavaSimpleSetterMethodsCodeGenerator.$(O) CustomJavaSimpleSetterMethodsCodeGenerator.$(H): CustomJavaSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGenerator.$(H) $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)CustomNewClassGenerator.$(O) CustomNewClassGenerator.$(H): CustomNewClassGenerator.st $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGenerator.$(H) $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)CustomReplaceIfNilWithIfTrueRefactoring.$(O) CustomReplaceIfNilWithIfTrueRefactoring.$(H): CustomReplaceIfNilWithIfTrueRefactoring.st $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/jn/refactoring_custom/CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)CustomSubclassResponsibilityCodeGenerator.$(O) CustomSubclassResponsibilityCodeGenerator.$(H): CustomSubclassResponsibilityCodeGenerator.st $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGenerator.$(H) $(INCLUDE_TOP)/jn/refactoring_custom/CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
--- a/Make.spec Sun Feb 01 16:34:31 2015 +0100
+++ b/Make.spec Sun Feb 01 20:31:27 2015 +0100
@@ -83,6 +83,7 @@
CustomAccessMethodsCodeGenerator \
CustomCodeSelectionRefactoring \
CustomIsAbstractCodeGenerator \
+ CustomJavaSimpleSetterMethodsCodeGenerator \
CustomNewClassGenerator \
CustomReplaceIfNilWithIfTrueRefactoring \
CustomSubclassResponsibilityCodeGenerator \
@@ -152,6 +153,7 @@
$(OUTDIR_SLASH)CustomAccessMethodsCodeGenerator.$(O) \
$(OUTDIR_SLASH)CustomCodeSelectionRefactoring.$(O) \
$(OUTDIR_SLASH)CustomIsAbstractCodeGenerator.$(O) \
+ $(OUTDIR_SLASH)CustomJavaSimpleSetterMethodsCodeGenerator.$(O) \
$(OUTDIR_SLASH)CustomNewClassGenerator.$(O) \
$(OUTDIR_SLASH)CustomReplaceIfNilWithIfTrueRefactoring.$(O) \
$(OUTDIR_SLASH)CustomSubclassResponsibilityCodeGenerator.$(O) \
--- a/abbrev.stc Sun Feb 01 16:34:31 2015 +0100
+++ b/abbrev.stc Sun Feb 01 20:31:27 2015 +0100
@@ -94,6 +94,7 @@
CustomAccessMethodsCodeGenerator CustomAccessMethodsCodeGenerator jn:refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
CustomCodeSelectionRefactoring CustomCodeSelectionRefactoring jn:refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
CustomIsAbstractCodeGenerator CustomIsAbstractCodeGenerator jn:refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+CustomJavaSimpleSetterMethodsCodeGenerator CustomJavaSimpleSetterMethodsCodeGenerator jn:refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
CustomNewClassGenerator CustomNewClassGenerator jn:refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
CustomReplaceIfNilWithIfTrueRefactoring CustomReplaceIfNilWithIfTrueRefactoring jn:refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
CustomSubclassResponsibilityCodeGenerator CustomSubclassResponsibilityCodeGenerator jn:refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
--- a/bc.mak Sun Feb 01 16:34:31 2015 +0100
+++ b/bc.mak Sun Feb 01 20:31:27 2015 +0100
@@ -113,6 +113,7 @@
$(OUTDIR)CustomAccessMethodsCodeGenerator.$(O) CustomAccessMethodsCodeGenerator.$(H): CustomAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGenerator.$(H) $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)CustomCodeSelectionRefactoring.$(O) CustomCodeSelectionRefactoring.$(H): CustomCodeSelectionRefactoring.st $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\jn\refactoring_custom\CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)CustomIsAbstractCodeGenerator.$(O) CustomIsAbstractCodeGenerator.$(H): CustomIsAbstractCodeGenerator.st $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGenerator.$(H) $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)CustomJavaSimpleSetterMethodsCodeGenerator.$(O) CustomJavaSimpleSetterMethodsCodeGenerator.$(H): CustomJavaSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGenerator.$(H) $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)CustomNewClassGenerator.$(O) CustomNewClassGenerator.$(H): CustomNewClassGenerator.st $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGenerator.$(H) $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)CustomReplaceIfNilWithIfTrueRefactoring.$(O) CustomReplaceIfNilWithIfTrueRefactoring.$(H): CustomReplaceIfNilWithIfTrueRefactoring.st $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\jn\refactoring_custom\CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)CustomSubclassResponsibilityCodeGenerator.$(O) CustomSubclassResponsibilityCodeGenerator.$(H): CustomSubclassResponsibilityCodeGenerator.st $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGenerator.$(H) $(INCLUDE_TOP)\jn\refactoring_custom\CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
--- a/libInit.cc Sun Feb 01 16:34:31 2015 +0100
+++ b/libInit.cc Sun Feb 01 20:31:27 2015 +0100
@@ -59,6 +59,7 @@
_CustomAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
_CustomCodeSelectionRefactoring_Init(pass,__pRT__,snd);
_CustomIsAbstractCodeGenerator_Init(pass,__pRT__,snd);
+_CustomJavaSimpleSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
_CustomNewClassGenerator_Init(pass,__pRT__,snd);
_CustomReplaceIfNilWithIfTrueRefactoring_Init(pass,__pRT__,snd);
_CustomSubclassResponsibilityCodeGenerator_Init(pass,__pRT__,snd);
--- a/patches/patches.rc Sun Feb 01 16:34:31 2015 +0100
+++ b/patches/patches.rc Sun Feb 01 20:31:27 2015 +0100
@@ -25,7 +25,7 @@
VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
VALUE "ProductName", "LibraryName\0"
VALUE "ProductVersion", "6.2.5.1516\0"
- VALUE "ProductDate", "Sun, 01 Feb 2015 15:30:01 GMT\0"
+ VALUE "ProductDate", "Sun, 01 Feb 2015 19:29:08 GMT\0"
END
END
--- a/refactoring_custom.rc Sun Feb 01 16:34:31 2015 +0100
+++ b/refactoring_custom.rc Sun Feb 01 20:31:27 2015 +0100
@@ -25,7 +25,7 @@
VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
VALUE "ProductName", "ProductName\0"
VALUE "ProductVersion", "6.2.5.1516\0"
- VALUE "ProductDate", "Sun, 01 Feb 2015 15:30:00 GMT\0"
+ VALUE "ProductDate", "Sun, 01 Feb 2015 19:29:06 GMT\0"
END
END