Skip to main content
summaryrefslogtreecommitdiffstats
blob: 0ee91cdd5f05e8375d1bc54e0f57d44f40fc0b43 (plain) (blame)
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2004, 2018 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 *
 * Contributors:
 * Fraunhofer FIRST - Initial API and implementation
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.internal.core.compiler.util;

import static org.eclipse.objectteams.otdt.core.compiler.ISMAPConstants.STEP_OVER_LINENUMBER;

import java.util.Arrays;
import java.util.List;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.CompilationResult.CheckPoint;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.ast.Expression.DecapsulationState;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.LiftingTypeReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.PotentialLiftExpression;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.QualifiedBaseReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.ResultReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TSuperMessageSend;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TsuperReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeAnchorReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.TThisBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;

/**
 * This factory creates "generated" elements, ie., elements that have
 * no direct connection to source code. Most functions are just simple factory
 * methods which however set source positions.
 *
 * @author stephan
 */
public class AstGenerator extends AstFactory {

	static final int AccIfcMethod = AccAbstract|AccSemicolonBody;
	public long sourceLevel = ClassFileConstants.JDK1_5;

	/** 
	 * If set to non-null, base anchored types matching this anchor are not encoded using the base field 
	 * (possibly with static prefix),
	 * but a simple name "base" is used, representing the base argument in a callin wrapper.
	 */
	public ITeamAnchor replaceableBaseAnchor = null;
	
	/**
	 * If this reference is non-null, qualifications in qualified this references that refer
	 * to <code>replaceableEnclosingClass</code>'s super class should be updated to 
	 * <code>replaceableEnclosingClass</code> itself (strengthening during copy).
	 */
	public ReferenceBinding replaceableEnclosingClass;
	
	public AstGenerator(int start, int end) {
		super(start, end);
	}

	public AstGenerator(long sourceLevel, int start, int end) {
		super(start, end);
		this.sourceLevel = sourceLevel;
	}

	public AstGenerator(long pos) {
		super((int)(pos>>>32), (int)pos);
	}

	public AstGenerator(ASTNode node) {
		super(0,0);
		retargetFrom(node);
	}

	public void setPositions(Expression expression) {
		expression.sourceStart = this.sourceStart;
		expression.sourceEnd   = this.sourceEnd;
	}

	public LocalDeclaration localVariable (char[] name, char[] type, Expression init) {
		return localVariable(name, new SingleTypeReference(type, this.pos), init);
	}

	public LocalDeclaration localVariable (char[] name, TypeBinding type, Expression init) {
		TypeReference typeReference = typeReference(type);
		typeReference.sourceStart = this.sourceStart;
		typeReference.sourceEnd   = this.sourceEnd;

		return localVariable(name, typeReference, init);
	}

	public LocalDeclaration localBaseVariable (char[] name, TypeBinding type, Expression init) {
		TypeReference typeReference = baseclassReference(type);
		typeReference.sourceStart = this.sourceStart;
		typeReference.sourceEnd   = this.sourceEnd;

		return localVariable(name, typeReference, init);
	}

	public LocalDeclaration localVariable(char[] name, TypeReference typeReference, Expression init) {
		LocalDeclaration variable = new LocalDeclaration(name, this.sourceStart, this.sourceEnd);
		variable.initialization = init;
		variable.declarationSourceStart = this.sourceStart;
		variable.declarationSourceEnd   = this.sourceEnd;
		variable.type = typeReference;
		variable.isGenerated = true;
		return variable;
	}

	public LocalDeclaration localVariable(char[] name, TypeReference typeReference, int modifiers, Expression init) {
		LocalDeclaration variable = new LocalDeclaration(name, this.sourceStart, this.sourceEnd);
		variable.initialization = init;
		variable.declarationSourceStart = this.sourceStart;
		variable.declarationSourceEnd   = this.sourceEnd;
		variable.type = typeReference;
		variable.modifiers = modifiers;
		variable.isGenerated = true;
		return variable;
	}

	public SingleNameReference singleNameReference(char[] name) {
		SingleNameReference ref = new SingleNameReference(name, this.pos);
		ref.isGenerated = true;
		return ref;
	}
	public QualifiedNameReference qualifiedNameReference(char[][] tokens) {
		long[] poss = new long[tokens.length];
		Arrays.fill(poss, this.pos);
		return new QualifiedNameReference(tokens, poss, this.sourceStart, this.sourceEnd);
	}
	public QualifiedNameReference qualifiedBaseNameReference(char[][] tokens) {
		QualifiedNameReference ref = qualifiedNameReference(tokens);
		ref.baseclassDecapsulation = DecapsulationState.REPORTED;
		return ref;
	}
	public QualifiedNameReference qualifiedNameReference(ReferenceBinding type) {
		char[][] tokens = CharOperation.splitOn('.', type.readableName());
		return qualifiedNameReference(tokens);
	}
	/**
	 * Qualified reference to a static field.
	 * @param field a static field
	 * @return a resolved qualified reference to the given field.
	 */
	public QualifiedNameReference qualifiedNameReference(FieldBinding field) {
		char[][] className = TypeAnalyzer.compoundNameOfReferenceType(field.declaringClass, true, false);
		int len = className.length;
		char[][] qualifiedName = new char[len+1][];
		System.arraycopy(className, 0, qualifiedName, 0, len);
		qualifiedName[len] = field.name;
		QualifiedNameReference qualifiedNameReference = qualifiedNameReference(qualifiedName);
		qualifiedNameReference.binding = field;
		qualifiedNameReference.actualReceiverType = field.declaringClass;
		qualifiedNameReference.resolvedType = field.type;
		qualifiedNameReference.bits &= ~ASTNode.RestrictiveFlagMASK;
		qualifiedNameReference.bits |= Binding.FIELD;
		qualifiedNameReference.constant = Constant.NotAConstant;
		return qualifiedNameReference;
	}
	public NameReference nameReference (ReferenceBinding type) {
	    char[] typeName = "void".toCharArray(); //$NON-NLS-1$
	    char [][] qname = TypeAnalyzer.compoundNameOfReferenceType(type, true, true);
	    char[] sname;
	    if ((qname != null) && (qname.length==1)) {
	        sname = qname[0]; // use this
	        qname = null;     // not this
	    } else {
	        sname = typeName;
	    }

	    NameReference nr = null;
	    if (qname == null)
	        nr = singleNameReference(sname);
	    else {
	        long[] poss = new long[qname.length];
	        Arrays.fill(poss, 0);
	        nr = qualifiedNameReference(qname);
	    }
	    return nr;
	}
	public SingleNameReference baseNameReference(char[] name) {
		SingleNameReference result = singleNameReference(name);
		result.baseclassDecapsulation = DecapsulationState.REPORTED;
		return result;
	}
	public NameReference baseNameReference(ReferenceBinding type) {
		NameReference result = nameReference(type);
		result.baseclassDecapsulation = DecapsulationState.REPORTED;
		return result;
	}
	public TypeReference baseTypeReference(char[] name) {
		SingleTypeReference result = singleTypeReference(name);
		result.setBaseclassDecapsulation(DecapsulationState.REPORTED);
		return result;
	}

	public TypeReference baseTypeReference(ReferenceBinding type) {
		TypeReference result = typeReference(type);
		result.setBaseclassDecapsulation(DecapsulationState.REPORTED);
		return result;
	}

	public Expression thislikeNameReference(char[] name) {
		SingleNameReference result = singleNameReference(name);
		result.isThisLike = true;
		return result;
	}

	public ResultReference resultReference(
    		SingleNameReference ref, AbstractMethodMappingDeclaration mapping)
    {
    	return new ResultReference(ref, mapping);
    }

	public FieldReference fieldReference (Expression receiver, char[] name) {
		return fieldReference(receiver, name, DecapsulationState.NONE);
	}

	public FieldReference fieldReference (Expression receiver, char[] name, DecapsulationState baseDecapsulation) {
		FieldReference field = new FieldReference(name, this.pos);
		field.receiver = receiver;
		if (baseDecapsulation != DecapsulationState.NONE)
			field.setBaseclassDecapsulation(baseDecapsulation);
		return field;
	}

	/**
	 * Create a field reference from its elements.
	 * Perform necessary internal initializations without calling resolveType()
	 * @param receiver what's left of the dot
	 * @param field binding of the field being referenced
	 */
	public FieldReference resolvedFieldReference(
	        Expression   receiver,
	        FieldBinding field)
	{
	    FieldReference fieldRef = new FieldReference(field.name, (((long)this.sourceStart)<<32) + this.sourceEnd);
	    fieldRef.receiver = receiver;
	    fieldRef.actualReceiverType = receiver.resolvedType;
	    fieldRef.resolvedType = field.type;
	    fieldRef.binding = field; // codegenBinding will be set from analyseCode->manageSyntheticAccessIfNecessary
	    fieldRef.constant = Constant.NotAConstant;
	    return fieldRef;
	}

	public SingleTypeReference singleTypeReference(TypeBinding type) {
		return new SingleTypeReference(type.sourceName(), this.pos);
	}

	public SingleTypeReference singleTypeReference(char[] name) {
		return new SingleTypeReference(name, this.pos);
	}

	public ArrayTypeReference arrayTypeReference(char[] name, int dims) {
		return new ArrayTypeReference(name, dims, this.pos);
	}

	public NullLiteral nullLiteral() {
		NullLiteral result = new NullLiteral(this.sourceStart, this.sourceEnd);
		result.constant = Constant.NotAConstant;
		return result;
	}
	public Expression nullCheck(Expression value) {
		return internalNullCheck(value, OperatorIds.EQUAL_EQUAL);
	}
	public Expression nonNullCheck(Expression value) {
		return internalNullCheck(value, OperatorIds.NOT_EQUAL);
	}
	Expression internalNullCheck(Expression value, int operator) {
		EqualExpression result = new EqualExpression(
				value,
				nullLiteral(),
				operator) {
			protected void checkVariableComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse, LocalVariableBinding local, int nullStatus, Expression reference) {
				// similar to super version: do mark flowInfo but avoid reporting any problems
				switch (nullStatus) {
					case FlowInfo.NULL :
						if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
							initsWhenTrue.markAsComparedEqualToNull(local); // from thereon it is set
							initsWhenFalse.markAsComparedEqualToNonNull(local); // from thereon it is set
						} else {
							initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
							initsWhenFalse.markAsComparedEqualToNull(local); // from thereon it is set
						}
						break;
					case FlowInfo.NON_NULL :
						if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
							initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
						}
						break;
				}
			}
		};
		result.sourceStart = this.sourceStart;
		result.sourceEnd = this.sourceEnd;
		result.constant = Constant.NotAConstant;
		result.isGenerated = true;
		return result;
	}
	public IntLiteral intLiteral(int val) {
		IntLiteral result = IntLiteral.buildIntLiteral(String.valueOf(val).toCharArray(), this.sourceStart, this.sourceEnd);
		return result;
	}
	public TeamModel.UpdatableIntLiteral updatableIntLiteral(int val) {
		return new TeamModel.UpdatableIntLiteral(val, this.sourceStart, this.sourceEnd);
	}
	public Literal booleanLiteral(boolean val) {
		MagicLiteral result = val
			? new TrueLiteral(this.sourceStart, this.sourceEnd)
			: new FalseLiteral(this.sourceStart, this.sourceEnd);
		result.isGenerated = true;
		return result;
	}
	public StringLiteral stringLiteral(char[] cs) {
		return new StringLiteral(cs, this.sourceStart, this.sourceEnd, /*lineNumber*/0);
	}
	/** Create a verbatim class literal access (no need to replace by _OT$getClass$R()).*/
	public Expression classLiteralAccess(TypeReference reference) {
		return new ClassLiteralAccess(this.sourceEnd, reference, true);
	}

	/**
	 * Note: only use this if you are positively sure that compoundName contains no '$'!
	 */
	public QualifiedTypeReference qualifiedTypeReference(char[][] compoundName) {
		long[] poss = new long[compoundName.length];
		Arrays.fill(poss, this.pos);
		QualifiedTypeReference reference = new QualifiedTypeReference(compoundName, poss);
		reference.bits |= ASTNode.IgnoreRawTypeCheck;
		reference.isGenerated = true;
		return reference;
	}

	public QualifiedTypeReference qualifiedArrayTypeReference(char[][] compoundName, int dims) {
		long[] poss = new long[compoundName.length];
		Arrays.fill(poss, this.pos);
		ArrayQualifiedTypeReference reference = new ArrayQualifiedTypeReference(compoundName, dims, poss);
		reference.bits |= ASTNode.IgnoreRawTypeCheck;
		reference.isGenerated = true;
		return reference;
	}

	public SingleTypeReference parameterizedSingleTypeReference(char[] name, TypeReference[] typeParameters, int dimensions)
	{
		if (this.sourceLevel < ClassFileConstants.JDK1_5)
			return singleTypeReference(name);
		return new ParameterizedSingleTypeReference(name, typeParameters, 0, this.pos);
	}

	public QualifiedTypeReference parameterizedQualifiedTypeReference(
				char[][] compoundName,
				TypeReference[] lastTypeParameters)
	{
		TypeReference[][] typeParameters = new TypeReference[compoundName.length][];
		typeParameters[compoundName.length-1] = lastTypeParameters;
		return parameterizedQualifiedTypeReference(compoundName, typeParameters, 0);
	}
	public QualifiedTypeReference parameterizedQualifiedTypeReference(
				char[][] compoundName,
				TypeReference[][] typeParameters, int dims)
	{
		if (this.sourceLevel < ClassFileConstants.JDK1_5)
			return qualifiedTypeReference(compoundName);
		long[] poss = new long[compoundName.length];
		Arrays.fill(poss, this.pos);
		return new ParameterizedQualifiedTypeReference(compoundName, typeParameters, dims, poss);
	}

	/**
	 * This method is only used for non-role types (incl. type parameters).
	 * @param compoundName		  name of the main type
	 * @param lastTypeParameters  bindings representing type parameters
	 * @return a parameterized qualified type reference
	 */
	public QualifiedTypeReference parameterizedQualifiedTypeReference(
				char[][] compoundName,
				TypeBinding[] lastTypeParameters)
	{
		TypeReference[] parameterRefs = new TypeReference[lastTypeParameters.length];
		for(int i = 0; i < lastTypeParameters.length; i++) {
			parameterRefs[i] = typeReference(lastTypeParameters[i], true/*generic*/);
		}
		return parameterizedQualifiedTypeReference(compoundName, parameterRefs);
	}

	public TypeReference typeReference(TypeBinding type) {
		return typeReference(type, true);
	}
	public TypeReference typeReference(TypeBinding type, boolean makeGeneric) {
        int dims = 0;
        TypeBinding elementType = type;

        if (type instanceof ArrayBinding) {
            ArrayBinding ab = (ArrayBinding)type;
            dims = ab.dimensions;
            elementType = ab.leafComponentType;
        }
        TypeReference typeReference = createArrayTypeReference(elementType, dims, makeGeneric);
        typeReference.bits |= ASTNode.IgnoreRawTypeCheck;
        typeReference.isGenerated = true;
        typeReference.deprecationProblemId = 0;
        if (!type.isValidBinding())
        	typeReference.bits |= ASTNode.IsGeneratedWithProblem;
		return typeReference;
	}
	public TypeReference baseclassReference(TypeBinding type) {
		return baseclassReference(type, false);
	}
	public TypeReference baseclassReference(TypeBinding type, boolean erase) {
		erase &= type.isParameterizedType();
		if (erase)
			type = type.erasure();
		TypeReference result = typeReference(type);
		result.setBaseclassDecapsulation(DecapsulationState.REPORTED);
		TypeReference[] parameters = null;
		if (result instanceof ParameterizedSingleTypeReference)
			parameters = ((ParameterizedSingleTypeReference)result).typeArguments;
		else if (result instanceof ParameterizedQualifiedTypeReference) {
			TypeReference[][] allParams = ((ParameterizedQualifiedTypeReference)result).typeArguments;
			if (allParams != null)
				parameters = allParams[allParams.length-1]; // TODO for now only treat the last set of params
		}
		if (parameters != null)
			for (TypeReference parameter : parameters)
				parameter.setBaseclassDecapsulation(DecapsulationState.REPORTED);

		if (erase)
			result.bits |= ASTNode.IgnoreRawTypeCheck;
		return result;
	}
	public ParameterizedSingleTypeReference roleTypeReference(ITeamAnchor baseSideAnchor, ReferenceBinding roleType, int dims)
	{

		TypeAnchorReference anchorRef = typeAnchorReference(baseSideAnchor);
		TypeReference[] typeParameters;
		TypeBinding[] typeArguments = roleType.isParameterizedType() ? ((ParameterizedTypeBinding) roleType).arguments : null;
		if (typeArguments != null) {
			typeParameters = new TypeReference[typeArguments.length+1];
			typeParameters[0] = anchorRef;
			for (int i = 0; i < typeArguments.length; i++)
				typeParameters[i+1] = typeReference(typeArguments[i]);
		} else {
			typeParameters = new TypeReference[] { anchorRef };
		}
		ParameterizedSingleTypeReference result = new ParameterizedSingleTypeReference(
				roleType.internalName(),
				typeParameters,
				dims,
				this.pos);
		return result;
	}

    public TypeReference createArrayTypeReference(
            TypeBinding elementType,
            int dims)
    {
    	TypeReference typeReference = createArrayTypeReference(elementType, dims, true);
    	typeReference.deprecationProblemId = 0;
    	typeReference.bits |= ASTNode.IgnoreRawTypeCheck;
    	typeReference.isGenerated = true;
		return typeReference;
    }

    private TypeReference createArrayTypeReference(
            TypeBinding elementType,
            int dims,
            boolean makeGeneric)
    {
    	// check generics:
    	if (elementType.isTypeVariable()) {
    		TypeVariableBinding typeVariable = (TypeVariableBinding)elementType;
    		char[] variableName = typeVariable.sourceName();
			if (dims == 0)
				return new SingleTypeReference(variableName, this.pos);
			else
				return new ArrayTypeReference(variableName, dims, this.pos);
    	} else if (makeGeneric && elementType.isParameterizedType()) {
    		// this branch currently cannot handle references of this shape: Outer<T>.Inner
    		// should that be needed at some point the following variant might do:
/*
			ParameterizedTypeBinding paramType = (ParameterizedTypeBinding)elementType;
			char[][] compoundName = paramType.compoundName;
			char[]tokenString = CharOperation.concatWith(compoundName, '$');
			compoundName = CharOperation.splitOn('$', tokenString);
			TypeReference[][] arguments = new TypeReference[compoundName.length][];
			int argPos = compoundName.length-1;
			boolean haveArguments = false;			
			do {
				TypeBinding[] argumentTypes = paramType.arguments;
				if (argumentTypes != null) {
					haveArguments = true;
					TypeReference[] currentArgs = new TypeReference[argumentTypes.length];
					arguments[argPos] = currentArgs;
					for (int i = 0; i < argumentTypes.length; i++) {
						currentArgs[i] = typeReference(argumentTypes[i]);
					}
				}
				ReferenceBinding enclosing = paramType.enclosingType();
				argPos--;
				if (enclosing instanceof ParameterizedTypeBinding)
					paramType = (ParameterizedTypeBinding) enclosing;
				else break;
			} while (argPos >= 0);
			if (haveArguments) {
				long[] poss = new long[compoundName.length];
				Arrays.fill(poss, this.pos);
				return new ParameterizedQualifiedTypeReference(compoundName, arguments, dims, poss);
			}
 */
			ParameterizedTypeBinding paramType = (ParameterizedTypeBinding)elementType;
			TypeBinding[] argumentTypes = paramType.arguments;
    		if (argumentTypes != null) {
    			char[][] compoundName = paramType.compoundName;
    			char[]tokenString = CharOperation.concatWith(compoundName, '$');
    			compoundName = CharOperation.splitOn('$', tokenString);
				TypeReference[][] arguments = new TypeReference[compoundName.length][];
				TypeReference[] lastArgs = new TypeReference[argumentTypes.length];
				arguments[compoundName.length-1] = lastArgs;
	    		for (int i = 0; i < argumentTypes.length; i++) {
					lastArgs[i] = typeReference(argumentTypes[i]);
				}
	    		long[] poss = new long[argumentTypes.length];
	    		Arrays.fill(poss, this.pos);
	    		return new ParameterizedQualifiedTypeReference(compoundName, arguments, dims, poss);
    		}
    	} else if (elementType.isWildcard()) {
    		WildcardBinding wildcard = (WildcardBinding)elementType;
    		Wildcard result = new Wildcard(wildcard.boundKind);
    		result.sourceStart = this.sourceStart;
    		result.sourceEnd   = this.sourceEnd;
    		if (wildcard.bound != null)
    			result.bound = typeReference(wildcard.bound);
    		// Note(SH): I don't see dims to be relevant here, OK?
    		return result;
    	}

    	// from this point: not generic:
        char[] typeName = "void".toCharArray(); //$NON-NLS-1$
        char [][] qname = null;
        TypeAnchorReference anchorRef = null;
        if (elementType instanceof BaseTypeBinding) {
        	typeName = ((BaseTypeBinding) elementType).simpleName;
        } else if (elementType instanceof ReferenceBinding) {
            ReferenceBinding referenceBinding = (ReferenceBinding)elementType;
			qname = TypeAnalyzer.compoundNameOfReferenceType(referenceBinding, true, false);
            if (   referenceBinding instanceof DependentTypeBinding
            	&& ((DependentTypeBinding)referenceBinding).hasExplicitAnchor())
            {
            	DependentTypeBinding depBind = (DependentTypeBinding)referenceBinding;
            	anchorRef = typeAnchorReference(depBind.getAnchor());
            	typeName = referenceBinding.internalName();
            	qname = null;
            }
        }
        char[] sname;
        if ((qname != null) && (qname.length==1)) {
            sname = qname[0]; // use this
            qname = null;     // not this
        } else {
            sname = typeName;
        }
        long[] poss = null;
        if (qname != null) {
        	poss = new long[qname.length];
        	Arrays.fill(poss, this.pos);
        }

        if (anchorRef == null) {
	        if (dims == 0) {
	            if (qname == null)
	           		return new SingleTypeReference(sname, this.pos);
	            else
	                return new QualifiedTypeReference(qname, poss);
	        } else {
	            if (qname == null)
	                return new ArrayTypeReference(sname, dims, this.pos);
	            else {
	                return new ArrayQualifiedTypeReference(qname, dims, poss);
	            }
	        }
        } else {
			TypeReference[] typeReferences = new TypeReference[]{anchorRef};
        	assert qname == null;
			return new ParameterizedSingleTypeReference(sname, typeReferences, dims, this.pos);
        }
    }

    public TypeAnchorReference typeAnchorReference(ITeamAnchor anchor) {
    	ReferenceBinding firstClass= null;
    	if (   (anchor instanceof FieldBinding)
    		&& CharOperation.equals(((FieldBinding)anchor).name, IOTConstants._OT_BASE))
    	{
    		Reference anchorRef;
    		if (this.replaceableBaseAnchor == anchor) {
				anchorRef = singleNameReference(BASE);
			} else {
				firstClass = ((FieldBinding)anchor).declaringClass;
	    		if (this.replaceableEnclosingClass != null)
	    			firstClass = strengthenEnclosing(firstClass, this.replaceableEnclosingClass);
				anchorRef = new QualifiedBaseReference(typeReference(firstClass), this.sourceStart, this.sourceEnd);
			}
    		return new TypeAnchorReference(anchorRef, this.sourceStart);
    	} else {
    		firstClass= anchor.getFirstDeclaringClass();
    	}
    	Reference nameRef = null;
    	ITeamAnchor[] path = anchor.getBestNamePath();
    	if (firstClass != null) {
    		if (this.replaceableEnclosingClass != null)
    			firstClass = strengthenEnclosing(firstClass, this.replaceableEnclosingClass);
	        nameRef = qualifiedThisReference(firstClass);
	    	for (int i=0; i<path.length; i++)
	    		if (!(path[i] instanceof TThisBinding))
	    			nameRef = fieldReference(nameRef, path[i].internalName());
    	} else {
    		if (anchor instanceof TThisBinding)
    			nameRef = qualifiedThisReference(anchor.getFirstDeclaringClass());
    		else
    			nameRef = qualifiedNameReference(anchor.tokens());
    	}
    	TypeAnchorReference anchorRef = new TypeAnchorReference(nameRef, this.sourceStart);
    	return anchorRef;
    }

    private ReferenceBinding strengthenEnclosing(ReferenceBinding currentType, ReferenceBinding strongEnclosing) {
    	while (strongEnclosing != null) {
			if (TypeBinding.equalsEquals(strongEnclosing, currentType) || TypeBinding.equalsEquals(strongEnclosing.superclass(), currentType))
				return strongEnclosing;
			ReferenceBinding currentOuter = currentType.enclosingType();
			if (currentOuter != null) {
				ReferenceBinding strongOuter = strengthenEnclosing(currentOuter, strongEnclosing);
				if (strongOuter != null)
					return strongOuter.getMemberType(currentType.internalName());
			}
			strongEnclosing = strongEnclosing.enclosingType();
    	}
		return null;
	}

	public TypeParameter typeParameter(TypeVariableBinding typeVarBinding) {
    	TypeParameter result = unboundedTypeParameter(typeVarBinding.sourceName);
    	result.type = typeReference(typeVarBinding.superclass);
    	ReferenceBinding[] superInterfaces = typeVarBinding.superInterfaces;
		if (superInterfaces != Binding.NO_SUPERINTERFACES && superInterfaces.length > 0)
		{
    		result.type = typeReference(superInterfaces[0]);
    		if (superInterfaces.length > 1) {
	    		result.bounds = new TypeReference[superInterfaces.length-1];
	    		for (int i = 0; i < superInterfaces.length-1; i++) {
					result.bounds[i] = typeReference(superInterfaces[i-1]);
					result.bounds[i].bits |= ASTNode.IsSuperType;
				}
    		}
    	}
		return result;
    }

    public TypeParameter baseBoundedTypeParameter (char[] name, ReferenceBinding roleType) {
    	TypeParameter result = unboundedTypeParameter(name);
    	result.type = typeReference(roleType);
    	result.type.bits |= ASTNode.IsRoleType;
    	return result;
    }

	public TypeParameter unboundedTypeParameter(char[] name) {
		TypeParameter result = new TypeParameter();
		result.name = name;
    	result.sourceStart = this.sourceStart;
    	result.sourceEnd   = this.sourceEnd;
    	result.declarationSourceStart = this.sourceStart;
    	result.declarationSourceEnd   = this.sourceEnd;
		return result;
	}

	public Wildcard wildcard(int kind) {
		Wildcard result = new Wildcard(kind);
		result.sourceStart = this.sourceStart;
		result.sourceEnd   = this.sourceEnd;
		return result;
	}
	
	public LiftingTypeReference liftingTypeReference(TypeReference baseReference, TypeReference roleReference, 
													 char[] roleToken, char[][] baseTokens) 
	{
		LiftingTypeReference result = new LiftingTypeReference();
		result.sourceStart   = this.sourceStart;
		result.sourceEnd     = this.sourceEnd;
		result.baseReference = baseReference;
		result.roleReference = roleReference;
		int len = baseTokens.length;
		result.baseTokens 	 = new char[len][];
		System.arraycopy(baseTokens, 0, result.baseTokens, 0, len);
		result.roleToken     = roleToken;
		return result;
	}
	
	public FieldDeclaration field(int modifiers, TypeReference typeRef, char[] name, Expression init)
	{
		FieldDeclaration field = new FieldDeclaration(name, this.sourceStart, this.sourceEnd);
	    field.declarationSourceStart = this.sourceStart;
	    field.declarationSourceEnd   = this.sourceEnd;
	    field.declarationEnd         = this.sourceEnd;
	    field.initialization = init;
	    field.type = typeRef;
	    field.modifiers = modifiers;
	    field.isGenerated = true;
		return field;
	}

	public ConstructorDeclaration constructor(CompilationResult compilationResult,
			int modifiers, char[] selector, Argument[] arguments)
	{
		ConstructorDeclaration newMethod = new ConstructorDeclaration(compilationResult);
		setMethodPositions(newMethod);
		newMethod.isGenerated = true;

		newMethod.modifiers = modifiers;
		newMethod.selector = selector;
		newMethod.arguments = arguments;
		return newMethod;
	}

	public MethodDeclaration method(CompilationResult compilationResult,
			int modifiers, TypeBinding returnType, char[] selector, Argument[] arguments)
	{
		TypeReference returnTypeRef = null;
		if (returnType != null)
			returnTypeRef = typeReference(returnType);
		return method(compilationResult,
				modifiers,
				returnTypeRef,
				selector,
				arguments);
	}

	public MethodDeclaration method(CompilationResult compilationResult,
			int modifiers, TypeReference returnTypeRef, char[] selector, Argument[] arguments)
	{
		MethodDeclaration newMethod = new MethodDeclaration(compilationResult);
		setMethodPositions(newMethod);
		newMethod.isGenerated = true;

		newMethod.modifiers  = modifiers;
		newMethod.returnType = returnTypeRef;
		newMethod.selector   = selector;
		newMethod.arguments  = arguments;
		return newMethod;
	}

	public MethodDeclaration method(CompilationResult compilationResult,
			int modifiers, TypeReference returnType, char[] selector, Argument[] arguments, Statement[] statements)
	{
		MethodDeclaration newMethod = method(compilationResult, modifiers, returnType, selector, arguments);
		newMethod.statements = statements;
		newMethod.hasParsedStatements = true;
		return newMethod;
	}

	/** If typeBinding has a free type parameter, we need to push this param out as a method parameter. */
	public void maybeAddTypeParametersToMethod(ReferenceBinding typeBinding, MethodDeclaration methodDecl) 
	{
		if (typeBinding.isParameterizedType()) {
			TypeBinding[] arguments = ((ParameterizedTypeBinding)typeBinding).arguments;
			TypeParameter[] methodTypeParams = new TypeParameter[arguments.length];
			for (int i = 0; i < methodTypeParams.length; i++)
				// FIXME(SH): what if arguments are not TypeVariableBinding (how could that happen?)
				methodTypeParams[i] = typeParameter((TypeVariableBinding)arguments[i]);
			methodDecl.typeParameters = methodTypeParams;
		}
	}

	public Argument argument(char[] name, TypeReference type) {
		Argument result = new Argument(name, this.pos, type, 0 /*modifiers*/);
		result.declarationSourceStart = this.sourceStart;
		return result;
	}

	public Argument argument(char[] name, TypeReference type, int modifiers) {
		Argument result = new Argument(name, this.pos, type, modifiers);
		result.declarationSourceStart = this.sourceStart;
		return result;
	}

	public MessageSend messageSend(Expression receiver, char[] selector, Expression[] parameters) {
		MessageSend messageSend =  new MessageSend();
		messageSend.isGenerated = true;
		messageSend.sourceStart = this.sourceStart;
		messageSend.sourceEnd   = this.sourceEnd;
		messageSend.statementEnd = this.sourceEnd;
		messageSend.nameSourcePosition = this.pos;
		messageSend.receiver = receiver;
		messageSend.selector = selector;
		messageSend.arguments = parameters;
		return messageSend;
	}
	public MessageSend tsuperMessageSend(Expression receiver, char[] selector, Expression[] parameters) {
		TSuperMessageSend messageSend =  new TSuperMessageSend();
		messageSend.isGenerated = true;
		messageSend.sourceStart = this.sourceStart;
		messageSend.sourceEnd   = this.sourceEnd;
		messageSend.statementEnd = this.sourceEnd;
		messageSend.nameSourcePosition = this.pos;
		messageSend.receiver = receiver;
		messageSend.tsuperReference = new TsuperReference(this.sourceStart, this.sourceEnd);
		messageSend.selector = selector;
		messageSend.arguments = parameters;
		return messageSend;
	}

	// function type for the next method:
	public static interface IRunInScope { void run(BlockScope scope); }

	/**
	 * Create a message send that has a custom resolve method (see inside for details).
	 */
	public MessageSend messageSendWithResolveHook(Expression receiver, final MethodBinding method, Expression[] parameters, final IRunInScope hook) {
		MessageSend messageSend = new MessageSend() {
			@Override
			public TypeBinding resolveType(BlockScope scope) {
				this.constant = Constant.NotAConstant;
				// arguments always need resolving:
				if (this.arguments != null) {
					int length = this.arguments.length;
					for (int i = 0; i < length; i++){
						Expression argument = this.arguments[i];
						if (argument.resolvedType == null)
							argument.resolveType(scope);
					}
				}
				// skip the receiver unless its again a hooked message send:
				if (this.receiver.getClass() == this.getClass())
					this.receiver.resolveType(scope);
				
				this.binding = method;
				this.resolvedType = method.returnType;

				// the main payload:
				hook.run(scope);
				
				this.actualReceiverType = this.binding.declaringClass;
				return this.resolvedType;
			}
		};
		messageSend.isGenerated = true;
		messageSend.sourceStart = this.sourceStart;
		messageSend.sourceEnd   = this.sourceEnd;
		messageSend.statementEnd = this.sourceEnd;
		messageSend.nameSourcePosition = this.pos;
		messageSend.receiver = receiver;
		messageSend.selector = method.selector;
		messageSend.arguments = parameters;
		return messageSend;
	}

	public MessageSend messageSend(Expression receiver, char[] selector, Expression[] parameters, final TypeBinding resolvedReturn) {
		MessageSend messageSend = new MessageSend() {
			@Override
			public TypeBinding resolveType(BlockScope scope) {
				super.resolveType(scope);
				return this.resolvedType = resolvedReturn;
			}
		};
		messageSend.isGenerated = true;
		messageSend.sourceStart = this.sourceStart;
		messageSend.sourceEnd   = this.sourceEnd;
		messageSend.statementEnd = this.sourceEnd;
		messageSend.nameSourcePosition = this.pos;
		messageSend.receiver = receiver;
		messageSend.selector = selector;
		messageSend.arguments = parameters;
		return messageSend;
	}

	/** Create a message send to a method that will be created by the otre. */
	public MessageSend fakeMessageSend(Expression receiver, char[] selector, Expression[] parameters, 
									   final ReferenceBinding receiverType, final TypeBinding resolvedReturn) 
	{
		MessageSend messageSend = new MessageSend() {
			@Override
			public TypeBinding resolveType(BlockScope scope) {
				ReferenceContext referenceContext = scope.referenceContext();
				CheckPoint cp = referenceContext.compilationResult().getCheckPoint(referenceContext);
				super.resolveType(scope);
				referenceContext.compilationResult().rollBack(cp);
				this.binding = new MethodBinding(ClassFileConstants.AccStatic|ClassFileConstants.AccPublic, this.selector, 
												 resolvedReturn, this.binding.parameters, Binding.NO_EXCEPTIONS, receiverType);
				return this.resolvedType = resolvedReturn;
			}
		};
		messageSend.isGenerated = true;
		messageSend.sourceStart = this.sourceStart;
		messageSend.sourceEnd   = this.sourceEnd;
		messageSend.statementEnd = this.sourceEnd;
		messageSend.nameSourcePosition = this.pos;
		messageSend.receiver = receiver;
		messageSend.selector = selector;
		messageSend.arguments = parameters;
		return messageSend;
	}

	public AllocationExpression allocation(TypeReference typeRef, Expression[] arguments) {
		AllocationExpression result = new AllocationExpression();
		result.sourceStart = this.sourceStart;
		result.sourceEnd   = this.sourceEnd;
		result.statementEnd = this.sourceEnd;
		result.type = typeRef;
		result.arguments = arguments;
		result.isGenerated = true;
		return result;
	}

	public ArrayAllocationExpression arrayAllocation(TypeReference typeRef, int dims, Expression[] arguments)
	{
    	ArrayAllocationExpression allocation = new ArrayAllocationExpression();
    	allocation.type = typeRef;
    	if (arguments == null) {
			allocation.dimensions = new Expression[]{intLiteral(dims)};
		} else {
			allocation.dimensions = new Expression[dims];
			allocation.initializer = new ArrayInitializer();
			allocation.initializer.expressions = arguments;
		}
    	return setPos(allocation);
	}
	public QualifiedAllocationExpression qualifiedAllocation(
			Expression enclosingInstance, SingleTypeReference typeRef, Expression[] arguments)
	{
		QualifiedAllocationExpression result = new QualifiedAllocationExpression();
		result.enclosingInstance = enclosingInstance;
		result.type              = typeRef; // Note: QualifiedAllocationExpression for roles really needs a SingleTypeReference.
		result.arguments         = arguments;
		return setPos(result);
	}

	public QualifiedAllocationExpression anonymousAllocation(
			TypeReference superType, Expression[] arguments, TypeDeclaration anonymousType) 
	{
		QualifiedAllocationExpression result = new QualifiedAllocationExpression();
		result.enclosingInstance = null;
		result.type              = superType;
		result.arguments         = arguments;
		result.anonymousType = anonymousType;
		anonymousType.allocation = result;
		return setPos(result);		
	}

	public TypeDeclaration anonymousType(CompilationResult compilationResult) {
		TypeDeclaration anonymousType = new TypeDeclaration(compilationResult);
		anonymousType.sourceStart = this.sourceStart;
		anonymousType.sourceEnd   = this.sourceEnd;
		anonymousType.declarationSourceStart = this.sourceStart;
		anonymousType.declarationSourceEnd   = this.sourceEnd;
		anonymousType.bodyStart  = this.sourceStart;
		anonymousType.bodyEnd    = this.sourceEnd;
		anonymousType.name = CharOperation.NO_CHAR;
		anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
		anonymousType.isGenerated = true;
		return anonymousType;
	}
	
	public ExplicitConstructorCall explicitConstructorCall(int accessMode) {
		ExplicitConstructorCall call = new ExplicitConstructorCall(accessMode);
		call.sourceStart = this.sourceStart;
		call.sourceEnd = this.sourceEnd;
		return call;
	}

	public CastExpression castExpression(Expression expression, TypeReference type, int kind)
	{
        CastExpression cast = new CastExpression(
                expression,
                type,
				kind);
        cast.constant = Constant.NotAConstant;
        return setPos(cast);
	}
	/**
	 * Create a cast expression from its elements (reference types only).
	 * Perform necessary internal initializations without calling resolveType()
	 * @param expr
	 * @param type
	 * @param kind one of CastExpression.{DO_WRAP,NEED_CLASS,RAW}
	 *
	 * @return null is used to signal no cast created (because expr is 'this').
	 */
	public CastExpression resolvedCastExpression(
							        Expression   expr,
							        TypeBinding  type,
									int kind)
	{
	    if (expr instanceof ThisReference)
	        return null; // never useful to cast 'this'!
	    TypeReference typeRef = typeReference(type);
	    typeRef.sourceStart = this.sourceStart;
	    typeRef.sourceEnd   = this.sourceEnd;
	    typeRef.resolvedType = type;

	    CastExpression cast = new CastExpression(expr, typeRef, kind);
		typeRef.resolvedType =
		    cast.resolvedType = type;
	    cast.constant = Constant.NotAConstant;
	    cast.tagAsNeedCheckCast();
	    return setPos(cast);
	}

	public InstanceOfExpression instanceOfExpression(Expression expression, TypeReference type) {
		InstanceOfExpression result = new InstanceOfExpression(expression, type);
		return result;
	}
	public ReturnStatement returnStatement(Expression expression) {
		return new ReturnStatement(expression, this.sourceStart, this.sourceEnd);
	}
	public ReturnStatement returnStatement(Expression expression, boolean synthetic) {
		ReturnStatement returnStatement = new ReturnStatement(expression, this.sourceStart, this.sourceEnd);
		if (synthetic)
			returnStatement.isGenerated = true;
		return returnStatement;
	}
	public IfStatement ifStatement(Expression condition, Statement thenStatement) {
		return new IfStatement(condition, thenStatement, this.sourceStart, this.sourceEnd);
	}
	public IfStatement ifStatement(Expression condition, Statement thenStatement, Statement elseStatement)
	{
		IfStatement result = new IfStatement(condition, thenStatement, this.sourceStart, this.sourceEnd);
		result.elseStatement = elseStatement;
		return result;
	}
	public IfStatement ifStatement(Expression condition, Block thenBlock, Block elseBlock) {
		IfStatement result = new IfStatement(condition, thenBlock, this.sourceStart, this.sourceEnd);
		result.elseStatement = elseBlock;
		return result;
	}
	/**
	 * Assemble an ifstatement with negated condition, that hides the branch instruction from the debugger,
	 * even when stepping into the condition. 
	 */
	public IfStatement stealthIfNotStatement(final Expression condition, Statement thenStatement) {
		// mark step-over after the condition:
		Expression recordingCondition = new Expression() {
			public StringBuffer printExpression(int indent, StringBuffer output) { return condition.print(indent, output); }
			public TypeBinding resolveType(BlockScope scope) {
				return condition.resolveType(scope); 
			}
			public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding compileTimeType) {
				condition.computeConversion(scope, runtimeType, compileTimeType);
				this.constant = condition.constant;
				this.bits = condition.bits;
			}
			public Constant optimizedBooleanConstant() { 
				this.constant = condition.optimizedBooleanConstant();
				this.bits = condition.bits;
				return this.constant; 
			}
			public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
				return condition.analyseCode(currentScope, flowContext, flowInfo, valueRequired);
			}
			public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
				return condition.analyseCode(currentScope, flowContext, flowInfo);
			}
			public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
				condition.generateCode(currentScope, codeStream, valueRequired);
				// payload:
				codeStream.pcToSourceMap[codeStream.pcToSourceMapSize++] = codeStream.position;
				codeStream.pcToSourceMap[codeStream.pcToSourceMapSize++] = STEP_OVER_LINENUMBER;
			}
		};
		return new IfStatement(
				new UnaryExpression( // NOT
						recordingCondition,
						OperatorIds.NOT),
				thenStatement, 
				this.sourceStart, this.sourceEnd);
	}
	public ThrowStatement throwStatement(Expression exception) {
		return new ThrowStatement(exception, this.sourceStart, this.sourceEnd);
	}
	public CaseStatement caseStatement(Expression constExpr) {
		return new CaseStatement(constExpr, this.sourceStart, this.sourceEnd);
	}
	public BreakStatement breakStatement() {
		return new BreakStatement(null, this.sourceStart, this.sourceEnd);
	}
	public Assignment assignment(Reference lhs, Expression rhs) {
		Assignment ass = new Assignment(lhs, rhs, this.sourceEnd);
		ass.statementEnd = this.sourceEnd;
		return ass;
	}

	public Block block2(Statement stmt1, Statement stmt2) {
		int explicitDeclarations = 0;
		if (stmt1 instanceof LocalDeclaration) explicitDeclarations++;
		if (stmt2 instanceof LocalDeclaration) explicitDeclarations++;
		Block result = new Block(explicitDeclarations);
		result.sourceStart = this.sourceStart;
		result.sourceEnd = this.sourceEnd;
		result.statements = new Statement[] { stmt1, stmt2 };
		return result;
	}

	public Block block(Statement[] stmts) {
		int explicitDeclarations = 0;
		if (stmts != null)
			for (Statement statement : stmts)
				if (statement instanceof LocalDeclaration)
					explicitDeclarations++;

		Block result = new Block(explicitDeclarations);
		result.sourceStart = this.sourceStart;
		result.sourceEnd = this.sourceEnd;
		result.statements = stmts;
		return result;
	}

	public SynchronizedStatement synchronizedStatement(Expression expr, Statement[] stmts)
	{
		return new SynchronizedStatement(expr, block(stmts), this.sourceStart, this.sourceEnd);
	}

	public Statement statement(List<Statement> stmtList) {
		if (stmtList.isEmpty())
			return emptyStatement();
		if (stmtList.size() == 1)
			return stmtList.get(0);
		Statement[] stmtArray = new Statement[stmtList.size()];
		stmtList.toArray(stmtArray);
		return block(stmtArray);
	}

	public ForeachStatement foreach(
								LocalDeclaration variable,
								Expression       collection,
								Statement        body)
	{
		ForeachStatement foreach = new ForeachStatement(variable, this.sourceStart);
		foreach.collection = collection;
		foreach.action = body;
		if (this.sourceLevel < ClassFileConstants.JDK1_5)
			foreach.markRaw();
		return foreach;
	}

	public TryStatement tryFinally(Statement[] tryStatements, Statement[] finallyStatements) {
		TryStatement stat = new TryStatement();
		stat.sourceStart = this.sourceStart;
		stat.sourceEnd   = this.sourceEnd;
		stat.tryBlock = block(tryStatements);
		stat.finallyBlock = block(finallyStatements);
		if (finallyStatements != null) {
			int len = finallyStatements.length;
			if (len > 0) {
				stat.finallyBlock.sourceStart = finallyStatements[0].sourceStart;
				stat.finallyBlock.sourceEnd   = finallyStatements[len-1].sourceEnd;
			}
		}
		return stat;
	}

	public TryStatement tryCatch(Statement[] tryStatements, Argument exceptionArgument, Statement[] catchStatements) {
		TryStatement stat = new TryStatement();
		stat.sourceStart = this.sourceStart;
		stat.sourceEnd   = this.sourceEnd;
		stat.tryBlock = block(tryStatements);
		stat.catchArguments = new Argument[] { exceptionArgument };
		stat.catchBlocks = new Block[] { block(catchStatements) };
		return stat;
	}

	public TryStatement tryCatch(Statement[] tryStatements, Argument[] exceptionArguments, Statement[][] catchStatementss) {
		TryStatement stat = new TryStatement();
		stat.sourceStart = this.sourceStart;
		stat.sourceEnd   = this.sourceEnd;
		stat.tryBlock = block(tryStatements);
		stat.catchArguments = exceptionArguments;
		stat.catchBlocks = new Block[catchStatementss.length];
		for(int i=0; i<catchStatementss.length; i++)
			stat.catchBlocks[i] = block(catchStatementss[i]);
		return stat;
	}

	/** Generate a full try-catch-finally statement. */
	public TryStatement tryStatement(Statement[] tryStatements,
									 Argument[] exceptionArguments, Statement[][] catchStatementss,
									 Statement[] finallyStatements)
	{
		TryStatement stat = new TryStatement();
		stat.sourceStart = this.sourceStart;
		stat.sourceEnd   = this.sourceEnd;
		stat.tryBlock = block(tryStatements);
		stat.catchArguments = exceptionArguments;
		stat.catchBlocks = new Block[catchStatementss.length];
		for(int i=0; i<catchStatementss.length; i++)
			stat.catchBlocks[i] = block(catchStatementss[i]);
		stat.finallyBlock = block(finallyStatements);
		if (finallyStatements != null) {
			int len = finallyStatements.length;
			if (len > 0) {
				stat.finallyBlock.sourceStart = finallyStatements[0].sourceStart;
				stat.finallyBlock.sourceEnd   = finallyStatements[len-1].sourceEnd;
			}
		}
		return stat;
	}

	/**
	 * Create a lifting of an expression to an expectedType if expectedType is in deed
	 * a role type different from the type of expression (deferred decision).
	 * Assumes that the role must be within the current scope so that a qualified this
	 * suffices as a receiver for the lift call.
	 *
	 * @param receiver     receiver for the lift call (referring to some team instance)
	 * @param expression   the exression to be lifted
	 * @param expectedType the required role(?) type
	 * @param reversible   is reversibility of this operation requested (callin replace)?
	 * @return a PotentialLiftExpression or the original expression
	 */
	public Expression potentialLift(Expression  receiver,
								    Expression  expression,
								    TypeBinding expectedType,
								    boolean     reversible)
	{
		if (expectedType.leafComponentType().isBaseType())
			return expression; // cannot lift to simple
		ReferenceBinding expectedRef = (ReferenceBinding)expectedType.leafComponentType();
		ReferenceBinding teamBinding = expectedRef.enclosingType();
		if (teamBinding == null || !teamBinding.isTeam())
			return expression;
		if (receiver == null)
			receiver = new QualifiedThisReference(
					typeReference(teamBinding), this.sourceStart, this.sourceEnd);
		PotentialLiftExpression lifter = new PotentialLiftExpression(
				receiver,
				expression,
				expectedType);
		lifter.requireReverseOperation = reversible;
		return lifter;
	}

	public ThisReference thisReference() {
		return new ThisReference(this.sourceStart, this.sourceEnd);
	}


	public SuperReference superReference() {
		return new SuperReference(this.sourceStart, this.sourceEnd);
	}

	public ThisReference tsuperReference() {
		return new TsuperReference(this.sourceStart, this.sourceEnd);
	}

	/**
	 * @param binding prefix the "this" reference by this type.
	 * @return Outer.this where "Outer" is identified by binding
	 */
	public Reference qualifiedThisReference(ReferenceBinding binding) {
		return new QualifiedThisReference(
				typeReference(binding),
				this.sourceStart, this.sourceEnd);
	}
	/**
	 * @param reference prefix the "this" reference by this type.
	 * @return Outer.this where "Outer" is identified by reference
	 */
	public Expression qualifiedThisReference(TypeReference reference) {
		return new QualifiedThisReference(reference, this.sourceStart, this.sourceEnd);
	}
	public Statement emptyStatement() {
		return new EmptyStatement(this.sourceStart, this.sourceEnd) {
        			@Override public void resolve(BlockScope scope) { /* nop: no warning. */ } };
	}

	/**
	 * For debuggin purposes: create a println with given string as literal argument
	 * @return the statement (message send)
	 */
	public MessageSend println(String msg) {
		return messageSend(
				new QualifiedNameReference(
						new char[][]{"System".toCharArray(), "out".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$
						new long[]{this.pos, this.pos},
						this.sourceStart, this.sourceEnd),
				"println".toCharArray(), //$NON-NLS-1$
				new Expression[] {stringLiteral(msg.toCharArray())}
		);
	}
	/** print a message plus the value of an expression. */
	public MessageSend println(String msg, Expression expr) {
		return messageSend(
				new QualifiedNameReference(
						new char[][]{"System".toCharArray(), "out".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$
						new long[]{this.pos, this.pos},
						this.sourceStart, this.sourceEnd),
				"println".toCharArray(), //$NON-NLS-1$
				new Expression[] {
					new BinaryExpression(stringLiteral(msg.toCharArray()), expr, OperatorIds.PLUS)}
		);
	}

	/**
	 * A type reference for the cache of a given bound root role.
     * If source level >= 1.5 use a generic type for the cache!
     * Generic type respects different status for base/role types:
     * - base is resolved via base import scope and supports decapsulation.
	 */
	public QualifiedTypeReference getCacheTypeReference(Scope scope, RoleModel boundRootRole) {
		if ((scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5)) {
	    	ReferenceBinding baseTypeBinding = boundRootRole.getBaseTypeBinding();
	    	if (baseTypeBinding == null)
	    		baseTypeBinding = scope.getJavaLangObject();
			ReferenceBinding rootRoleBinding = boundRootRole.getInterfacePartBinding();

			ParameterizedQualifiedTypeReference fieldTypeRef;
			TypeReference[] typeArguments = new TypeReference[] {
				baseclassReference(baseTypeBinding, true/*erase*/),
				singleTypeReference(rootRoleBinding.sourceName())	
			};
			fieldTypeRef = (ParameterizedQualifiedTypeReference)parameterizedQualifiedTypeReference(
								WEAK_HASH_MAP,
								typeArguments);
			return fieldTypeRef;
	    } else {
	    	return new QualifiedTypeReference(WEAK_HASH_MAP, new long[]{this.pos,this.pos,this.pos});
	    }
	}

	/**
	 * @param resultExpr
	 * @return a message send for the boxed value.
	 */
	public MessageSend createBoxing(Expression resultExpr, BaseTypeBinding type)
	{
		char[][] boxedType = boxTypeName(type);
		return messageSend(qualifiedTypeReference(boxedType), TypeConstants.VALUEOF, new Expression[]{resultExpr});
	}

	public static char[][] boxTypeName(BaseTypeBinding type) {
		switch (type.id) {
		case TypeIds.T_byte: 	return TypeConstants.JAVA_LANG_BYTE;
		case TypeIds.T_boolean: return TypeConstants.JAVA_LANG_BOOLEAN;
		case TypeIds.T_int: 	return TypeConstants.JAVA_LANG_INTEGER;
		case TypeIds.T_short: 	return TypeConstants.JAVA_LANG_SHORT;
		case TypeIds.T_long : 	return TypeConstants.JAVA_LANG_LONG;
		case TypeIds.T_double: 	return TypeConstants.JAVA_LANG_DOUBLE;
		case TypeIds.T_float: 	return TypeConstants.JAVA_LANG_FLOAT;
		case TypeIds.T_char: 	return TypeConstants.JAVA_LANG_CHARACTER;
		default: throw new InternalCompilerError("trying to box non-primitive type"); //$NON-NLS-1$
		}
	}

	public Expression createUnboxing(Expression expression, BaseTypeBinding basicType) {
		char[][] boxedTypeName = boxTypeName(basicType);
		char[] selector = CharOperation.concat(basicType.sourceName(), "Value".toCharArray()); //$NON-NLS-1$
		return messageSend(
					castExpression(
							expression,
							qualifiedTypeReference(boxedTypeName),
							CastExpression.RAW),
					selector,
					null);
	}
	public Expression createCastOrUnboxing(Expression expression, TypeBinding expectedType, boolean baseAccess) {
		if (expectedType.isBaseType())
			return createUnboxing(expression, (BaseTypeBinding)expectedType);
		else if (baseAccess)
			return castExpression(expression, baseclassReference(expectedType), CastExpression.RAW);
		else
			return castExpression(expression, typeReference(expectedType), CastExpression.RAW);
	}
	public Expression createCastOrUnboxing(Expression expression, TypeBinding expectedType, Scope originalScope) {
		if (expectedType.isBaseType())
			return createUnboxing(expression, (BaseTypeBinding)expectedType);
		else
			return castExpression(expression, alienScopeTypeReference(typeReference(expectedType), originalScope), CastExpression.RAW);
	}
	
	// ========= Method Mappings: =========
	public CalloutMappingDeclaration calloutMappingDeclaration(
			CompilationResult compilationResult) {
		CalloutMappingDeclaration result = new CalloutMappingDeclaration(compilationResult);
		result.sourceStart = this.sourceStart;
		result.sourceEnd = this.sourceEnd;
		return result;
	}
	public MethodSpec methodSpec(char[] selector) {
		return new MethodSpec(selector, this.sourceStart, this.sourceEnd);
	}
	public FieldAccessSpec fieldAccessSpec(char[] fieldName, TypeBinding type, boolean isSetter) {
		return new FieldAccessSpec(fieldName, typeReference(type), this.pos,
								   isSetter?TerminalTokens.TokenNameset:TerminalTokens.TokenNameget);
	}

	// ========= DETAILED EXPRESSIONS ===========
	public ArrayReference arrayReference(Expression expression, int index) {
		return setPos(new ArrayReference(expression, intLiteral(index)));
	}

	public ArrayReference arrayReference(Expression expression, Expression indexExpression) {
		return setPos(new ArrayReference(expression, indexExpression));
	}

	public EqualExpression equalExpression (Expression left, Expression right, int operator)
	{
		return setPos(new EqualExpression(left, right, operator));
	}
	public <E extends Expression> E setPos(E e) {
		e.sourceStart = this.sourceStart;
		e.sourceEnd = this.sourceEnd;
		e.statementEnd = this.sourceEnd;
		return e;
	}
	// ========== ANNOTATION =============
	public SingleMemberAnnotation singleMemberAnnotation(char[][] compoundName, Expression memberValue) {
		SingleMemberAnnotation result = new SingleMemberAnnotation(qualifiedTypeReference(compoundName), this.sourceStart);
		result.sourceEnd = this.sourceEnd;
		result.declarationSourceEnd = this.sourceEnd;
		result.memberValue = memberValue;
		return result;
	}
	public SingleMemberAnnotation singleStringsMemberAnnotation(char[][] compoundName, char[][] memberValues) {
		SingleMemberAnnotation result = new SingleMemberAnnotation(qualifiedTypeReference(compoundName), this.sourceStart);
		result.sourceEnd = this.sourceEnd;
		result.declarationSourceEnd = this.sourceEnd;
		ArrayInitializer arrayInitializer = new ArrayInitializer();
		arrayInitializer.expressions = new Expression[memberValues.length];
		for (int i = 0; i < memberValues.length; i++)
			arrayInitializer.expressions[i] = stringLiteral(memberValues[i]);
		result.memberValue = arrayInitializer;
		return result;
	}
	
	public NormalAnnotation normalAnnotation(char[][] compoundName, char[][] names, Expression[] values) {
		assert names.length == values.length : "names and values must have same length"; //$NON-NLS-1$
		NormalAnnotation result = new NormalAnnotation(qualifiedTypeReference(compoundName), this.sourceStart);
		result.sourceEnd = this.sourceEnd;
		result.declarationSourceEnd = this.sourceEnd;
		MemberValuePair[] pairs = new MemberValuePair[names.length];
		for (int i = 0; i < names.length; i++) {
			pairs[i] = new MemberValuePair(names[i], this.sourceStart, this.sourceEnd, values[i]);
		}
		result.memberValuePairs = pairs;
		return result;
	}
	
	public MarkerAnnotation markerAnnotation(char[][] compoundName) {
		return new MarkerAnnotation(qualifiedTypeReference(compoundName), this.sourceStart);
	}

	public void addNonNullAnnotation(Argument argument, LookupEnvironment environment) {
		addNullAnnotation(argument, environment, true);
	}

	public void addNullAnnotation(Argument argument, LookupEnvironment environment, boolean nonNull) {
		CompilerOptions compilerOptions = environment.globalOptions;
		if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
			char[][] annotationName = nonNull ? environment.getNonNullAnnotationName() : environment.getNullableAnnotationName();
			if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_8) {
				argument.annotations = new Annotation[]{ markerAnnotation(annotationName) };
			} else {
				int levels = argument.type.getAnnotatableLevels();
				argument.type.annotations = new Annotation[levels][];
				argument.type.annotations[levels-1] = new Annotation[] { markerAnnotation(annotationName) };
			}
		}
	}

	/**
	 * Wrap the baseclass reference from a tsuper role to a new type reference
	 * yet using the original scope for resolving.
	 * Also used for type references in callin wrappers
	 */
	public TypeReference alienScopeTypeReference(TypeReference original, Scope origScope)
	{
		if (original instanceof IAlienScopeTypeReference)
			origScope = ((IAlienScopeTypeReference)original).getAlienScope();
//		if (origScope.parent.kind == Scope.CLASS_SCOPE)
//			origScope = (ClassScope)origScope.parent;
	
		TypeReference result;
		if (original instanceof ParameterizedSingleTypeReference) {
			ParameterizedSingleTypeReference pstRef = (ParameterizedSingleTypeReference) original;
			TypeReference[] typeArguments = AstClone.copyTypeArguments(original, this.pos, pstRef.typeArguments);
			result = new AlienScopeParameterizedSingleTypeReference(pstRef.token, typeArguments, pstRef.dimensions, this.pos, origScope);
		} else if (original instanceof SingleTypeReference) {
			if (original instanceof ArrayTypeReference && original.dimensions() > 0) { // could be parameterized type reference
				ArrayTypeReference singleTypeRef = (ArrayTypeReference) original;
				result = new AlienScopeArrayTypeReference(singleTypeRef.token, this.pos, singleTypeRef.dimensions, origScope);				
			} else {
				SingleTypeReference singleTypeRef = (SingleTypeReference) original;
				result = new AlienScopeSingleTypeReference(singleTypeRef.token, this.pos, origScope);
			}
		} else if (original instanceof QualifiedTypeReference) {
			if (original instanceof ArrayQualifiedTypeReference && original.dimensions() > 0) { // could be parameterized type reference
				ArrayQualifiedTypeReference qTypeRef= (ArrayQualifiedTypeReference)original;
				result = new AlienScopeArrayQualifiedTypeReference(qTypeRef.tokens, qTypeRef.sourcePositions, qTypeRef.dimensions(), origScope);				
			} else if (original instanceof ParameterizedQualifiedTypeReference) {
				ParameterizedQualifiedTypeReference qTypeRef= (ParameterizedQualifiedTypeReference)original;
				result = new AlienScopeParameterizedQualifiedTypeReference(qTypeRef, origScope);
			} else {
				QualifiedTypeReference qTypeRef= (QualifiedTypeReference)original;
				result = new AlienScopeQualifiedTypeReference(qTypeRef.tokens, qTypeRef.sourcePositions, origScope);
			}
		} else {			
			throw new InternalCompilerError("Unexpected type reference: "+original); //$NON-NLS-1$
		}
		result.setBaseclassDecapsulation(DecapsulationState.REPORTED);
		result.bits |= ASTNode.IgnoreRawTypeCheck;
		return result;
	}
}

Back to the top