node@(Syntax Node traits) inferTypesIn: namespace "Assigns a type for the node as determined through propagation of existing type information and hints." [ node type ]. node@(Syntax Node traits) inferTypes [ node inferTypesIn: lobby literalType ]. _@(Syntax ImplicitArgument traits) inferTypesIn: namespace [ namespace ]. ann@(Syntax Annotation traits) inferTypesIn: namespace [ ann type: (ann value inferTypesIn: namespace) ]. message@(Syntax Message traits) inferTypesIn: namespace [ message type == Types Any ifFalse: [message arguments do: [| :argument | argument inferTypesIn: namespace]. ^ message type]. message type: (message selector inferOn: (message arguments collect: [| :argument | argument inferTypesIn: namespace])) ]. opts@(Syntax OptionalKeywords traits) inferTypesIn: namespace [| msgType | msgType: opts message inferTypes. opts arguments do: [| :argument | argument inferTypesIn: namespace]. opts type == Types Any ifTrue: [opts type: msgType]. opts type ]. paren@(Syntax Parenthesis traits) inferTypesIn: namespace [ paren statements do: [| :statement | statement inferTypesIn: namespace]. paren type == Types Any ifTrue: [paren type: paren statements last type] ifFalse: [paren type] ]. var@(Syntax Variable traits) inferTypesIn: namespace [ var type ]. block@(Syntax Block traits) inferTypesIn: namespace [| resultType | block localVariables do: [| :var | var inferTypesIn: namespace]. resultType: Types Any. block statements do: [| :statement | resultType: (statement inferTypesIn: namespace)]. block type == Types Any ifTrue: [block type: (Types Block from: (block inputVariables collect: [| :variable | variable type]) to: resultType)] ifFalse: [block type] ]. array@(Syntax Array traits) inferTypesIn: namespace [ array statements do: [| :statement | statement inferTypesIn: namespace]. array type == Types Any ifTrue: [array type: (Types Array of: (array statements inject: Types None into: [| :x :y | x union: y type]))] ifFalse: [array type] ]. obj@(Root traits) literalTypeIn: _ [ Types Singleton of: obj ]. literal@(Syntax Literal traits) inferTypesIn: namespace [ literal type == Types Any ifTrue: [literal type: (literal value literalTypeIn: namespace)] ifFalse: [literal type] ]. load@(Syntax LoadVariable traits) inferTypesIn: _ [ load type == Types Any ifTrue: [load type: load variable type] ifFalse: [load type] ]. Syntax addPrototype: #TypeMismatch derivedFrom: {Warning}. Syntax TypeMismatch addSlot: #source. Syntax TypeMismatch addSlot: #target. tm@(Syntax TypeMismatch traits) from: source to: target causedBy: description [| newTM | newTM: (tm newDescription: description). newTM source: source. newTM target: target. newTM description: description. newTM ]. store@(Syntax StoreVariable traits) inferTypesIn: namespace [ store value inferTypesIn: namespace. (store variable type subsumes: store value type) ifFalse: [(Syntax TypeMismatch from: store value to: store variable causedBy: 'Type mismatch in assignment to local variable: ' ; (store variable name as: String)) signal]. store type == Types Any ifTrue: [store type: store value type] ifFalse: [store type] ]. return@(Syntax Return traits) inferTypesIn: namespace [ return value inferTypesIn: namespace. return type == Types Any ifTrue: [return type: return value type] ifFalse: [return type] ].