-
-
Notifications
You must be signed in to change notification settings - Fork 353
/
CompletionContext.class.st
151 lines (129 loc) · 3.55 KB
/
CompletionContext.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"
I am a context class that hooks the new completion functionality into the system. To do that, i reimplement some of the methods but use most of the old ones from NECompletion package, such as the functionality to call the menu, etc.
"
Class {
#name : #CompletionContext,
#superclass : #Object,
#instVars : [
'source',
'position',
'completionToken',
'ast',
'node',
'class',
'entries',
'sorter',
'engine'
],
#classVars : [
'SorterClass'
],
#category : #'NECompletion-Model'
}
{ #category : #'instance creation' }
CompletionContext class >> engine: aCompletionEngine class: aClass source: aString position: anInteger [
^ self new
engine: aCompletionEngine
class: aClass
source: aString
position: anInteger
]
{ #category : #accessing }
CompletionContext class >> sorterClass [
^ SorterClass
]
{ #category : #accessing }
CompletionContext class >> sorterClass: aSorter [
SorterClass := aSorter
]
{ #category : #entries }
CompletionContext >> activateEntryAt: anIndex [
(self entries at: anIndex) activateOn: self
]
{ #category : #accessing }
CompletionContext >> completionToken [
^ completionToken ifNil: [ ^ '' ]
]
{ #category : #accessing }
CompletionContext >> engine [
^ engine
]
{ #category : #'initialize-release' }
CompletionContext >> engine: aCompletionEngine class: aClass source: aString position: anInteger [
class := aClass.
source := aString.
position := anInteger.
engine := aCompletionEngine.
sorter := self class sorterClass new context: self.
self parseSource.
node := ast nodeForOffset: position.
completionToken := node completionToken: position
]
{ #category : #accessing }
CompletionContext >> entries [
^entries ifNil: [entries := self initEntries ]
]
{ #category : #entries }
CompletionContext >> entryCount [
^ self entries size
]
{ #category : #testing }
CompletionContext >> hasEntries [
^ self entries isEmptyOrNil not
]
{ #category : #testing }
CompletionContext >> hasMessage [
^ self message notNil
]
{ #category : #entries }
CompletionContext >> initEntries [
^ sorter sortCompletionList: (node completionEntries: position) asOrderedCollection
]
{ #category : #parsing }
CompletionContext >> isWorkspace [
^ engine notNil and: [ engine isScripting ]
]
{ #category : #accessing }
CompletionContext >> message [
^self hasEntries
ifFalse: ['no completions found']
ifTrue: [nil]
]
{ #category : #action }
CompletionContext >> narrowWith: aString [
"we need to re-init if the string is shorter as the user types backspace"
(aString size < self completionToken size) ifTrue: [ entries := self initEntries ].
"we narrow the entries down"
entries := self entries select: [ :each | each contents beginsWith: completionToken ].
"and update the completionToken"
completionToken := aString
]
{ #category : #accessing }
CompletionContext >> node [
^ node
]
{ #category : #parsing }
CompletionContext >> parseSource [
ast := class compiler
source: source;
noPattern: self isWorkspace;
options: #(+ optionParseErrors + optionSkipSemanticWarnings);
parse.
ast doSemanticAnalysis.
TypingVisitor new visitNode: ast
]
{ #category : #replacement }
CompletionContext >> replaceTokenInEditorWith: aString [
engine replaceTokenInEditorWith: aString
]
{ #category : #accessing }
CompletionContext >> sorter: anObject [
"this allows tests to change the sorter"
sorter := anObject
]
{ #category : #accessing }
CompletionContext >> title [
"we only give a title if we know the type of the receiver of a message send"
node isMessage ifFalse: [ ^'' ].
^node receiver propertyAt: #type ifPresent: #name ifAbsent: ''
]