src/share/classes/com/sun/tools/javac/comp/MemberEnter.java

changeset 1791
e9855150c5b0
parent 1755
ddb4a2bfcd82
child 1802
8fb68f73d4b1
equal deleted inserted replaced
1790:9f11c7676cd5 1791:e9855150c5b0
994 List<Type> typarams = List.nil(); 994 List<Type> typarams = List.nil();
995 List<Type> thrown = List.nil(); 995 List<Type> thrown = List.nil();
996 long ctorFlags = 0; 996 long ctorFlags = 0;
997 boolean based = false; 997 boolean based = false;
998 boolean addConstructor = true; 998 boolean addConstructor = true;
999 JCNewClass nc = null;
999 if (c.name.isEmpty()) { 1000 if (c.name.isEmpty()) {
1000 JCNewClass nc = (JCNewClass)env.next.tree; 1001 nc = (JCNewClass)env.next.tree;
1001 if (nc.constructor != null) { 1002 if (nc.constructor != null) {
1002 addConstructor = nc.constructor.kind != ERR; 1003 addConstructor = nc.constructor.kind != ERR;
1003 Type superConstrType = types.memberType(c.type, 1004 Type superConstrType = types.memberType(c.type,
1004 nc.constructor); 1005 nc.constructor);
1005 argtypes = superConstrType.getParameterTypes(); 1006 argtypes = superConstrType.getParameterTypes();
1011 } 1012 }
1012 thrown = superConstrType.getThrownTypes(); 1013 thrown = superConstrType.getThrownTypes();
1013 } 1014 }
1014 } 1015 }
1015 if (addConstructor) { 1016 if (addConstructor) {
1017 MethodSymbol basedConstructor = nc != null ?
1018 (MethodSymbol)nc.constructor : null;
1016 JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, 1019 JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
1020 basedConstructor,
1017 typarams, argtypes, thrown, 1021 typarams, argtypes, thrown,
1018 ctorFlags, based); 1022 ctorFlags, based);
1019 tree.defs = tree.defs.prepend(constrDef); 1023 tree.defs = tree.defs.prepend(constrDef);
1020 } 1024 }
1021 } 1025 }
1397 * @param thrown The thrown exceptions of the constructor. 1401 * @param thrown The thrown exceptions of the constructor.
1398 * @param based Is first parameter a this$n? 1402 * @param based Is first parameter a this$n?
1399 */ 1403 */
1400 JCTree DefaultConstructor(TreeMaker make, 1404 JCTree DefaultConstructor(TreeMaker make,
1401 ClassSymbol c, 1405 ClassSymbol c,
1406 MethodSymbol baseInit,
1402 List<Type> typarams, 1407 List<Type> typarams,
1403 List<Type> argtypes, 1408 List<Type> argtypes,
1404 List<Type> thrown, 1409 List<Type> thrown,
1405 long flags, 1410 long flags,
1406 boolean based) { 1411 boolean based) {
1407 List<JCVariableDecl> params = make.Params(argtypes, syms.noSymbol); 1412 JCTree result;
1408 List<JCStatement> stats = List.nil();
1409 if (c.type != syms.objectType)
1410 stats = stats.prepend(SuperCall(make, typarams, params, based));
1411 if ((c.flags() & ENUM) != 0 && 1413 if ((c.flags() & ENUM) != 0 &&
1412 (types.supertype(c.type).tsym == syms.enumSym)) { 1414 (types.supertype(c.type).tsym == syms.enumSym)) {
1413 // constructors of true enums are private 1415 // constructors of true enums are private
1414 flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR; 1416 flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
1415 } else 1417 } else
1416 flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR; 1418 flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
1417 if (c.name.isEmpty()) flags |= ANONCONSTR; 1419 if (c.name.isEmpty()) {
1418 JCTree result = make.MethodDef( 1420 flags |= ANONCONSTR;
1419 make.Modifiers(flags), 1421 }
1420 names.init, 1422 Type mType = new MethodType(argtypes, null, thrown, c);
1421 null, 1423 Type initType = typarams.nonEmpty() ?
1422 make.TypeParams(typarams), 1424 new ForAll(typarams, mType) :
1423 params, 1425 mType;
1424 make.Types(thrown), 1426 MethodSymbol init = new MethodSymbol(flags, names.init,
1425 make.Block(0, stats), 1427 initType, c);
1426 null); 1428 init.params = createDefaultConstructorParams(make, baseInit, init,
1429 argtypes, based);
1430 List<JCVariableDecl> params = make.Params(argtypes, init);
1431 List<JCStatement> stats = List.nil();
1432 if (c.type != syms.objectType) {
1433 stats = stats.prepend(SuperCall(make, typarams, params, based));
1434 }
1435 result = make.MethodDef(init, make.Block(0, stats));
1427 return result; 1436 return result;
1437 }
1438
1439 private List<VarSymbol> createDefaultConstructorParams(
1440 TreeMaker make,
1441 MethodSymbol baseInit,
1442 MethodSymbol init,
1443 List<Type> argtypes,
1444 boolean based) {
1445 List<VarSymbol> initParams = null;
1446 List<Type> argTypesList = argtypes;
1447 if (based) {
1448 /* In this case argtypes will have an extra type, compared to baseInit,
1449 * corresponding to the type of the enclosing instance i.e.:
1450 *
1451 * Inner i = outer.new Inner(1){}
1452 *
1453 * in the above example argtypes will be (Outer, int) and baseInit
1454 * will have parameter's types (int). So in this case we have to add
1455 * first the extra type in argtypes and then get the names of the
1456 * parameters from baseInit.
1457 */
1458 initParams = List.nil();
1459 VarSymbol param = new VarSymbol(0, make.paramName(0), argtypes.head, init);
1460 initParams = initParams.append(param);
1461 argTypesList = argTypesList.tail;
1462 }
1463 if (baseInit != null && baseInit.params != null &&
1464 baseInit.params.nonEmpty() && argTypesList.nonEmpty()) {
1465 initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams;
1466 List<VarSymbol> baseInitParams = baseInit.params;
1467 while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) {
1468 VarSymbol param = new VarSymbol(baseInitParams.head.flags(),
1469 baseInitParams.head.name, argTypesList.head, init);
1470 initParams = initParams.append(param);
1471 baseInitParams = baseInitParams.tail;
1472 argTypesList = argTypesList.tail;
1473 }
1474 }
1475 return initParams;
1428 } 1476 }
1429 1477
1430 /** Generate call to superclass constructor. This is: 1478 /** Generate call to superclass constructor. This is:
1431 * 1479 *
1432 * super(id_0, ..., id_n) 1480 * super(id_0, ..., id_n)

mercurial