Commits

Ryan Macnak committed 5ec3698

Work on mirrors for new mixin representation

  • Participants
  • Parent commits 554ae67

Comments (0)

Files changed (2)

File Mirrors4.ns3

-Newspeak3
+Newspeak3
+'Mirrors'
+class Mirrors4 usingLib: platform = NewspeakObject (
+"The new Newspeak  mirrors API. It is a work in progress that attempts to address weaknesses of the current API and of past mirror APIs. The mirrors here are high level mirrors: they represent language constructs in NS2 and above.
 
-'Mirrors'
+The API follows several general guidelines:
 
-
+1) Operations return mirrors (an exception is getting the reflectee).
+2) Operations take non-mirrors as arguments.
+3) Operations take a failure block.
 
-class Mirrors4 usingLib: platform = NewspeakObject (
-"The new Newspeak  mirrors API. It is a work in progress that attempts to address weaknesses of the current API and of past mirror APIs. The mirrors here are high level mirrors: they represent language constructs in NS2 and above.
-
-The API follows several general guidelines:
-
-1) Operations return mirrors (an exception is getting the reflectee).
-2) Operations take non-mirrors as arguments.
-3) Operations take a failure block.
-
-The motivation for (3) is that mirrors should be useful in both local and distributed settings. Forcing the user to confront the possibility of failure helps make code more robust in the distributed case.  This also contributes to (1); returned results may refer to remote values, and going through the mirror API to deal with them will help ensure failure scenarios are dealt with.
-
-On the other hand, arguments can always be converted to mirrors by the API.  Much of the awkwardness in mirror APIs stems from the need to package arguments as mirrors - with the API often immediately extracting the reflectee afterwards.  The API should endeavor to deal with either mirrors or non-mirrors when this makes sense (e.g., when applying a mixin to a superclass, the superclass argument could be either a class or a class mirror) or to provide a separate call for mirrors (say, when adding a method - one call might accept source as a string, another a MethodMirror).
-
-The implementation will likely change. As we reform the reflective interface, we are likely to reduce our reliance on existing code like SqueakVMMirror and NS2Reflection; either their code will migrate here or vice versa.
-
-The API is divided into immutable and mutable parts. Mirrors are basically immutable.  As such they support introspection directly. In order to mutate code, one uses MirrorBuilders. These are created based on a mirror, and allow modifications to be accumulated without having any effect on the system.  The builder can be asked to provide a mirror reflecting its current state at any time. This allows the results of multiple builders to be batched and submitted to the atomic installer as well.
-
-All this brings up the question of how mirrors differ from ASTs. Mirrors and ASTs should ideally be viewed as different implementations of the same interface.  Mirrors differ in how they are constructed and how they compute their subtrees. Mirrors may be connected to a live representation, or to a source base or whatever. 
-
-MirrorBuilders also differ in supporting mutability and in what inputs can drive them (e.g, addFromSource:) so they extend the base API of mirrors and ASTs. 
-
-It may be a while before this module realizes the ideal description given above. Also, the implementation still relies heavily on earlier reflective APIs - be they the built-in Squeak reflection classes or other efforts. Ultimately, the actual logic for this should reside here.
-
-   Copyright 2008 Cadence Design Systems, Inc.
-   Copyright (c) 2009-2010 Gilad Bracha
-   Copyright 2011 Gilad Bracha, Ryan Macnak and Cadence Design Systems
-
-   Licensed under the Apache License, Version 2.0 (the ''License''); you may not use this file except in compliance with the License.  You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0" 
-|  
-MutableHashedMap = platform collections Dictionary.
-MutableList = platform collections OrderedCollection.
-IdentitySet = platform IdentitySet.
-IdentityDictionary = platform IdentityDictionary.
-
-Duct = platform blackMarket Duct. "Note: not the one in brazil because brazil is not available during bootstrap"
-BrazilWeakStorage = platform blackMarket BrazilWeakStorage.
-
-Error = platform Exceptions Error.
-Metaclass = platform Metaclass.
-SystemMetadata = platform NewsqueakMixins SystemMetadata.
-Language = platform NsMultilanguage Language.
-SystemChangeNotifier = platform SystemChangeNotifier.
-
-
-"atomicInstaller = platform namespace AtomicInstaller usingPlatform: platform."
-atomicInstaller = platform AtomicInstaller4 usingPlatform: platform.
-
-lowLevelMirrors = platform namespace LowLevelMirrors usingLib: platform.
-LowLevelMirror = lowLevelMirrors Mirror.
-CompiledMixinMirror = lowLevelMirrors CompiledMixinMirror.
-LowLevelMixinMirror = lowLevelMirrors LowLevelMixinMirror.
-LowLevelMethodMirror = lowLevelMirrors LowLevelMethodMirror.
-InstanceVariableMirror = lowLevelMirrors InstanceVariableMirror.
-ImmutableMirrorGroup = (platform namespace MirrorGroups usingLib: platform) ImmutableMirrorGroup.
-
-
-private vmmirror = platform blackMarket NewspeakCore VMMirror new.
-
-parserLib = Delay computation: [platform namespace BlocklessCombinatorialParsing usingLib: platform].
-grammar = Delay computation: [platform namespace Newspeak3Grammar parserLib: parserLib].
-asts = Delay computation: [platform namespace Newspeak3AST usingLib: platform].
-parsing = Delay computation: [platform namespace Newspeak3Parsing
-	usingLib: platform
-	ast: asts
-	grammar: grammar].
-compilation = Delay computation: [platform namespace Newspeak3Compilation
-	usingPlatform: platform 
-	newspeakParser: parsing
-	mirrorLib: platform mirrors].
-
-protected storedCompiler "cached compiler and module"
-
-
-private mixinBasedMirrors <WeakIdentitySet[MixinMirror]> = BrazilWeakStorage new.
-|
-)
+The motivation for (3) is that mirrors should be useful in both local and distributed settings. Forcing the user to confront the possibility of failure helps make code more robust in the distributed case.  This also contributes to (1); returned results may refer to remote values, and going through the mirror API to deal with them will help ensure failure scenarios are dealt with.
 
-(
+On the other hand, arguments can always be converted to mirrors by the API.  Much of the awkwardness in mirror APIs stems from the need to package arguments as mirrors - with the API often immediately extracting the reflectee afterwards.  The API should endeavor to deal with either mirrors or non-mirrors when this makes sense (e.g., when applying a mixin to a superclass, the superclass argument could be either a class or a class mirror) or to provide a separate call for mirrors (say, when adding a method - one call might accept source as a string, another a MethodMirror).
 
-
+The implementation will likely change. As we reform the reflective interface, we are likely to reduce our reliance on existing code like SqueakVMMirror and NS2Reflection; either their code will migrate here or vice versa.
 
-class MirrorEvent = (
-""
-|
-|
-)
+The API is divided into immutable and mutable parts. Mirrors are basically immutable.  As such they support introspection directly. In order to mutate code, one uses MirrorBuilders. These are created based on a mirror, and allow modifications to be accumulated without having any effect on the system.  The builder can be asked to provide a mirror reflecting its current state at any time. This allows the results of multiple builders to be batched and submitted to the atomic installer as well.
 
-('testing'
+All this brings up the question of how mirrors differ from ASTs. Mirrors and ASTs should ideally be viewed as different implementations of the same interface.  Mirrors differ in how they are constructed and how they compute their subtrees. Mirrors may be connected to a live representation, or to a source base or whatever. 
 
-isMirrorEvent ^<Boolean> = (
+MirrorBuilders also differ in supporting mutability and in what inputs can drive them (e.g, addFromSource:) so they extend the base API of mirrors and ASTs. 
 
-
+It may be a while before this module realizes the ideal description given above. Also, the implementation still relies heavily on earlier reflective APIs - be they the built-in Squeak reflection classes or other efforts. Ultimately, the actual logic for this should reside here.
 
-)
+   Copyright 2008 Cadence Design Systems, Inc.
+   Copyright (c) 2009-2010 Gilad Bracha
+   Copyright 2011 Gilad Bracha, Ryan Macnak and Cadence Design Systems
 
-
+   Licensed under the Apache License, Version 2.0 (the ''License''); you may not use this file except in compliance with the License.  You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0"|  
+MutableHashedMap = platform collections Dictionary.
+MutableList = platform collections OrderedCollection.
+IdentitySet = platform IdentitySet.
+IdentityDictionary = platform IdentityDictionary.
 
-class MethodMirror reflecting: m <CompiledMethod> = Mirror reflecting: m (
-"A basic mirror for a language level method."
-)
+Duct = platform blackMarket Duct. "Note: not the one in brazil because brazil is not available during bootstrap"
+BrazilWeakStorage = platform blackMarket BrazilWeakStorage.
 
-('as yet unclassified'
+Error = platform Exceptions Error.
+Metaclass = platform Metaclass.
+zSystemMetadata = platform NewsqueakMixins SystemMetadata.
+zLanguage = platform NsMultilanguage Language.
+SystemChangeNotifier = platform SystemChangeNotifier.
 
-category ^<Symbol> = (
 
-
+"atomicInstaller = platform namespace AtomicInstaller usingPlatform: platform."
+atomicInstaller = platform AtomicInstaller4 usingPlatform: platform.
 
-definingMixin ^<MixinMirror> = (
+lowLevelMirrors = platform namespace LowLevelMirrors usingLib: platform.
+LowLevelMirror = lowLevelMirrors Mirror.
+CompiledMixinMirror = lowLevelMirrors CompiledMixinMirror.
+LowLevelMixinMirror = lowLevelMirrors LowLevelMixinMirror.
+LowLevelMethodMirror = lowLevelMirrors LowLevelMethodMirror.
+InstanceVariableMirror = lowLevelMirrors InstanceVariableMirror.
+ImmutableMirrorGroup = (platform namespace MirrorGroups usingLib: platform) ImmutableMirrorGroup.
 
-
 
-name ^<Symbol> = (
+private vmmirror = platform blackMarket NewspeakCore VMMirror new.
 
-
+parserLib = Delay computation: [platform namespace BlocklessCombinatorialParsing usingLib: platform].
+grammar = Delay computation: [platform namespace Newspeak3Grammar parserLib: parserLib].
+asts = Delay computation: [platform namespace Newspeak3AST usingLib: platform].
+parsing = Delay computation: [platform namespace Newspeak3Parsing
+	usingLib: platform
+	ast: asts
+	grammar: grammar].
+compilation = Delay computation: [platform namespace Newspeak3Compilation
+	usingPlatform: platform 
+	newspeakParser: parsing
+	mirrorLib: platform mirrors].
 
-simpleName = (
+protected storedCompiler "cached compiler and module"
 
-
 
-source ^<String> = (
+private mixinBasedMirrors <WeakIdentitySet[MixinMirror]> = BrazilWeakStorage new.
+|)
+(
+class ClassDeclarationBuilder fromMixinRep: rep <MixinRep> forExistingMixin: mixin <Mixin> = (
+"
+Builders do not give an ordinary mirror representing their current state: ask the builder itself. (Although this could be done: submit to atomic install without a namespace, don't install into Smalltalk, don't update the existingMixin, and reflect on the result.)
 
-
+Builders internally keep a CompiledMixinMirror that reflects the current state, including edits made but not yet installed. Queries reflect the state of this CMM.
 
-visibility ^<Symbol> = (
+Builders are connected up and down.  If you get a builder on a declaration, if you ask *the builder* for an enclosing or nested declaration and edit, installing any of them means installing all of them.  Builders created de novo (via reflecting: or fromSource:) remain independent.
+"|
+	"Used to create the namespace for AtomicInstall so existing instances are updated"
+	prvtExistingMixin <Mixin | nil> = mixin.
 
-
+	"Lazy.  It should not be neccessary to always unpack an entire module definition.
+	Perhaps this should be eager to complete creating-a-builder-is-like-forking semantics."
+	prvtEnclosingDeclaration <ClassDeclarationBuilder>
+	
+	"Eager. Simplifies CDB on installed CD versus new CD.  This must be computed anyway to install."
+	public instanceSide <MixinBuilder> = MixinBuilder 
+		forClassDeclaration: self
+		lowLevelMixin: rep first lowLevelMirror
+		withNestedReps: rep last.
+		
+	public classSide <MixinBuilder> = MixinBuilder 
+		forClassDeclaration: self
+		lowLevelMixin: rep first lowLevelMirror classMixin
+		withNestedReps: {}.
+	
+	prvtCompiledMixinMirror <CompiledMixinMirror> = rep first.
+	
+	public header <ClassHeaderBuilder> = ClassHeaderBuilder forClassDeclaration: self.
+|)
+('API'
+enclosingClass ^<ClassDeclarationBuilder> = (
+	prvtEnclosingDeclaration ifNil: [
+		| enclosing <Mixin> |
+		
+		prvtExistingMixin isNil ifTrue: [^nil].
+		
+		enclosing:: prvtExistingMixin enclosingMixin.
+		enclosing ifNil:[^nil].
+		
+		prvtEnclosingDeclaration:: ClassDeclarationBuilder reflecting: enclosing.
+		
+		prvtEnclosingDeclaration instanceSide nestedClasses addMirror: self
+	].
+	^prvtEnclosingDeclaration
+)
+fullyQualifiedName ^<Symbol> = (
+	^prvtCompiledMixinMirror name
+)
+headerFromSource: newHeader <String> = (
+	|
+	compiledResults <MixinRep>
+	|
+	
+	#BOGUS yourself.
+	"API:
+		<ClassDeclarationBuilder> headerFromSource:
+		vs
+		<ClassDeclarationBuilder> header source:
+	
+	Semantics: Do we allow the name to be changed? If so:	
+		Have to check for conflicts with methods/slots of enclosing.
+		If it conflicts with another class, override it?
+		If it is new, does this make a copy, or replace the old one?
+		
+		Currently, this takes 'Foo = ()' instead of 'class Foo = ()'.  Perhaps we should do the latter since an access modifier might be specified?
+	"
+	compiledResults:: compiler compileClassHeader: ('Newspeak3 ''', header category, ''' class ', newHeader) readStream of: self.
 
-)
+	lazyIsTopLevel ifTrue: [
+		"Result directly corresponds to me"
+		checkForSlotConflicts: compiledResults first.
+		checkForNameChange: compiledResults first.
+		prvtCompiledMixinMirror: compiledResults first.
+	] ifFalse: [
+		"Result corresponds to my enclosing class, since my slot/accessor may have been adjusted"
+		| newRep <MixinRep> = onlyElementOf: compiledResults last. |
+		checkForSlotConflicts: newRep first.
+		checkForNameChange: newRep first.
+		enclosingClass prvtCompiledMixinMirror: compiledResults first.	
+		prvtCompiledMixinMirror: newRep first.
+	].
+)
+install ^<ClassDeclarationMirror> = (
+	|
+	reps <List[MixinRep]>
+	existingMixinMap <IdentityMap[MixinRep,Mixin]>
+	mixinResults <List[Mixin]>
+	|
+	prvtEnclosingDeclaration ifNotNil: [
+		"Modifications were made to my enclosing class, must go up to really install."
+		prvtEnclosingDeclaration install.
+		assert: [reflectee notNil] 
+			message: 'Reflectee should have been filled in after install'.
+		^ClassDeclarationMirror reflecting: reflectee
+	].
+ 
+	
+	existingMixinMap: IdentityDictionary new.
+	reps: {collectMixinRepInto: existingMixinMap}.
 
-
+	mixinResults:: atomicInstaller install: reps withExistingMixins: existingMixinMap.
+	
+	"Fill-in reflectees for builders that were created from source"
+	self extractReflecteeFrom: (onlyElementOf: mixinResults).
 
-class MutableMethodGroup group: mirrors within: mb = MutableMirrorGroup group: mirrors within: mb (
-""
-|
-|
-)
+	"Notify those listening on the mirrors' Ducts (the IDE)"
+	self notifyExistingMirrors. 
+	
+	"Notify those listening for Squeak change nofitications (background source saver, VCS image source mirror cache)"
+	SystemChangeNotifier uniqueInstance
+		classDefinitionChangedFrom: reflectee definingClass
+		to: reflectee definingClass.
+	
+	assert: [reflectee notNil] message: 'Reflectee should have been filled in after install'.
+	^ClassDeclarationMirror reflecting: reflectee
+)
+name ^<Symbol> = (
+	^self fullyQualifiedName
+)
+reflectee ^<Mixin | nil> = (
+	#BOGUS yourself.
+	"If this builder corresponds to a class declaration that was already installed, we're okay. But this builder might represent a new class declaration that doesn't have a corresponding Mixin yet (#install will ensure it is filled, though). So, do we return a potentially nil reflectee or not support accessing a reflectee at all?"
+	
+	^prvtExistingMixin
+)
+simpleName ^<Symbol> = (
+	^fullyQualifiedNameToSimple: fullyQualifiedName
+)'as yet unclassifed'
+printOn: stm = (
+	stm nextPutAll: 'ClassDeclarationBuilder:'; nextPutAll: fullyQualifiedName
+)'private'
+checkForNameChange: newCompiledMixinMirror = (
+	
+	newCompiledMixinMirror name = self name ifFalse: [Error signal: 'Cannot change name this way'].
+)
+checkForSlotConflicts: newCompiledMixinMirror = (
+	
+	newCompiledMixinMirror lowLevelMirror instVars do: [:each <InstanceVariableMirror> | instanceSide checkNameConflictsForSlot: each name].
+)
+collectMixinRepInto: dict <IdentityMap[MixinRep,Mixin]> ^<MixinRep> = (
+	| rep |
+	rep: {
+		prvtCompiledMixinMirror.
+		instanceSide nestedClasses collect: [:ea | ea collectMixinRepInto: dict].
+	}.
+	prvtExistingMixin ifNotNil: [dict at: rep put: prvtExistingMixin].
+	^rep
+)
+compiledMixinMirror = (
+	"Asked for by compiler"
+	^prvtCompiledMixinMirror
+)
+extractReflecteeFrom: mixin <Mixin> = (
 
-('accessing'
+	"For builders that already had a non-nil reflectee, this is not necessary since the old reflectee has been become:d to the new one (at least if atomic install is working right...).  But this is required for builders that have been created from source and didn't have a reflectee yet.  This will connect them to their reflectees."
 
-addFromSource: s <String> = (
+	prvtExistingMixin:: mixin.
+	
+	mixin nestedMixins keysAndValuesDo: [:fullName :nestedMixin |
+		| n m |
+		n:: fullyQualifiedNameToSimple: fullName.
+		m:: instanceSide nestedClasses findMirrorNamed: n.
+		m extractReflecteeFrom: nestedMixin
+	].
+)
+lazyIsTopLevel = (
 
-
+	prvtEnclosingDeclaration isNil ifFalse: [^false].
+	
+	"enclosingDeclaration not yet created"
+	prvtExistingMixin isNil ifTrue: [^true "can't be created: must be new decl"].
+	^prvtExistingMixin enclosingMixin isNil
+)
+notifyExistingMirrors = (
+	instanceSide notifyExistingMirrors.
+	classSide notifyExistingMirrors.
+)'testing'
+isClassDeclarationMirror ^<Boolean> = (
+	^true
+)) : ('accessing'
+fromSource: src <String> ^<ClassDeclarationBuilder> = (
+	^self fromUnitSource: 'Newspeak3 ''Uncategorized'' ', src
+)'as yet unclassified'
+fromUnitSource: src <String> ^<ClassDeclarationBuilder> = (
+	| rep <MixinRep> |
+	rep:: compiler
+		compileClassSource: src readStream
+		within: nil.
+	^self fromMixinRep: rep forExistingMixin: nil
+)
+reflecting: mixin <Mixin> ^<ClassDeclarationBuilder> = (
+	assert: [mixin isMixin & mixin isMeta not] message: 'Provide an instance-side mixin'.
+	^self 
+		fromMixinRep: (mixinRepFor: mixin)
+		forExistingMixin: mixin
+))
+class ClassDeclarationMirror reflecting: mixin <Mixin> = Mirror reflecting: mixin (
+"A class declaration defines the instance and class sides, and a header. Each side comprises methods and nested classes. The header provides a superclass clauses, a primary factory a class comment and an instance initializer.  
 
-addMirror: m <MethodBuilder>= (
+This mirror provides a view of a class declaration based on its runtime representation in the Newspeak image running on Squeak. To create an instance, provide the instance-side mixin. The mirror can obtain all necessary information from that."|
+	instanceSideLazy
+	classSideLazy
+|assert: [mixin isMixin & mixin isMeta not] message: 'Provide an instance-side mixin')
+('API'
+classSide ^ <MixinMirror> = (
+	classSideLazy ifNil: [
+		classSideLazy:: MixinMirror reflecting: reflectee classMixin].
+	^classSideLazy
+)
+enclosingClass ^ <ClassDeclarationMirror> = (
+	| enclosing <Class> |
+	enclosing:: reflectee enclosingMixin. 
+	enclosing ifNil:[^nil].
+	^ClassDeclarationMirror reflecting: enclosing mixin
+)
+fullyQualifiedName ^ <Symbol> = (
+	^reflectee definingClass name
+)
+header ^ <ClassHeaderMirror> = (
+	^ClassHeaderMirror reflecting: reflectee
+)
+instanceSide ^ <MixinMirror> = (
+	instanceSideLazy ifNil: [
+		instanceSideLazy:: MixinMirror reflecting: reflectee].
+	^instanceSideLazy
+)
+name ^ <Symbol> = (
+	^self fullyQualifiedName
+)
+simpleName ^ <Symbol> = (
+	^fullyQualifiedNameToSimple: fullyQualifiedName
+)
+source ^ <String> = (
+	^String streamContents: [ :s | reflectee printClassOn: s ]	
+)'restricted'
+compiledMixinMirror = (
+	"Used by the compiler.  Polymorphic with ClassDeclarationBuilder, which must answer the one that represents edits in progress."
+	^makeCompiledMixinMirrorForMixin: reflectee
+)'testing'
+isClassDeclarationMirror ^<Boolean> = (
+	^true
+))
+class ClassHeaderBuilder forClassDeclaration: decl = (
+"Describe the class in this comment."|
+	prvtDeclaration <ClassDeclarationBuilder> = decl.
+|)
+('as yet unclassified'
+category ^<Symbol> = (
+	^prvtDeclaration prvtCompiledMixinMirror category ifNil: ['Uncategorized']
+)
+category: c <Symbol | String> = (
+	prvtDeclaration prvtCompiledMixinMirror category: c asSymbol
+)
+name ^<Symbol> = (
+	"Is this full or simple?"
+	^prvtDeclaration name
+)
+name: newSimpleName <Symbol> = (
+	|
+	token
+	newHeaderSource
+	compiledResults <MixinRep>
+	|
 
-
+	"check for name conflict with sibling members"
+	prvtDeclaration lazyIsTopLevel ifFalse: [
+		| existing |
+		existing:: prvtDeclaration enclosingClass instanceSide nestedClasses findMirrorNamed: newSimpleName.
+		(existing isNil or: [existing = prvtDeclaration])
+			ifFalse: [Error signal: 'A sibling already exists with the name ',newSimpleName].
 
-removeMirror: m = (
+		"remove old accessors"
+		prvtDeclaration enclosingClass instanceSide nestedClasses
+			removeSlotAndAccessorOf: prvtDeclaration.
+	].
 
-
 
-'private'
+	"patch header source with the new name"
+	token:: (grammar TypedNS3Grammar new classHeader parse: source readStream) first.
+	newHeaderSource:: 
+		(source copyFrom: 1 to: token start - 1) , 
+		newSimpleName , 
+		(source copyFrom: token end + 1 to: source size).
 
-lowLevelMixin = (
 
-
+	"compile etc"
 
-)
+	compiledResults:: compiler 
+		compileClassHeader: ('Newspeak3 ''', category, ''' class ', newHeaderSource) readStream
+		of: prvtDeclaration.	
+	
+	prvtDeclaration lazyIsTopLevel ifTrue: [
+		"Result directly corresponds to me"
+		prvtDeclaration checkForSlotConflicts: compiledResults first.
+		prvtDeclaration prvtCompiledMixinMirror: compiledResults first.
+	] ifFalse: [
+		"Result corresponds to my enclosing class, since my slot/accessor may have been adjusted"
+		| newRep <MixinRep> = onlyElementOf: compiledResults last. |
+		prvtDeclaration checkForSlotConflicts: newRep first.
+		prvtDeclaration enclosingClass prvtCompiledMixinMirror: compiledResults first.	
+		prvtDeclaration prvtCompiledMixinMirror: newRep first.
+	].
+)
+primaryFactory ^ <MethodBuiler> = (
 
-
+	| lowLevelMethodMirror |
 
-class MethodBuilder reflecting: llm in: mb = (
-"Describe the class in this comment."
-|
-	prvtLowLevelMethodMirror = llm.
-	prvtMixinBuilder = mb.
-|
-)
+	lowLevelMethodMirror:: prvtDeclaration prvtCompiledMixinMirror lowLevelMirror classMixin methods mirrors
+		detect: [:mirror | mirror isConstructor].
 
-('as yet unclassified'
+	^MethodBuilder reflecting: lowLevelMethodMirror in: prvtDeclaration classSide
+)
+source ^<String> = (
+	^prvtDeclaration prvtCompiledMixinMirror header
+)
+source: newHeaderSource <String> = (
+	prvtDeclaration headerFromSource: newHeaderSource
+))
+class ClassHeaderMirror reflecting: mixin <Mixin> = Mirror reflecting: mixin ("A class header defines the class' name, primary factory, superclass clause, class comment and instance initializer (slots and init expressions).
 
-category ^<Symbol> = (
+This mirror provides access to a class header based on the runtime representation.")
+('API'
+category ^ <Symbol> = (
+	^reflectee category
+)
+classComment ^ <String> = (
+	^reflectee classComment
+)
+declaration ^<ClassDeclarationMirror> = (
+	^ClassDeclarationMirror reflecting: self reflectee
+)
+primaryFactory ^ <MethodMirror> = (
 
-
+	^MethodMirror reflecting: (reflectee classMixin
+		methodDict at: primaryFactoryName)
+)
+source ^ <String> = (
+	^ reflectee cachedHeaderSource
+)'as yet unclassified'
+name ^ <Symbol> = (
+	^reflectee name
+)
+preamble ^<Symbol> = (
+	"Foo factory = SuperFoo superFactory"
+	| headerAst |
+	headerAst:: Language newspeak3 parserInstance classHeader parse: self source readStream.
+	^source copyFrom: headerAst start to: headerAst superConstructorCall end
+)
+primaryFactoryName ^ <Symbol> = (
+	^reflectee cachedConstructorName
+)
+slotDecls ^ <MirrorGroup[SlotDefMirror]> = (
+	
+	^self slots
+)
+slots ^ <MirrorGroup[SlotDefMirror]> = (
+	
+	"Need also visibility, mutablity of each"
+	^ImmutableMirrorGroup group: 
+		((reflectee instVarNames
+			reject: [:ea | ea includes: $`]) 
+				collect: [:ea | SlotMirror named: ea])
+)
+superclassClause ^ <SendAST> = (
+	self halt.
+	^(SystemMetadata definingClassMetadataOf: reflectee definingClass) superclassClause
+))
+class ClassMirror reflecting: c <Class> = Mirror reflecting: c (
+"WIP. New mirror for classes.  Does just what we need for porting the parser library.
 
-category: cat <String | Symbol> = (
+Copyright (c) 2009-2010 Gilad Bracha
 
-
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ''Software''), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
 
-definingMixin ^<MixinBuilder> = (
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
 
-
+THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"|
 
-name ^<Symbol> = (
+|)
+('as yet unclassified'
+allSuperclasses ^ <List[ClassMirror]> = (
+	| klass <Class> superclasses <List[Class]> |
+	superclasses:: MutableList new.
+	klass:: superclass.
+	[klass isNil] whileFalse:[
+		superclasses add: klass.
+		klass:: klass superclass.
+	].
+	^superclasses
+)
+canUnderstand: selector <Symbol> ^<Boolean> = (
+	
+	(mixin canUnderstand: selector) ifTrue: [^true].
+	superclass = nil
+		ifTrue: [^false]
+		ifFalse: [^superclass canUnderstand: selector].
+)
+computeMirrorGroup: mgAccessor <[Mirror, ^MirrorGroup]> ^ <MirrorGroup> = (
+"Return a mirror group based on the mixins group and those of all superclasses. The argument mgAccessor extracts a mirror group from any mirror provided to it."
+	| mg <MirrorGroup>  |
+	
+	mg:: MutableMirrorGroup group:{} within: self.
+	(allSuperclasses reverse add: self; yourself) do:[:klass <ClassMirror> |
+		mg addAllMirrors: (mgAccessor value: klass mixin)
+	].
+	^ ImmutableMirrorGroup group: mg	
+)
+enclosingObject ^ <ObjectMirror> = (
+	^SystemMetadata enclosingObjectOf: reflectee
+)
+methods ^ <MirrorGroup[MethodMirror]> = (
+	^computeMirrorGroup: [:r | r methods]
+)
+mixin ^ <MixinMirror> = (
 
-
+	^MixinMirror reflecting: reflectee mixin
+)
+name ^ <Symbol> = (
+	^reflectee name
+)
+nestedClasses ^ <MirrorGroup[ClassDeclarationMirror]> = (
+	^computeMirrorGroup: [:r | r nestedClasses]
+)
+simpleName ^ <Symbol> = (
 
-reflectee ^<CompiledMethod> = (
+	^ mixin simpleName
+)
+slots ^ <MirrorGroup[SlotMirror]> = (
+	^computeMirrorGroup: [:r | r slots].
+)
+superclass ^ <ClassMirror> = (
+	reflectee superclass isNil ifTrue:[^nil].
+	^ClassMirror reflecting: reflectee superclass
+))
+class ImmutableMirrorGroupInMixin group: mirrorz in: mixinMirror = ImmutableMirrorGroup group: mirrorz (|
+	public enclosingMixin <MixinMirror> = mixinMirror.
+	public channelForChanges <Duct> = Duct new.
+|channelForChanges beWeak owner: self)
+('private'
+private notifyAddedMirror: newMirror = (
+	channelForChanges send: (MirrorAddedEvent forNewMirror: newMirror)
+)
+private notifyRemovedMirror: oldMirror = (
+	channelForChanges send: (MirrorRemovedEvent forOldMirror: oldMirror)
+)
+private notifyReplacedMirror: oldMirror with: newMirror = (
+	channelForChanges send: (MirrorReplacedEvent from: oldMirror to: newMirror)
+)'restricted'
+updateToContain: actualMirrors <Collection[Mirror]> = (
+	
 
-
+	|
+	mirrorNames
+	|
+	"'update' out.
+	mirrors out.
+	'->' out.
+	actualMirrors out."
 
-selector ^<Symbol> = (
+	mirrorNames:: actualMirrors collect: [:newMirror |
+		| oldMirror |
+		oldMirror:: findMirrorNamed: newMirror simpleName.
+		oldMirror == nil ifTrue: [
+			mirrors addLast: newMirror.
+			notifyAddedMirror: newMirror.
+		] ifFalse: [
+			oldMirror = newMirror ifTrue: [
+				"Unchanged"
+			] ifFalse: [
+				mirrors at: (mirrors indexOf: oldMirror) put: newMirror.
+				notifyReplacedMirror: oldMirror with: newMirror.
+			]
+		].
+		newMirror simpleName.
+	].
 
-
+	mirrors copy do: [:oldMirror |
+		(mirrorNames includes: oldMirror simpleName) ifFalse: [
+			mirrors remove: oldMirror.
+			notifyRemovedMirror: oldMirror.
+		].
+	].
+))
+class MessageMirror selector: s <Symbol> args: as <List[Object]> = (
+"Reifies the notion of a message, per the Newspeak specification. This is what should actually be sent to doesNotUnderstand:"|
+	selector <Symbol>= s.
+	arguments <List[Object]> = as.
+|)
+('as yet unclassified'
+sendTo: r <Object> ^ <Object> = (
+	^r perform: selector with: arguments
+))
+class MethodBuilder reflecting: llm in: mb = (
+"Describe the class in this comment."|
+	prvtLowLevelMethodMirror = llm.
+	prvtMixinBuilder = mb.
+|)
+('as yet unclassified'
+category ^<Symbol> = (
+	^prvtLowLevelMethodMirror metadata at: #category
+)
+category: cat <String | Symbol> = (
+	^prvtLowLevelMethodMirror metadata at: #category put: cat asSymbol
+)
+definingMixin ^<MixinBuilder> = (
+	^prvtMixinBuilder
+)
+name ^<Symbol> = (
+	^prvtLowLevelMethodMirror selector
+)
+reflectee ^<CompiledMethod> = (
+	#BOGUS yourself.
+	"Poorly defined: If this a new method, the compiled method retrieved from the low level method would not be able to answer with its source.  This is because in Squeak, the compiled method has to ask for it from its class, which will fail if the method is not yet installed. Perhaps it would be better to not give access to this."
+	"^lowLevelMethodMirror compiledMethod"
+	FAIL.
+)
+selector ^<Symbol> = (
+	^name
+)
+simpleName ^<Symbol> = (
+	^name
+)
+source ^<String> = (
+	^prvtLowLevelMethodMirror method 
+		ifNil: [prvtLowLevelMethodMirror src]
+		ifNotNil: [:it | it getSource]
+))
+class MethodMirror reflecting: m <CompiledMethod> = Mirror reflecting: m (
+"A basic mirror for a language level method.")
+('as yet unclassified'
+category ^<Symbol> = (
+	^reflectee methodClass organization categoryOfElement: name
+)
+definingMixin ^<MixinMirror> = (
+	^MixinMirror reflecting: reflectee methodClass mixin
+)
+name ^<Symbol> = (
+	^reflectee selector
+)
+simpleName = (
+	^ name
+)
+source ^<String> = (
+	^reflectee getSource asString
+)
+visibility ^<Symbol> = (
+	#BOGUS yourself.  "Is the NS3 compiler setting this info?  Not that the VM respects it yet anyway..."
+	reflectee isProtected ifTrue: [^#protected].
+	reflectee isPrivate ifTrue: [^#private].
+	^#public
+))
+class Mirror reflecting: r <Object> = (
+"Top of the Mirror hierarchy. An abstract class.  
 
-simpleName ^<Symbol> = (
+Copyright (c) 2009-2010 Gilad Bracha
 
-
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ''Software''), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
 
-source ^<String> = (
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
 
-
+THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
 
-)
+"|
+	reflectee <Object> = r.
+|)
+('as yet unclassified'
+= other = (
+	^self class = other class and: [self reflectee == other reflectee]
+)
+hash = (
+	^ reflectee identityHash
+)
+isMirror ^<Boolean> = (
+	^true
+)
+printOn: stm = (
+	stm	nextPutAll: class simpleName.
+	stm	nextPutAll: ' reflecting: '.
+	reflectee printOn: stm.
+)
+reflecteeIfFail:  fblk <[Exception]> ^ <Object>  = (
+	^reflectee "default; we can always access the reflectee of a local object; subclasses may override if there are issues"
+))
+class MirrorAddedEvent forNewMirror: m = MirrorEvent (
+"Sent by a mirror group on its channelForUpdates when a new mirror has been added."|
+	public newMirror = m.
+|)
+('as yet unclassified'
+isMirrorAddedEvent ^<Boolean> = (
+	^true
+))
+class MirrorEvent = (
+""|
+|)
+('testing'
+isMirrorEvent ^<Boolean> = (
+	^true
+))
+class MirrorRemovedEvent forOldMirror: m = MirrorEvent (
+"Sent by a mirror group on its channelForUpdates when an existing mirror has been removed."|
+	public oldMirror = m.
+|)
+('as yet unclassified'
+isMirrorRemovedEvent ^<Boolean> = (
+	^true
+))
+class MirrorReplacedEvent from: oldM to: newM = MirrorEvent (
+"Sent by a mirror group on its channelForUpdates when an existing mirror has been replaced by a new mirror."|
+	public oldMirror = oldM.
+	public newMirror = newM.
+|)
+('as yet unclassified'
+isMirrorReplacedEvent ^<Boolean> = (
+	^true
+))
+class MixinBuilder forClassDeclaration: cbd lowLevelMixin: llm withNestedReps: reps = (
+"The mirror builder for mixins.  See MixinMirror."|
+	public declaration <ClassDeclarationBuilder> = cbd.
+	public isMeta <Boolean> = llm isMeta.
+	public methods <MutableMethodGroup> = MutableMethodGroup group: (methodsFrom: llm) within: self.
+	public nestedClasses <MutableNestedClassGroup> = MutableNestedClassGroup group: (nestedClassesFrom: reps) within: self.
+|)
+('accessing'
+canUnderstand: selector <Symbol> ^<Boolean> = (
+	
+	"Slot, method, nested class, or factory method"
+	
+	(methods includesMirrorNamed: selector) ifTrue: [^true].
+	(nestedClasses includesMirrorNamed: selector) ifTrue: [^true].
+	(slots includesMirrorNamed: selector) ifTrue: [^true].
+	(selector last = $:) ifTrue: [
+		#BOGUS. "Someday immutable slots will be enforced and this won't be quite right"
+		(slots includesMirrorNamed: (selector allButLast: 1)) ifTrue: [^true].
+	].
+	isMeta ifTrue: [
+		declaration header primaryFactory simpleName = selector ifTrue: [^true].
+	].
+	^false
+)
+slots ^ <ImmutableMirrorGroup[SlotMirror]> = (
+	| slotMirrors <Collection[SlotMirror]> | 
+	isMeta ifTrue: [ slotMirrors:: {} ] ifFalse: [
+		slotMirrors:: (declaration prvtCompiledMixinMirror lowLevelMirror instVars 
+			collect: [:each <InstanceVariableMirror> | SlotMirror named: each name])
+				reject: [:each <SlotMirror> | each name includes: $`].
+	].
+	^ImmutableMirrorGroup group: slotMirrors
+)'private'
+checkNameConflictsForMethod: selector <Symbol> = (
+	(nestedClasses includesMirrorNamed: selector)
+		ifTrue:[^Error signal: 'Class already has nested class named ', selector].
+	(slots includesMirrorNamed: selector)
+		ifTrue:[^Error signal: 'Class already has slot named ', selector].
+	isMeta ifTrue: [declaration header primaryFactory simpleName = selector 
+		ifTrue:[^Error signal: 'Class already has primary factory named ', selector]].
+)
+checkNameConflictsForNestedClass: klassName <Symbol> = (
+	(methods includesMirrorNamed: klassName)
+		ifTrue:[^Error signal: 'Class already has method named ', klassName].
+	(slots includesMirrorNamed: klassName)
+		ifTrue:[^Error signal: 'Class already has slot named ', klassName]	
+)
+checkNameConflictsForSlot: slotName <Symbol> = (
+	(nestedClasses includesMirrorNamed: slotName) 
+		ifTrue:[^Error signal: 'Class already has nested class named ', slotName].		
+	(methods includesMirrorNamed: slotName)
+		ifTrue:[^Error signal: 'Class already has method named ', slotName]
+)
+methodsFrom: llm <LowLevelMixinMirror> ^<List[MethodBuilder]> = (
+	^(llm methods 
+		select: [:m <LowLevelMethodMirror> | m isSynthetic not])
+			collect: [:m <LowLevelMethodMirror> | MethodBuilder reflecting: m in: self]
+)
+nestedClassesFrom: reps <List[MixinRep]> ^<List[ClassDeclarationBuilder]> = (
+	^reps collect: [:rep <MixinRep> | | nc |
+		
+		nc:: (ClassDeclarationBuilder fromMixinRep: rep forExistingMixin: nil).
+		nc prvtEnclosingDeclaration: declaration.
+		
+		"The existingMixin will be nil if this is a new (uninstalled) class declaration."
+		declaration reflectee ifNotNil: [:mixin |
+			| nestedMixin |
+			nestedMixin:: mixin nestedMixins at: nc name.
+			nc prvtExistingMixin: nestedMixin.
+		].
+		
+		nc
+	]
+)
+notifyExistingMirrors = (
+	isMeta
+		ifTrue: [mixinChanged: declaration reflectee classMixin]
+		ifFalse: [mixinChanged: declaration reflectee].
 
-
+	nestedClasses do: [:ea | ea notifyExistingMirrors].
+)) : ('as yet unclassified'
+reflecting: mixin <Mixin | ClassMixin> ^<MixinBuilder> = (
+	^mixin isMeta
+		ifTrue: [(ClassDeclarationBuilder reflecting: mixin definingClass theNonMetaClass mixin) classSide]
+		ifFalse: [(ClassDeclarationBuilder reflecting: mixin) instanceSide]
+))
+class MixinMirror reflecting: m <Mixin> = Mirror reflecting: m (
+"A mixin is the difference between a class and its superclass: a set of additional methods, slots and nested class declarations.  Newspeak class declarations define an instance-side mixin and a class-side mixin, and Newspeak classes (other than Top) are all the result of mixin application.
 
-class ClassDeclarationMirror reflecting: mixin <Mixin> = Mirror reflecting: mixin (
-"A class declaration defines the instance and class sides, and a header. Each side comprises methods and nested classes. The header provides a superclass clauses, a primary factory a class comment and an instance initializer.  
-
-This mirror provides a view of a class declaration based on its runtime representation in the Newspeak image running on Squeak. To create an instance, provide the instance-side mixin. The mirror can obtain all necessary information from that."
-|
-	instanceSideLazy
-	classSideLazy
-|
-	assert: [mixin isMixin & mixin isMeta not] message: 'Provide an instance-side mixin'
-)
+What about mirroring the initializer?
+Need to decide who does these things - the class declaration mirror or the mixin mirror. One should delegate to the other."|
+	slotsLazy
+	methodsLazy 
+	nestedClassesLazy 
+|mixinBasedMirrors add: self)
+('accessing'
+applications ^<Set[ClassMirror]> = (
 
-('API'
+	^reflectee applications collect: [:ea | ClassMirror reflecting: ea]
+)
+canUnderstand: selector <Symbol> ^<Boolean> = (
+	
+	"Slot, method, nested class, or factory method"
+	
+	(methods includesMirrorNamed: selector) ifTrue: [^true].
+	(nestedClasses includesMirrorNamed: selector) ifTrue: [^true].
+	(slots includesMirrorNamed: selector) ifTrue: [^true].
+	(selector last = $:) ifTrue: [
+		#BOGUS. "Someday immutable slots will be enforced and this won't be quite right"
+		(slots includesMirrorNamed: (selector allButLast: 1)) ifTrue: [^true].
+	].
+	isMeta ifTrue: [
+		declaration header primaryFactory simpleName = selector ifTrue: [^true].
+	].
+	^false
+)
+declaration ^ <ClassDeclarationMirror> = (
+	^ClassDeclarationMirror 
+		reflecting: (isMeta ifFalse:[reflectee] ifTrue:[reflectee instanceMixin]) 
+)
+isMeta ^ <Boolean> = (
+	^self reflectee isMeta
+)
+isMixinMirror ^<Boolean> = (
+	^true
+)
+methods ^ <MirrorGroup[MethodMirror]> = (
+	methodsLazy ifNil: [
+		methodsLazy:: ImmutableMirrorGroupInMixin group: computeMethods in: self].
+	^methodsLazy
+)
+name ^ <Symbol> = (
+	^reflectee name
+)
+nestedClasses ^ <MirrorGroup[ClassDeclarationMirror]> = (
+	nestedClassesLazy ifNil: [
+		nestedClassesLazy:: ImmutableMirrorGroupInMixin group: computeNestedClasses in: self].
+	^nestedClassesLazy
+)
+simpleName ^ <Symbol> = (
 
-classSide ^ <MixinMirror> = (
+	^ SystemMetadata fullyQualifiedNameToSimple: reflectee simpleName
+)
+slots ^ <MirrorGroup[SlotMirror]> = (
+	slotsLazy ifNil: [
+		slotsLazy:: ImmutableMirrorGroupInMixin group: computeSlots in: self].
+	^slotsLazy
+)'as yet unclassified'
+classMixin ^ <MixinMirror> = (
+	#BOGUS yourself.
+	isMeta 
+		ifFalse:[^MixinMirror reflecting: reflectee classMixin]
+		ifTrue:[^MixinMirror reflecting: Metaclass mixin].
+		"This would be true in a pure Newspeak system, but not on our implementation"
+)
+computeMethods ^ <Collection[MethodMirror]> = (
 
-
+	^(reflectee methodDictionary values
+		collect: [:each <CompiledMethod> | MethodMirror reflecting: each])
+			reject: [:each <MethodMirror> | each reflectee isSynthetic].
+)
+dualMixin ^ <MixinMirror> = (
+	isMeta 
+		ifTrue:[^MixinMirror reflecting: reflectee instanceMixin]
+		ifFalse:[^classMixin].
+)'private'
+computeNestedClasses ^<Collection[ClassDeclarationMirror]> = (
+	| metadata |
+	isMeta ifTrue: [^{}].
 
-enclosingClass ^ <ClassDeclarationMirror> = (
+	^reflectee nestedMixins values 
+		collect: [:each | ClassDeclarationMirror reflecting: each]
+)
+computeSlots ^ <Collection[SlotMirror]> = (
 
-
+	^(reflectee instVarNames 
+		reject: [:iv <String> | iv includes: $`])
+			collect: [:iv <String> | SlotMirror named: iv].
+)'restricted'
+mixinChanged = (
+	slotsLazy ifNotNil: [:it | it updateToContain: computeSlots].
+	methodsLazy ifNotNil: [:it | it updateToContain: computeMethods].
+	nestedClassesLazy ifNotNil: [:it | it updateToContain: computeNestedClasses].
+))
+class MutableMethodGroup group: mirrors within: mb = MutableMirrorGroup group: mirrors within: mb (
+""|
+|)
+('accessing'
+addFromSource: s <String> = (
+	| 
+	result <LowLevelMethodMirror>
+	cat
+	newM
+	|
+	result:: compiler
+		compileMethodSource: s readStream 
+		within: enclosingMixin declaration.
+	
+	cat:: (findMirrorNamed: result simpleName)
+		ifNil: [#'as yet unclassified']
+		ifNotNil: [:oldMirror | oldMirror category].
+	
+	result metadata at: #category put: cat.
+	"Category must be set or it will think it's synthetic and lose the source"
+	
+	newM:: MethodBuilder reflecting: result in: enclosingMixin.
+	addMirror: newM.
+	^newM
+)
+addMirror: m <MethodBuilder>= (
+	
+	"What would it mean if a user of builders called this?  A MethodMirror would need to be converted to a MethodBuilder.  A MethodBuilder that already is a member of another method group may need to be copied."
+	
+	enclosingMixin checkNameConflictsForMethod: m name.
+	
+	super addMirror: m.
+	lowLevelMixin methods addMirror: m prvtLowLevelMethodMirror.
+	^m
+)
+removeMirror: m = (
 
-fullyQualifiedName ^ <Symbol> = (
+	super removeMirror: m.
+	lowLevelMixin methods removeMirror: m prvtLowLevelMethodMirror.
+)'private'
+lowLevelMixin = (
+	"Cannot cache from instantiation: might be replaced by editing class header or add/remove nested class."	
+	^enclosingMixin isMeta
+		ifTrue: [enclosingMixin declaration compiledMixinMirror lowLevelMirror classMixin]
+		ifFalse: [enclosingMixin declaration compiledMixinMirror lowLevelMirror].
+))
+class MutableMirrorGroup group: ms within: mb = ImmutableMirrorGroup group: ms (
+"A mirror group for high level mirrors. Takes base level elements as arguments to be added, and supports a notion of ordering, so that source declaration ordering can be preserved.
 
-
+A MutableMirrorGroup knows about its enclosing mirror, because it supports adding members in source form via the #addFromSource: abstract method, which is specialized by subclasses. The source must be compiled, and that requires the enclosing mirror to provide the necessary surrounding scope.
+"| 
+	public enclosingMixin <MixinBuilder> = mb.	"definingMixin?"
+|)
+('as yet unclassified'
+addAllMirrors: mirrorGroup <MirrorGroup | Collection[Mirror]> = (
+	mirrorGroup do: [:each | addMirror: each]
+)
+addFromSource: s <String> = (
+	self subclassResponsibility
+)
+addMirror: m <Mirror>  = (
+	mirrors keysAndValuesDo: [:index :mirror | 
+		mirror simpleName = m simpleName ifTrue: [^mirrors at: index put: m]].
+	^mirrors addLast: m
+)
+mirrors ^ <MutableHashedMap[Mirror]> = (
+" mirrors is also an outer scope slot; we define this method to ensure we get the inherited one."
+	^super mirrors
+)
+removeAll = (
+	mirrors: MutableList new.
+)
+removeAllSuchThat: blk = (
+	mirrors select: blk thenDo: [ :m <Mirror> | removeMirrorNamed: m name].
+)
+removeMirror: m <Mirror> = (
+	^mirrors remove: m
+)
+removeMirrorNamed: n <Symbol | String> = (
+	| m |
+	m:: findMirrorNamed: n.
+	^m ifNotNil: [removeMirror: m].
+))
+class MutableNestedClassGroup group: mirrors within: mb = MutableMirrorGroup group: mirrors within: mb (
+""|
+|)
+('accessing'
+addFromSource: source <String> ^<ClassDeclarationBuilder> = (
+	|
+	enclosingDeclaration
+	compiledResults <MixinRep>
+	nestedReps
+	newCDB
+	|
+	enclosingDeclaration:: enclosingMixin declaration.
+	
+	compiledResults:: compiler 
+		compileClassSource: ('Newspeak3 ''', enclosingDeclaration header category, ''' ', source) readStream
+		within: enclosingDeclaration.
+		
+	enclosingDeclaration prvtCompiledMixinMirror: compiledResults first.
+	nestedReps:: compiledResults last.
+	
+	assert: [nestedReps size = 1] message: 'Does it only answer with me and not my siblings?'.
+	
+	newCDB:: ClassDeclarationBuilder fromMixinRep: nestedReps first forExistingMixin: nil.
+	newCDB prvtEnclosingDeclaration: enclosingDeclaration.
+		
+	addMirror: newCDB.
+	^newCDB
+)
+addMirror: m <ClassDeclarationBuilder> = (
 
-header ^ <ClassHeaderMirror> = (
+	#BOGUS yourself.
+	"What would it mean if a user of builders called this?  A ClassDeclarationMirror would need to be converted to a ClassDeclarationBuilder.  A ClassDeclarationBuilder that already has an enclosing class different than this group's would need to be deep copied."
 
-
+	enclosingMixin checkNameConflictsForNestedClass: m simpleName.
+	super addMirror: m.
+	^m
+)'as yet unclassified'
+removeMirror: victim <ClassDeclarationBuilder> = (
+	|
+	victimName
+	sep
+	|
+	"Must patch the enclosing class of the victim"
+	removeSlotAndAccessorOf: victim.
+	
+	super removeMirror: victim.
+)
+removeSlotAndAccessorOf: victim <ClassDeclarationBuilder> = (
+	|
+	victimName
+	sep
+	|
+	victimName: victim fullyQualifiedName.
+	sep:: Language newspeak3 syntheticNameSeparator.
+	lowLevelMixin methods removeMirrorNamed: victimName,sep,'slot'.
+	lowLevelMixin methods removeMirrorNamed: victimName,sep,'slot:'.
+	lowLevelMixin methods removeMirrorNamed: victim simpleName.
+	lowLevelMixin instVars removeMirrorNamed: victimName,sep,'slot'.
+	
+	"Indices can change if the victim's slot is not the last one"
+	compiler generateSlotAccessorsFor: lowLevelMixin.
+)'private'
+lowLevelMixin = (
+	"Cannot cache from instaniation: might be replaced by editing class header or add/remove nested class."
+	^enclosingMixin isMeta
+		ifTrue: [enclosingMixin declaration compiledMixinMirror lowLevelMirror classMixin]
+		ifFalse: [enclosingMixin declaration compiledMixinMirror lowLevelMirror].
+))
+class ObjectMirror reflecting: r <Object> = Mirror reflecting: r (
+"A high level mirror on local objects. The API for a Newspeak object mirror is exceedingly simple. One can view or change its reflectee's class; one can send the reflectee a message; one can set the reflectee's slots; and one can request access to the reflectee.  We may later extend this with printing/safe printing, the ability to execute an arbitrary method on the reflectee, or generalized super-object access.
 
-instanceSide ^ <MixinMirror> = (
+All of this is realized in methods of this class, except reflectee access which is inherited.
 
-
+Note that there is no need to get slots - we can send a message to do that.  However, for the time being we support that as well, as there is no way to access overridden features.
 
-name ^ <Symbol> = (
+The differences between #perform: on an object and a mirror are:
 
-
+1. The mirror can perform private messages.
+2. The mirror forces the user to deal with possible failure.
+3. The result is also a mirror.
 
-simpleName ^ <Symbol> = (
+We may choose to refactor the implementation so that all the work is done by a NewspeakObjectMirorUtility. The idea is that in cases where many objects are involved, it is wasteful to allocate a dedicated mirror per object. Instead,  the utility can be shared across all the objects. This works as long as we are prepared to give out a global authority to mirror all objects; if we want fine grain security, we need a capability per object.
 
-
+Copyright (c) 2009-2010 Gilad Bracha
 
-source ^ <String> = (
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ''Software''), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
 
-
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
 
-'restricted'
+THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
 
-compiledMixinMirror = (
+")
+('as yet unclassified'
+evaluate: expression <String> ^<ObjectMirror> = (
+	
+	| cls mxn mtdMirror result |
+	cls:: vmmirror classOf: reflectee.
+	mxn:: MixinMirror reflecting: cls mixin.
+	mtdMirror:: compiler
+		compileExpressionSource: expression readStream
+		inContext: nil
+		inMixin: mxn declaration. 
+		
+	mtdMirror metadata at: #category put: 'DoIts'.
+	mtdMirror klass: cls.
+	
+	result:: vmmirror 
+		object: reflectee 
+		executeMethod: mtdMirror compiledMethod
+		with: {}
+		ifFail: [primitiveFailed].
 
-
+	^ObjectMirror reflecting: result
+)
+getClassIfFail:  fblk <[Exception]> ^ <ClassMirror>  = (
+	^ClassMirror reflecting: (vmmirror classOf: reflectee)  "never fails on local objects"
+)
+getSlot: slotName <Symbol> ifFail:  fblk <[Exception, ^R def]> ^ <ObjectMirror | R> = (
+	^self class reflecting: ( vmmirror
+		namedSlotOf: reflectee
+		at: (reflectee class instVarIndexFor: slotName)
+		ifFail: fblk
+	)
+)
+perform: selector <Symbol> with:  args <Array[Object]> ifFail:  fblk <[Exception]>  ^ <ObjectMirror> = (
+	| result <Object> |
+	result:: [reflectee perform: selector withArguments: args] on: Error do: [:ex <Error> | ^fblk value: ex].
+	^self class reflecting: result
+)
+setClass: klass <Class | ClassMirror> ifFail:  fblk <[Exception]> ^ <ClassMirror>  = (
+	vmmirror changeClassOf: reflectee to: klass ifFail: fblk
+)
+setSlot: slotName <Symbol> to:  obj <Object> ifFail:  fblk <[Exception]> = (
+	vmmirror
+		namedSlotOf: reflectee
+		at: (reflectee class instVarIndexFor: slotName)
+		put: obj
+		ifFail: fblk
+))
+class SlotMirror named: n <String> = Mirror reflecting: n (
+"WIP. Just enough to get us going.
 
-'testing'
+Copyright (c) 2009-2010 Gilad Bracha
 
-isClassDeclarationMirror ^<Boolean> = (
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ''Software''), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
 
-
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
 
-)
+THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.")
+('as yet unclassified'
+isMutable = (
+	"Used by compiler in scope building"
+	^true
+)
+name ^ <String> = (
+	#BOGUS yourself.
+	^reflectee
+)
+simpleName = (
 
-
+	^ name
+)
+source = (
+	^name
+))'as yet unclassified'
+compiler ^ <Newspeak3Compilation Compiler> = (
+	storedCompiler ifNil:[
+			storedCompiler:: compilation Compiler new.
+			storedCompiler language: Language newspeak3.	].
+	^storedCompiler
+)
+fullyQualifiedNameToSimple: name = (
+	^(name subStrings: {$`}) last asSymbol
+)
+isSubInitializerSelector: sel = (
+	| ts  <OrderedCollection[String]> | 
+	ts:: sel findTokens: syntheticNameSeparator.
+	^ ts size > 1 
+		and: [(ts at: ts size - 1) allSatisfy: [:x|x isDigit]] 
+		and: [ (ts last) startsWith: 'init' ].	
+)
+mixinChanged: mixin = (
+	#BOGUS. "It really should be 'mirror reflectee == mixin', but it appears there are still issues with atomic install"
+	mixinBasedMirrors do: [:mirror | 
+		mirror reflectee definingClass = mixin definingClass ifTrue: [mirror mixinChanged]].
+)
+onlyElementOf: tuple = (
+	assert: [tuple size = 1] message: 'The tuple does not have a single item.'.
+	^tuple first
+)'construct-mixinrep'
+isConstructorSelector: sel forMixin: mxn = (
+	^mxn declaration header primaryFactoryName = sel
+	"^ (sel = 'new') 
+		ifTrue: [ true ]
+		ifFalse: [ | src <Yield> impl | 
+			impl:: mxn isMeta
+			ifFalse: [ mxn implementationMirror ]
+			ifTrue: [ | klass <Class> |
+				klass:: mxn implementationMirror implementationClass.
+				(reflectionClass new mixinFor: klass theNonMetaClass) implementationMirror
+			].
+		src:: impl classHeader constructor.
+		src isNil 
+			ifTrue: [ false ]
+			ifFalse: [ | mp <MessagePatternAST> |
+				mp:: parserInstance messagePattern parse: src contents readStream.
+				sel = mp selector]]."
+)
+isNestedClassAccessorSelector: sel forMixin: mxn = (
+	| ts <OrderedCollection[String]> |
+	ts:: sel findTokens: syntheticNameSeparator.
+	^ (ts size = 1 and: [mxn nestedClasses includesMirrorNamed: ts anyOne])
+		or: [ ts size > 2 
+			and: [(ts last = 'slot' or: [ts last = 'slot:']) 
+				and: [mxn nestedClasses includesMirrorNamed: (ts at: ts size - 1)]]]
+)
+isSlotAccessorSelector: sel forMixin: mxn = (
+	^ (mxn slots includesMirrorNamed: sel)
+		or: [(sel endsWith: ':') 
+			and: [mxn slots includesMirrorNamed: (sel copyFrom: 1 to: sel size - 1)]].	
+)
+isSuperConstructorSelector: sel = (
+	| ts  <OrderedCollection[String]> | 
+	ts:: sel findTokens: syntheticNameSeparator.
+	^ ts size > 1 and: [(ts at: ts size - 1) = 'superInit'].
+)
+makeCompiledMixinMirrorFor: lowLevelMixinMirror <LowLevelMixinMirror> from: mixin <Mixin> = (
 
-class MessageMirror selector: s <Symbol> args: as <List[Object]> = (
-"Reifies the notion of a message, per the Newspeak specification. This is what should actually be sent to doesNotUnderstand:"
-|
-	selector <Symbol>= s.
-	arguments <List[Object]> = as.
-|
-)
+	^(CompiledMixinMirror 
+		language: mixin language
+		header:  mixin cachedHeaderSource
+		mirror: lowLevelMixinMirror)
+	comment: mixin classComment.	
+)
+makeCompiledMixinMirrorForMixin: mixin <Mixin> = (
+	^ makeCompiledMixinMirrorFor: (makeLowLevelMixinMirrorFor: mixin) from: mixin.
+)
+makeLowLevelMixinMirrorFor: mixin <Mixin> = (
+	| llm <LowLevelMixinMirror> llcm | 
+	assert:[mixin isMeta not] message: ''.
+	
+	llm:: LowLevelMixinMirror named: mixin name isMeta: false.
 
-('as yet unclassified'
+	"instance variables -- n.b. slot accessors need to be generated"
+	mixin instVarNames do: [: iv | 
+		llm instVars addMirror: (lowLevelMirrors InstanceVariableMirror named: iv)
+	].
 
-sendTo: r <Object> ^ <Object> = (
+	"methods"
+	mixin methodDictionary keysAndValuesDo: [ :selector :method |
+		| methodMirror |
+		methodMirror:: LowLevelMethodMirror new.
+		methodMirror method: method. 
+		methodMirror klass: mixin.
+		methodMirror selector: selector.
+		llm methods addMirror: methodMirror.
+	].
+	setMetadataForMixinMirror: llm inMixin: mixin .
 
-
+	"category"
+	llm category: (mixin category ifNil:['Uncategorized']).
+	
+	"meta class / class side"
+	llcm:: lowLevelMirrors LowLevelMixinMirror named: mixin classMixin name isMeta: true.
+	mixin classMixin methodDictionary keysAndValuesDo: [ :selector :method |
+		| methodMirror |
+		methodMirror:: LowLevelMethodMirror new.
+		methodMirror method: method. 
+		methodMirror klass: mixin classMixin.
+		methodMirror selector: selector.
+		llcm methods addMirror: methodMirror.
+	].
+	setMetadataForMixinMirror: llcm inMixin: mixin classMixin.
+	llm cachedClassMixin: llcm.
+	
+	^llm
+)
+mixinRepFor: mixin <Mixin> ^ <MixinRep> = (
+	^{
+	makeCompiledMixinMirrorForMixin: mixin. 
+	mixin nestedMixins values collect: [ :nc <Class> | mixinRepFor: nc ].
+	}
+)
+setMetadataForMethodMirror: mirror <LowLevelMethodMirror> inMixin: mixin <Mixin|ClassMixin> = (
+	| category <String> |
 
-)
+	category:: (mixin organization categoryOfElement: mirror selector).
+	mirror metadata at: #isSynthetic put: category isNil.
+	mirror metadata at: #category put: category.
+	category ifNil: [ setMetadataForSyntheticMethod: mirror inMixin: mixin ].
+)
+setMetadataForMixinMirror: mirror <LowLevelMixinMirror> inMixin: mixin <Mixin|ClassMixin> = (
 
-
+	mirror methods do: [ :mm <LowLevelMethodMirror> |
+		setMetadataForMethodMirror: mm inMixin: mixin.
+	].
+)
+setMetadataForSyntheticMethod: mtd <LowLevelMethodMirror> inMixin: mixin <Mixin|ClassMixin> = (
+	| selector meta mxn |
 
-class ClassHeaderBuilder forClassDeclaration: decl = (
-"Describe the class in this comment."
-|
-	prvtDeclaration <ClassDeclarationBuilder> = decl.
-|
-)
+	mxn:: MixinMirror reflecting: mixin.
+	selector:: mtd selector.
 
-('as yet unclassified'
+	meta:: mtd metadata.
+	"meta at: #isSuperConstructor put: false.
+	meta at: #isSubInitializer put: false.
+	meta at: #isConstructor put: false.
+	meta at: #isSlotAccessor put: false.
+	meta at: #isNestedClassAccessor put: false."
 
-category ^<Symbol> = (
-
-
-
-category: c <Symbol | String> = (
-
-
-
-name ^<Symbol> = (
-
-
-
-name: newSimpleName <Symbol> = (
-
-
-
-primaryFactory ^ <MethodBuiler> = (
-
-
-
-source ^<String> = (
-
-
-
-source: newHeaderSource <String> = (
-
-
-
-)
-
-
-
-class SlotMirror named: n <String> = Mirror reflecting: n (
-"WIP. Just enough to get us going.
-
-Copyright (c) 2009-2010 Gilad Bracha
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the ''Software''), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE."
-)
-
-('as yet unclassified'
-
-isMutable = (
-
-
-
-name ^ <String> = (
-
-
-
-simpleName = (
-
-
-
-source = (
-
-
-
-)
-
-
-
-class MixinMirror reflecting: m <Mixin> = Mirror reflecting: m (
-"A mixin is the difference between a class and its superclass: a set of additional methods, slots and nested class declarations.  Newspeak class declarations define an instance-side mixin and a class-side mixin, and Newspeak classes (other than Top) are all the result of mixin application.
-
-What about mirroring the initializer?
-Need to decide who does these things - the class declaration mirror or the mixin mirror. One should delegate to the other."
-|
-	slotsLazy
-	methodsLazy 
-	nestedClassesLazy 
-|
-	mixinBasedMirrors add: self.
-
-)
-
-('as yet unclassified'
-
-classMixin ^ <MixinMirror> = (
-
-
-
-computeMethods ^ <Collection[MethodMirror]> = (
-
-
-
-dualMixin ^ <MixinMirror> = (
-
-
-
-'accessing'
-
-applications ^<Set[ClassMirror]> = (
-
-
-
-canUnderstand: selector <Symbol> ^<Boolean> = (
-
-
-
-declaration ^ <ClassDeclarationMirror> = (
-
-
-
-isMeta ^ <Boolean> = (
-
-
-
-isMixinMirror ^<Boolean> = (
-
-
-
-methods ^ <MirrorGroup[MethodMirror]> = (
-
-
-
-name ^ <Symbol> = (
-
-
-
-nestedClasses ^ <MirrorGroup[ClassDeclarationMirror]> = (
-
-
-
-simpleName ^ <Symbol> = (
-
-
-
-slots ^ <MirrorGroup[SlotMirror]> = (
-
-
-
-'private'
-
-computeNestedClasses ^<Collection[ClassDeclarationMirror]> = (
-
-
-
-computeSlots ^ <Collection[SlotMirror]> = (
-
-
-
-'restricted'
-
-mixinChanged = (
-
-
-
-)
-
-
-
-class MirrorAddedEvent forNewMirror: m = MirrorEvent (
-"Sent by a mirror group on its channelForUpdates when a new mirror has been added."
-|
-	public newMirror = m.
-|
-)
-
-('as yet unclassified'
-
-isMirrorAddedEvent ^<Boolean> = (
-
-
-
-)
-
-
-
-class ClassDeclarationBuilder fromMixinRep: rep <MixinRep> forExistingMixin: mixin <Mixin> = (
-"
-Builders do not give an ordinary mirror representing their current state: ask the builder itself. (Although this could be done: submit to atomic install without a namespace, don't install into Smalltalk, don't update the existingMixin, and reflect on the result.)
-
-Builders internally keep a CompiledMixinMirror that reflects the current state, including edits made but not yet installed. Queries reflect the state of this CMM.
-
-Builders are connected up and down.  If you get a builder on a declaration, if you ask *the builder* for an enclosing or nested declaration and edit, installing any of them means installing all of them.  Builders created de novo (via reflecting: or fromSource:) remain independent.
-"
-|
-	"Used to create the namespace for AtomicInstall so existing instances are updated"
-	prvtExistingMixin <Mixin | nil> = mixin.
-
-	"Lazy.  It should not be neccessary to always unpack an entire module definition.
-	Perhaps this should be eager to complete creating-a-builder-is-like-forking semantics."
-	prvtEnclosingDeclaration <ClassDeclarationBuilder>
-	
-	"Eager. Simplifies CDB on installed CD versus new CD.  This must be computed anyway to install."
-	public instanceSide <MixinBuilder> = MixinBuilder 
-		forClassDeclaration: self
-		lowLevelMixin: rep first lowLevelMirror
-		withNestedReps: rep last.
-		
-	public classSide <MixinBuilder> = MixinBuilder 
-		forClassDeclaration: self
-		lowLevelMixin: rep first lowLevelMirror classMixin
-		withNestedReps: {}.
-	
-	prvtCompiledMixinMirror <CompiledMixinMirror> = rep first.
-	
-	public header <ClassHeaderBuilder> = ClassHeaderBuilder forClassDeclaration: self.
-|
-)
-
-('API'
-
-enclosingClass ^<ClassDeclarationBuilder> = (
-
-
-
-fullyQualifiedName ^<Symbol> = (
-
-
-
-headerFromSource: newHeader <String> = (
-
-
-
-install ^<ClassDeclarationMirror> = (
 
-
-
-
-name ^<Symbol> = (
-
-
-
-reflectee ^<Mixin | nil> = (
-
-
-
-simpleName ^<Symbol> = (
-
-
-
-'private'
-
-checkForNameChange: newCompiledMixinMirror = (
-
-
-
-checkForSlotConflicts: newCompiledMixinMirror = (
-
-
-
-collectMixinRepInto: dict <IdentityMap[MixinRep,Mixin]> ^<MixinRep> = (
-
-
-
-compiledMixinMirror = (
-
-
-
-extractReflecteeFrom: mixin <Mixin> = (
-
-
-
-lazyIsTopLevel = (
-
-
-
-notifyExistingMirrors = (
-
-
-
-'as yet unclassifed'
-
-printOn: stm = (
-
-
-
-'testing'
-
-isClassDeclarationMirror ^<Boolean> = (
-
-
-
-) : (
-
-'as yet unclassified'
-
-reflecting: mixin <Mixin> ^<ClassDeclarationBuilder> = (
-
-
-
-fromUnitSource: src <String> ^<ClassDeclarationBuilder> = (
-
-
-
-'accessing'
-
-fromSource: src <String> ^<ClassDeclarationBuilder> = (
-
-
-
-)
-
-
-
-class MirrorReplacedEvent from: oldM to: newM = MirrorEvent (
-"Sent by a mirror group on its channelForUpdates when an existing mirror has been replaced by a new mirror."
-|
-	public oldMirror = oldM.
-	public newMirror = newM.
-|
-)
-
-('as yet unclassified'
-
-isMirrorReplacedEvent ^<Boolean> = (
-
-
-
-)
-
-
-
-class ClassMirror reflecting: c <Class> = Mirror reflecting: c (
-"WIP. New mirror for classes.  Does just what we need for porting the parser library.
-
-Copyright (c) 2009-2010 Gilad Bracha
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the ''Software''), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-"
-|
-
-|
-)
-
-('as yet unclassified'
-
-allSuperclasses ^ <List[ClassMirror]> = (
-
-
-
-canUnderstand: selector <Symbol> ^<Boolean> = (
-
-
-
-computeMirrorGroup: mgAccessor <[Mirror, ^MirrorGroup]> ^ <MirrorGroup> = (
-
-
-
-enclosingObject ^ <ObjectMirror> = (
-
-
-
-methods ^ <MirrorGroup[MethodMirror]> = (
-
-
-
-mixin ^ <MixinMirror> = (
-
-
-
-name ^ <Symbol> = (
-
-
-
-nestedClasses ^ <MirrorGroup[ClassDeclarationMirror]> = (
-
-
-
-simpleName ^ <Symbol> = (
-
-
-
-slots ^ <MirrorGroup[SlotMirror]> = (
-
-
-
-superclass ^ <ClassMirror> = (
-
-
-
-)
-
-
-
-class MixinBuilder forClassDeclaration: cbd lowLevelMixin: llm withNestedReps: reps = (
-"The mirror builder for mixins.  See MixinMirror."
-|
-	public declaration <ClassDeclarationBuilder> = cbd.
-	public isMeta <Boolean> = llm isMeta.
-	public methods <MutableMethodGroup> = MutableMethodGroup group: (methodsFrom: llm) within: self.
-	public nestedClasses <MutableNestedClassGroup> = MutableNestedClassGroup group: (nestedClassesFrom: reps) within: self.
-|
-)
-
-('private'
-
-checkNameConflictsForMethod: selector <Symbol> = (
-
-
-
-checkNameConflictsForNestedClass: klassName <Symbol> = (
-
-
-
-checkNameConflictsForSlot: slotName <Symbol> = (
-
-
-
-methodsFrom: llm <LowLevelMixinMirror> ^<List[MethodBuilder]> = (
-
-
-
-nestedClassesFrom: reps <List[MixinRep]> ^<List[ClassDeclarationBuilder]> = (
-
-
-
-notifyExistingMirrors = (
-
-
-
-'accessing'
-
-canUnderstand: selector <Symbol> ^<Boolean> = (
-
-
-
-slots ^ <ImmutableMirrorGroup[SlotMirror]> = (
-
-
-
-) : (
-
-'as yet unclassified'
-
-reflecting: mixin <Mixin | ClassMixin> ^<MixinBuilder> = (
-
-
-
-)
-
-
-
-class ObjectMirror reflecting: r <Object> = Mirror reflecting: r (
-"A high level mirror on local objects. The API for a Newspeak object mirror is exceedingly simple. One can view or change its reflectee's class; one can send the reflectee a message; one can set the reflectee's slots; and one can request access to the reflectee.  We may later extend this with printing/safe printing, the ability to execute an arbitrary method on the reflectee, or generalized super-object access.
-
-All of this is realized in methods of this class, except reflectee access which is inherited.
-
-Note that there is no need to get slots - we can send a message to do that.  However, for the time being we support that as well, as there is no way to access overridden features.
-
-The differences between #perform: on an object and a mirror are:
-
-1. The mirror can perform private messages.
-2. The mirror forces the user to deal with possible failure.
-3. The result is also a mirror.
-
-We may choose to refactor the implementation so that all the work is done by a NewspeakObjectMirorUtility. The idea is that in cases where many objects are involved, it is wasteful to allocate a dedicated mirror per object. Instead,  the utility can be shared across all the objects. This works as long as we are prepared to give out a global authority to mirror all objects; if we want fine grain security, we need a capability per object.
-
-Copyright (c) 2009-2010 Gilad Bracha
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the ''Software''), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-"
-
-)
-
-('as yet unclassified'
-
-evaluate: expression <String> ^<ObjectMirror> = (
-
-
-
-getClassIfFail:  fblk <[Exception]> ^ <ClassMirror>  = (
-
-
-
-getSlot: slotName <Symbol> ifFail:  fblk <[Exception, ^R def]> ^ <ObjectMirror | R> = (
-
-
-
-perform: selector <Symbol> with:  args <Array[Object]> ifFail:  fblk <[Exception]>  ^ <ObjectMirror> = (
-
-
-
-setClass: klass <Class | ClassMirror> ifFail:  fblk <[Exception]> ^ <ClassMirror>  = (
-
-
-
-setSlot: slotName <Symbol> to:  obj <Object> ifFail:  fblk <[Exception]> = (
-
-
-
-)
-
-
-
-class MirrorRemovedEvent forOldMirror: m = MirrorEvent (
-"Sent by a mirror group on its channelForUpdates when an existing mirror has been removed."
-|
-	public oldMirror = m.
-|
-)
-
-('as yet unclassified'
-
-isMirrorRemovedEvent ^<Boolean> = (
-
-
-
-)
-
-
-
-class ClassHeaderMirror reflecting: mixin <Mixin> = Mirror reflecting: mixin ("A class header defines the class' name, primary factory, superclass clause, class comment and instance initializer (slots and init expressions).
-
-This mirror provides access to a class header based on the runtime representation."
-
-)
-
-('as yet unclassified'
-
-name ^ <Symbol> = (
-
-
-
-preamble ^<Symbol> = (
-
-
-
-primaryFactoryName ^ <Symbol> = (
-
-
-
-slotDecls ^ <MirrorGroup[SlotDefMirror]> = (
-
-
-
-slots ^ <MirrorGroup[SlotDefMirror]> = (
-
-
-
-superclassClause ^ <SendAST> = (
-
-
-
-'API'
-
-category ^ <Symbol> = (
-
-
-
-classComment ^ <String> = (
-
-
-
-declaration ^<ClassDeclarationMirror> = (
-
-
-
-primaryFactory ^ <MethodMirror> = (
-
-
-
-source ^ <String> = (
-
-
-
-)
-
-
-
-class MutableNestedClassGroup group: mirrors within: mb = MutableMirrorGroup group: mirrors within: mb (
-""
-|
-|
-)
-
-('as yet unclassified'
-
-removeMirror: victim <ClassDeclarationBuilder> = (
-
-
-
-removeSlotAndAccessorOf: victim <ClassDeclarationBuilder> = (
-
-
-
-'private'
-
-lowLevelMixin = (
-
-
-
-'accessing'
-
-addFromSource: source <String> ^<ClassDeclarationBuilder> = (
-
-
-
-addMirror: m <ClassDeclarationBuilder> = (
-
-
-
-)
-
-
-
-class MutableMirrorGroup group: ms within: mb = ImmutableMirrorGroup group: ms (
-"A mirror group for high level mirrors. Takes base level elements as arguments to be added, and supports a notion of ordering, so that source declaration ordering can be preserved.
-
-A MutableMirrorGroup knows about its enclosing mirror, because it supports adding members in source form via the #addFromSource: abstract method, which is specialized by subclasses. The source must be compiled, and that requires the enclosing mirror to provide the necessary surrounding scope.
-"
-| 
-	public enclosingMixin <MixinBuilder> = mb.	"definingMixin?"
-|
-)
-
-('as yet unclassified'
-
-addAllMirrors: mirrorGroup <MirrorGroup | Collection[Mirror]> = (
-
-
-
-addFromSource: s <String> = (
-