1
1
package org .eclipse .dltk .internal .javascript .parser ;
2
2
3
+ import static org .eclipse .dltk .internal .javascript .validation .JavaScriptValidations .reportValidationStatus ;
4
+
3
5
import java .util .ArrayList ;
4
6
import java .util .List ;
5
7
import java .util .StringTokenizer ;
6
8
7
9
import org .eclipse .core .runtime .Assert ;
10
+ import org .eclipse .dltk .annotations .Nullable ;
8
11
import org .eclipse .dltk .compiler .problem .IProblemIdentifier ;
9
12
import org .eclipse .dltk .compiler .problem .IValidationStatus ;
10
13
import org .eclipse .dltk .compiler .problem .ValidationStatus ;
11
14
import org .eclipse .dltk .core .ISourceNode ;
12
15
import org .eclipse .dltk .internal .javascript .ti .IReferenceAttributes ;
13
16
import org .eclipse .dltk .internal .javascript .ti .TypeInferencer2 ;
14
- import org .eclipse .dltk .internal .javascript .validation .JavaScriptValidations ;
15
17
import org .eclipse .dltk .internal .javascript .validation .ValidationMessages ;
16
18
import org .eclipse .dltk .javascript .core .JavaScriptProblems ;
17
19
import org .eclipse .dltk .javascript .parser .JSProblemReporter ;
18
20
import org .eclipse .dltk .javascript .parser .jsdoc .JSDocTag ;
19
21
import org .eclipse .dltk .javascript .typeinference .IValueCollection ;
20
22
import org .eclipse .dltk .javascript .typeinference .IValueReference ;
21
23
import org .eclipse .dltk .javascript .typeinference .ReferenceKind ;
24
+ import org .eclipse .dltk .javascript .typeinfo .ITypeCheck ;
22
25
import org .eclipse .dltk .javascript .typeinfo .ITypeChecker ;
23
26
import org .eclipse .dltk .javascript .typeinfo .ITypeCheckerExtension ;
24
27
import org .eclipse .dltk .javascript .typeinfo .TypeUtil ;
25
28
import org .eclipse .dltk .javascript .typeinfo .model .AnyType ;
26
29
import org .eclipse .dltk .javascript .typeinfo .model .ArrayType ;
27
30
import org .eclipse .dltk .javascript .typeinfo .model .ClassType ;
28
31
import org .eclipse .dltk .javascript .typeinfo .model .FunctionType ;
32
+ import org .eclipse .dltk .javascript .typeinfo .model .GenericType ;
29
33
import org .eclipse .dltk .javascript .typeinfo .model .JSType ;
30
34
import org .eclipse .dltk .javascript .typeinfo .model .MapType ;
31
35
import org .eclipse .dltk .javascript .typeinfo .model .Member ;
@@ -86,26 +90,58 @@ public void checkType(JSType type, ISourceNode tag, int flags) {
86
90
checkType (((MapType ) type ).getValueType (), tag , flags );
87
91
} else if (type instanceof SimpleType ) {
88
92
if (type instanceof ParameterizedType ) {
89
- for ( JSType param : (( ParameterizedType ) type )
90
- .getActualTypeArguments ()) {
93
+ final ParameterizedType parameterized = ( ParameterizedType ) type ;
94
+ for ( JSType param : parameterized .getActualTypeArguments ()) {
91
95
checkType (param , tag , flags );
92
96
}
97
+ checkType (((SimpleType ) type ).getTarget (), tag , flags ,
98
+ new ITypeCheck [] { new ParameterizedTypeCheck (
99
+ parameterized ) });
100
+ } else {
101
+ checkType (((SimpleType ) type ).getTarget (), tag , flags , null );
93
102
}
94
- final Type t = ((SimpleType ) type ).getTarget ();
95
- checkType (t , tag , flags );
96
103
} else if (type instanceof ClassType ) {
97
104
final Type t = ((ClassType ) type ).getTarget ();
98
105
if (t == null ) {
99
106
return ;
100
107
}
101
- checkType (t , tag , flags );
108
+ checkType (t , tag , flags , null );
102
109
}
103
110
}
104
111
105
- public abstract void checkType (Type type , ISourceNode tag , int flags );
112
+ public abstract void checkType (Type type , ISourceNode tag , int flags ,
113
+ @ Nullable ITypeCheck [] checks );
106
114
107
115
}
108
116
117
+ private static class ParameterizedTypeCheck implements ITypeCheck {
118
+ private final ParameterizedType parameterizedType ;
119
+
120
+ public ParameterizedTypeCheck (ParameterizedType parameterizedType ) {
121
+ this .parameterizedType = parameterizedType ;
122
+ }
123
+
124
+ public IValidationStatus checkType (Type type ) {
125
+ if (type instanceof GenericType ) {
126
+ final GenericType genericType = (GenericType ) type ;
127
+ if (genericType .getTypeParameters ().size () != parameterizedType
128
+ .getActualTypeArguments ().size ()) {
129
+ return new ValidationStatus (
130
+ JavaScriptProblems .PARAMETERIZED_TYPE_INCORRECT_ARGUMENTS ,
131
+ NLS .bind (
132
+ ValidationMessages .IncorrectNumberOfTypeArguments ,
133
+ type .getName ()));
134
+ }
135
+ return null ;
136
+ } else {
137
+ return new ValidationStatus (
138
+ JavaScriptProblems .NOT_GENERIC_TYPE , NLS .bind (
139
+ ValidationMessages .NotGenericType ,
140
+ type .getName ()));
141
+ }
142
+ }
143
+ }
144
+
109
145
public static class TypeChecker extends AbstractTypeChecker implements
110
146
ITypeCheckerExtension {
111
147
@@ -125,17 +161,12 @@ public void checkType(JSType type, ISourceNode tag, int flags) {
125
161
if (extension instanceof IValidatorExtension2 ) {
126
162
final IValidationStatus status = ((IValidatorExtension2 ) extension )
127
163
.validateTypeExpression (type );
128
- if (status != null ) {
129
- if (status == ValidationStatus .OK ) {
130
- break ;
131
- } else {
132
- JavaScriptValidations .reportValidationStatus (
133
- reporter , status , tag ,
134
- JavaScriptProblems .INACCESSIBLE_TYPE ,
135
- ValidationMessages .InaccessibleType ,
136
- type .getName ());
137
- return ;
138
- }
164
+ if (status != null && status != ValidationStatus .OK ) {
165
+ reportValidationStatus (reporter , status , tag ,
166
+ JavaScriptProblems .INACCESSIBLE_TYPE ,
167
+ ValidationMessages .InaccessibleType ,
168
+ type .getName ());
169
+ return ;
139
170
}
140
171
}
141
172
}
@@ -144,25 +175,29 @@ public void checkType(JSType type, ISourceNode tag, int flags) {
144
175
}
145
176
146
177
@ Override
147
- public void checkType (Type type , ISourceNode tag , int flags ) {
178
+ public void checkType (Type type , ISourceNode tag , int flags ,
179
+ @ Nullable ITypeCheck [] checks ) {
148
180
if (type .getKind () == TypeKind .UNKNOWN
149
181
|| type .getKind () == TypeKind .UNRESOLVED ) {
150
182
queue .add (new QueueItem (type , tag , context .currentCollection (),
151
- flags ));
183
+ flags , checks ));
152
184
} else {
153
185
checkDeprecatedType (type , tag );
186
+ if (checks != null ) {
187
+ doChecks (type , tag , checks );
188
+ }
154
189
}
155
190
}
156
191
157
192
public void validate () {
158
193
for (QueueItem item : queue ) {
159
- checkType ( item . tag , context .resolveType (item .type ),
160
- item .collection , item .flags );
194
+ doCheckType ( context .resolveType (item .type ), item . tag ,
195
+ item .flags , item .checks , item . collection );
161
196
}
162
197
}
163
198
164
- protected void checkType ( ISourceNode tag , Type type ,
165
- IValueCollection collection , int flags ) {
199
+ private void doCheckType ( Type type , ISourceNode tag , int flags ,
200
+ @ Nullable ITypeCheck [] checks , IValueCollection collection ) {
166
201
if (type .eIsProxy ()) {
167
202
Assert .isTrue (!type .eIsProxy (), "Type \" " + type .getName ()
168
203
+ "\" is a proxy" );
@@ -205,6 +240,20 @@ protected void checkType(ISourceNode tag, Type type,
205
240
reportUnknownType (tag , TypeUtil .getName (type ));
206
241
} else {
207
242
checkDeprecatedType (type , tag );
243
+ if (checks != null ) {
244
+ doChecks (type , tag , checks );
245
+ }
246
+ }
247
+ }
248
+
249
+ private void doChecks (Type type , ISourceNode tag , ITypeCheck [] checks ) {
250
+ for (ITypeCheck check : checks ) {
251
+ final IValidationStatus status = check .checkType (type );
252
+ if (status != null && status != ValidationStatus .OK ) {
253
+ reportValidationStatus (reporter , status , tag ,
254
+ JavaScriptProblems .INACCESSIBLE_TYPE ,
255
+ ValidationMessages .InaccessibleType , type .getName ());
256
+ }
208
257
}
209
258
}
210
259
@@ -214,22 +263,18 @@ private void checkDeprecatedType(Type type, ISourceNode tag) {
214
263
JavaScriptProblems .DEPRECATED_TYPE ,
215
264
NLS .bind (ValidationMessages .DeprecatedType ,
216
265
TypeUtil .getName (type )), tag .start (), tag .end ());
266
+ return ;
217
267
} else if (extensions != null ) {
218
268
for (IValidatorExtension extension : extensions ) {
219
269
if (extension instanceof IValidatorExtension2 ) {
220
270
final IValidationStatus status = ((IValidatorExtension2 ) extension )
221
271
.validateAccessibility (type );
222
- if (status != null ) {
223
- if (status == ValidationStatus .OK ) {
224
- return ;
225
- } else {
226
- JavaScriptValidations .reportValidationStatus (
227
- reporter , status , tag ,
228
- JavaScriptProblems .INACCESSIBLE_TYPE ,
229
- ValidationMessages .InaccessibleType ,
230
- type .getName ());
231
- return ;
232
- }
272
+ if (status != null && status != ValidationStatus .OK ) {
273
+ reportValidationStatus (reporter , status , tag ,
274
+ JavaScriptProblems .INACCESSIBLE_TYPE ,
275
+ ValidationMessages .InaccessibleType ,
276
+ type .getName ());
277
+ return ;
233
278
}
234
279
}
235
280
}
@@ -277,13 +322,17 @@ private static class QueueItem {
277
322
final ISourceNode tag ;
278
323
final IValueCollection collection ;
279
324
final int flags ;
325
+ @ Nullable
326
+ final ITypeCheck [] checks ;
280
327
281
328
public QueueItem (Type type , ISourceNode tag ,
282
- IValueCollection collection , int flags ) {
329
+ IValueCollection collection , int flags ,
330
+ @ Nullable ITypeCheck [] checks ) {
283
331
this .type = type ;
284
332
this .tag = tag ;
285
333
this .collection = collection ;
286
334
this .flags = flags ;
335
+ this .checks = checks ;
287
336
}
288
337
289
338
}
0 commit comments