Eliot Miranda uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-eem.975.mcz ==================== Summary ==================== Name: System-eem.975 Author: eem Time: 14 November 2017, 11:22:51.118839 am UUID: d8e00134-ca31-43fb-8558-8bf9a15c7aba Ancestors: System-tpr.974 Add the ability to set a pragma preference stored in a class or global variable by analysing the getter, obviating the need for a setter. Improve the class comment for PragmaPreference and mention this feature. =============== Diff against System-tpr.974 =============== Item was changed: Preference subclass: #PragmaPreference instanceVariableNames: 'provider getter setter' classVariableNames: '' poolDictionaries: '' category: 'System-Preferences'! + !PragmaPreference commentStamp: 'eem 11/14/2017 11:20' prior: 0! + Differs from superclass by redirecting all queries to a preference provider that defines its preference via a class-side preference method marked with a pragma. For example, evaluate + self systemNavigation browseAllCallsOn: #preference:categoryList:description:type: + + Each preference method getter can be accompanied by a setter that assigns to the preference whose value the getter answers. If the getter is of the form + ^SomeGlobalOrClassVar ifNil: [...] + then the framework is smart enough to figure out the SomeGlobalOrClassVar from the getter and no setter method is required.! - !PragmaPreference commentStamp: 'ar 3/9/2009 21:27' prior: 0! - Differs from superclass by redirecting all queries to preference provider.! Item was added: + ----- Method: PragmaPreference>>attemptToSetValueFromGetter: (in category 'value') ----- + attemptToSetValueFromGetter: aValue + "Attempt to set the value of the preference from the getter method, answering if the attempt was successful. + Do so by seeing if the method is of the form + ^ClassVar ifNil: [...] + by analysing its bytecode, and if so, extracting the class (or global) var and setting its value." + | getterMethod getterBytecodes getterBytecodeNames + constant comparison branchTuple distance followingpc + classVar | + getterMethod := provider class compiledMethodAt: getter ifAbsent: [^false]. + getterBytecodes := getterMethod abstractBytecodeMessagesAndPCs. + getterBytecodeNames := getterBytecodes collect: [:tuple| tuple first selector]. + ((getterBytecodeNames beginsWith: #(pushLiteralVariable: doDup #pushConstant: send:super:numArgs: jump:if:)) + and: [getterBytecodeNames last == #methodReturnTop + and: [(constant := getterBytecodes third first) arguments first == nil + and: [(comparison := getterBytecodes fourth first) arguments first == #== + and: [branchTuple := getterBytecodes fifth. + followingpc := getterBytecodes sixth last. + distance := branchTuple first arguments first. + "i.e. does the branch jump to the return?" + distance + followingpc = getterBytecodes last second]]]]) ifFalse: + [^false]. + classVar := getterBytecodes first first arguments first. + classVar value: aValue. + ^true! Item was changed: ----- Method: PragmaPreference>>rawValue: (in category 'value') ----- rawValue: aValue "set the value as indicated, with no side effects" + [provider perform: setter with: aValue] + on: MessageNotUnderstood + do: [:ex| + (self attemptToSetValueFromGetter: aValue) ifFalse: + [ex pass]]! - provider perform: setter with: aValue! |
Free forum by Nabble | Edit this page |