@@ -267,60 +267,74 @@ protected SourceUnit getSourceUnit() {
267
267
return source ;
268
268
}
269
269
270
+ @ Override
271
+ public void visitField (final FieldNode node ) {
272
+ Map <GenericsTypeName , GenericsType > oldNames = genericParameterNames ;
273
+ if (!canSeeTypeVars (node .getModifiers (), node .getDeclaringClass ())) {
274
+ genericParameterNames = Collections .emptyMap ();
275
+ }
276
+
277
+ if (!fieldTypesChecked .contains (node )) {
278
+ resolveOrFail (node .getType (), node );
279
+ }
280
+ super .visitField (node );
281
+
282
+ genericParameterNames = oldNames ;
283
+ }
284
+
285
+ @ Override
286
+ public void visitProperty (final PropertyNode node ) {
287
+ Map <GenericsTypeName , GenericsType > oldNames = genericParameterNames ;
288
+ if (!canSeeTypeVars (node .getModifiers (), node .getDeclaringClass ())) {
289
+ genericParameterNames = Collections .emptyMap ();
290
+ }
291
+
292
+ resolveOrFail (node .getType (), node );
293
+ fieldTypesChecked .add (node .getField ());
294
+
295
+ super .visitProperty (node );
296
+
297
+ genericParameterNames = oldNames ;
298
+ }
299
+
300
+ private static boolean canSeeTypeVars (final int mods , final ClassNode node ) {
301
+ return !Modifier .isStatic (mods ) || Traits .isTrait (node ); // GROOVY-8864, GROOVY-11508
302
+ }
303
+
270
304
@ Override
271
305
protected void visitConstructorOrMethod (final MethodNode node , final boolean isConstructor ) {
272
306
VariableScope oldScope = currentScope ;
273
307
currentScope = node .getVariableScope ();
274
308
Map <GenericsTypeName , GenericsType > oldNames = genericParameterNames ;
275
- genericParameterNames = node .isStatic () && !Traits .isTrait (node .getDeclaringClass ())
276
- ? new HashMap <>() : new HashMap <>(genericParameterNames );
309
+ genericParameterNames =
310
+ canSeeTypeVars (node .getModifiers (), node .getDeclaringClass ())
311
+ ? new HashMap <>(genericParameterNames ) : new HashMap <>();
277
312
278
313
resolveGenericsHeader (node .getGenericsTypes ());
279
314
315
+ resolveOrFail (node .getReturnType (), node );
280
316
for (Parameter p : node .getParameters ()) {
281
317
p .setInitialExpression (transform (p .getInitialExpression ()));
282
- resolveOrFail (p .getType (), p .getType ());
318
+ ClassNode t = p .getType ();
319
+ resolveOrFail (t , t );
283
320
visitAnnotations (p );
284
321
}
285
- ClassNode [] exceptions = node .getExceptions ();
286
- for (ClassNode t : exceptions ) {
287
- resolveOrFail (t , node );
322
+ if (node .getExceptions () != null ) {
323
+ for (ClassNode t : node .getExceptions ()) {
324
+ resolveOrFail (t , t );
325
+ }
288
326
}
289
- resolveOrFail (node .getReturnType (), node );
290
327
291
328
MethodNode oldCurrentMethod = currentMethod ;
292
329
currentMethod = node ;
330
+
293
331
super .visitConstructorOrMethod (node , isConstructor );
294
332
295
333
currentMethod = oldCurrentMethod ;
296
334
genericParameterNames = oldNames ;
297
335
currentScope = oldScope ;
298
336
}
299
337
300
- @ Override
301
- public void visitField (final FieldNode node ) {
302
- ClassNode t = node .getType ();
303
- if (!fieldTypesChecked .contains (node )) {
304
- resolveOrFail (t , node );
305
- }
306
- super .visitField (node );
307
- }
308
-
309
- @ Override
310
- public void visitProperty (final PropertyNode node ) {
311
- Map <GenericsTypeName , GenericsType > oldPNames = genericParameterNames ;
312
- if (node .isStatic () && !Traits .isTrait (node .getDeclaringClass ())) {
313
- genericParameterNames = new HashMap <>();
314
- }
315
-
316
- ClassNode t = node .getType ();
317
- resolveOrFail (t , node );
318
- super .visitProperty (node );
319
- fieldTypesChecked .add (node .getField ());
320
-
321
- genericParameterNames = oldPNames ;
322
- }
323
-
324
338
private void resolveOrFail (final ClassNode type , final ASTNode node ) {
325
339
resolveOrFail (type , "" , node );
326
340
}
@@ -731,7 +745,7 @@ private boolean resolveAliasFromModule(final ClassNode type) {
731
745
if (importNode != null && importNode != currImportNode ) {
732
746
// static alias only for inner classes and must be at end of chain
733
747
ClassNode tmp = new ConstructedNestedClass (importNode .getType (), importNode .getFieldName ());
734
- if (resolve (tmp , false , false , true ) && (tmp .getModifiers () & Opcodes . ACC_STATIC ) != 0 ) {
748
+ if (resolve (tmp , false , false , true ) && Modifier . isStatic (tmp .getModifiers ()) ) {
735
749
type .setRedirect (tmp .redirect ());
736
750
return true ;
737
751
}
@@ -752,7 +766,7 @@ private boolean resolveAliasFromModule(final ClassNode type) {
752
766
// At this point we know that we have a match for pname. This may
753
767
// mean, that name[pname.length()..<-1] is a static inner class.
754
768
// For this the rest of the name does not need any dots in its name.
755
- // It is either completely a inner static class or it is not.
769
+ // It is either completely an inner static class or it is not.
756
770
// Since we do not want to have useless lookups we create the name
757
771
// completely and use a ConstructedClassWithPackage to prevent lookups against the package.
758
772
String className = aliasedNode .getNameWithoutPackage () + "$" + name .substring (pname .length () + 1 ).replace ('.' , '$' );
@@ -813,7 +827,7 @@ protected boolean resolveFromModule(final ClassNode type, final boolean testModu
813
827
// check package this class is defined in. The usage of ConstructedClassWithPackage here
814
828
// means, that the module package will not be involved when the
815
829
// compiler tries to find an inner class.
816
- ClassNode tmp = new ConstructedClassWithPackage (module .getPackageName (), name );
830
+ ClassNode tmp = new ConstructedClassWithPackage (module .getPackageName (), name );
817
831
if (resolve (tmp , false , false , false )) {
818
832
ambiguousClass (type , tmp , name );
819
833
return true ;
@@ -823,15 +837,15 @@ protected boolean resolveFromModule(final ClassNode type, final boolean testModu
823
837
for (ImportNode importNode : module .getStaticImports ().values ()) {
824
838
if (importNode .getFieldName ().equals (name )) {
825
839
ClassNode tmp = new ConstructedNestedClass (importNode .getType (), name );
826
- if (resolve (tmp , false , false , true ) && (tmp .getModifiers () & Opcodes . ACC_STATIC ) != 0 ) {
840
+ if (resolve (tmp , false , false , true ) && Modifier . isStatic (tmp .getModifiers ()) ) {
827
841
type .setRedirect (tmp .redirect ());
828
842
return true ;
829
843
}
830
844
}
831
845
}
832
846
for (ImportNode importNode : module .getStaticStarImports ().values ()) {
833
847
ClassNode tmp = new ConstructedNestedClass (importNode .getType (), name );
834
- if (resolve (tmp , false , false , true ) && (tmp .getModifiers () & Opcodes . ACC_STATIC ) != 0 ) {
848
+ if (resolve (tmp , false , false , true ) && Modifier . isStatic (tmp .getModifiers ()) ) {
835
849
ambiguousClass (type , tmp , name );
836
850
return true ;
837
851
}
@@ -840,7 +854,7 @@ protected boolean resolveFromModule(final ClassNode type, final boolean testModu
840
854
for (ImportNode importNode : module .getStarImports ()) {
841
855
if (importNode .getType () != null ) {
842
856
ClassNode tmp = new ConstructedNestedClass (importNode .getType (), name );
843
- if (resolve (tmp , false , false , true ) && (tmp .getModifiers () & Opcodes . ACC_STATIC ) != 0 ) {
857
+ if (resolve (tmp , false , false , true ) && Modifier . isStatic (tmp .getModifiers ()) ) {
844
858
ambiguousClass (type , tmp , name );
845
859
return true ;
846
860
}
@@ -862,7 +876,7 @@ protected boolean resolveToOuter(final ClassNode type) {
862
876
863
877
// We do not need to check instances of LowerCaseClass
864
878
// to be a Class, because unless there was an import for
865
- // for this we do not lookup these cases. This was a decision
879
+ // this we do not look up these cases. This was a decision
866
880
// made on the mailing list. To ensure we will not visit this
867
881
// method again we set a NO_CLASS for this name
868
882
if (type instanceof LowerCaseClass ) {
@@ -951,7 +965,7 @@ private static String lookupClassName(final PropertyExpression pe) {
951
965
doInitialClassTest = classNameInfo .getV2 ();
952
966
}
953
967
954
- if (null == name || name .length () == 0 ) return null ;
968
+ if (name == null || name .length () == 0 ) return null ;
955
969
956
970
return name .toString ();
957
971
}
@@ -1089,7 +1103,7 @@ private void checkThisAndSuperAsPropertyAccess(final PropertyExpression expressi
1089
1103
addError ("The class '" + type .getName () + "' needs to be an outer class of '" +
1090
1104
currentClass .getName () + "' when using '.this' or '.super'." , expression );
1091
1105
}
1092
- if ((currentClass .getModifiers () & Opcodes . ACC_STATIC ) == 0 ) return ;
1106
+ if (! Modifier . isStatic (currentClass .getModifiers ()) ) return ;
1093
1107
if (currentScope != null && !currentScope .isInStaticContext ()) return ;
1094
1108
addError ("The usage of 'Class.this' and 'Class.super' within static nested class '" +
1095
1109
currentClass .getName () + "' is not allowed in a static context." , expression );
@@ -1100,13 +1114,6 @@ protected Expression transformVariableExpression(final VariableExpression ve) {
1100
1114
visitAnnotations (ve );
1101
1115
Variable v = ve .getAccessedVariable ();
1102
1116
1103
- if (!(v instanceof DynamicVariable ) && !checkingVariableTypeInDeclaration ) {
1104
- /*
1105
- * GROOVY-4009: when a normal variable is simply being used, there is no need to try to
1106
- * resolve its type. Variable type resolve should proceed only if the variable is being declared.
1107
- */
1108
- return ve ;
1109
- }
1110
1117
if (v instanceof DynamicVariable ) {
1111
1118
String name = ve .getName ();
1112
1119
ClassNode t = ClassHelper .make (name );
@@ -1132,8 +1139,14 @@ protected Expression transformVariableExpression(final VariableExpression ve) {
1132
1139
for (VariableScope scope = currentScope ; scope != null && !scope .isRoot (); scope = scope .getParent ()) {
1133
1140
if (scope .removeReferencedClassVariable (ve .getName ()) == null ) break ;
1134
1141
}
1135
- return new ClassExpression (t );
1142
+ ClassExpression ce = new ClassExpression (t );
1143
+ ce .setSourcePosition (ve );
1144
+ return ce ;
1136
1145
}
1146
+ } else if (!checkingVariableTypeInDeclaration ) {
1147
+ // GROOVY-4009: When a normal variable is simply being used, there is no need to try to
1148
+ // resolve its type. Variable type resolve should proceed only if the variable is being declared.
1149
+ return ve ;
1137
1150
}
1138
1151
resolveOrFail (ve .getType (), ve );
1139
1152
ClassNode origin = ve .getOriginType ();
@@ -1206,14 +1219,14 @@ protected Expression transformBinaryExpression(final BinaryExpression be) {
1206
1219
protected Expression transformClosureExpression (final ClosureExpression ce ) {
1207
1220
boolean oldInClosure = inClosure ;
1208
1221
inClosure = true ;
1209
- for (Parameter para : getParametersSafe (ce )) {
1210
- ClassNode t = para .getType ();
1211
- resolveOrFail (t , ce );
1212
- visitAnnotations (para );
1213
- if (para .hasInitialExpression ()) {
1214
- para .setInitialExpression (transform (para .getInitialExpression ()));
1215
- }
1216
- visitAnnotations (para );
1222
+ for (Parameter p : getParametersSafe (ce )) {
1223
+ ClassNode t = p .getType ();
1224
+ resolveOrFail (t , t );
1225
+ visitAnnotations (p );
1226
+ if (p .hasInitialExpression ()) {
1227
+ p .setInitialExpression (transform (p .getInitialExpression ()));
1228
+ }
1229
+ visitAnnotations (p );
1217
1230
}
1218
1231
1219
1232
Statement code = ce .getCode ();
0 commit comments