With type inference, the data type of an expression can be deduced, which allows providing meaningful autocompleter suggestions or documentation for a class or method.
The type inference strategies below take only the global scope into account (e.g. like when evaluating a simple line on the console). For longer console input or complete ruby files, one would have to consider nested scopes and visibility of variables by building an abstract syntax tree out of the complete code.
first identifier → token → next token → …
Tries to find the object corresponding to the first identifier, then evaluates subsequent tokens using introspection where possible.
- TokenClassificationByObject:
- We have a reference to the exact object in ObjectSpace.
- TokenClassificationByClass:
- We know the class in ObjectSpace, but we don't have an instance of it.
- TokenClassificationByDoc:
- Fallback to documentation to know what type a method returns (since Ruby is not statically typed, introspection cannot provide the return types). We use statically generated documentation from yardoc. However documentation may sometimes be incomplete and miss return type information.
model = Sketchup.active_model
model.selection
-
Search
model
in ObjectSpace
TokenClassificationByObject(model, is_instance=true)
-
Search an identifier
selection
inSketchup::Model
→ We find a method, but don't know its return type.
TokenClassificationByDoc("Sketchup::Model#selection", is_instance=true)
-
Search
Sketchup::Model#selection
in yardoc documentation → It returns anSketchup::Selection
, but we don't have a reference to the exact instance.
TokenClassificationByClass(Sketchup::Selection, is_instance=true)
This approach tries to guess the most likely type starting from the last token. Since a token can be member of multiple classes or objects this results in a tree of possibilities, but it can be narrowed down by matches for the previous tokens.
… → previous token → last token
- Last token
↓ - Which types (previous token) respond to that token?
↓ - Which of these types can be returned by previous previous token?
Usually already with two tokens, the possibilities can be reduced to one.
unknown_reference.entities.length.to_s
-
Find classes that have a method
to_s
.
Array#to_s
,Fixnum#to_s
,Float#to_s
,Hash#to_s
,NilClass#to_s
… -
Then find classes that have a method
length
which returns an instance of the former classes.
Array#length
,Hash#length
,Sketchup::Entities#length
, … -
Then find classes that have a method
entities
and return aSketchup::Entities
(orArray
orHash
).
Sketchup::Model#entities
,Sketchup::Model#active_entities
,Sketchup::ComponentDefinition#entities
,Sketchup::Group#entities