Merge jdk7-b58

Mon, 04 May 2009 22:16:46 -0700

author
tbell
date
Mon, 04 May 2009 22:16:46 -0700
changeset 268
5bcac54d408b
parent 266
8a2424db1a14
parent 267
e2722bd43f3a
child 269
88bcb6772159
child 275
846944dd48a4

Merge

     1.1 --- a/src/share/classes/com/sun/tools/classfile/Opcode.java	Thu Apr 30 15:04:50 2009 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/classfile/Opcode.java	Mon May 04 22:16:46 2009 -0700
     1.3 @@ -226,7 +226,7 @@
     1.4      INVOKESPECIAL(0xb7, CPREF_W),
     1.5      INVOKESTATIC(0xb8, CPREF_W),
     1.6      INVOKEINTERFACE(0xb9, CPREF_W_UBYTE_ZERO),
     1.7 -    // unused 0xba
     1.8 +    INVOKEDYNAMIC(0xba, CPREF_W_UBYTE_ZERO),
     1.9      NEW(0xbb, CPREF_W),
    1.10      NEWARRAY(0xbc, ATYPE),
    1.11      ANEWARRAY(0xbd, CPREF_W),
     2.1 --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Apr 30 15:04:50 2009 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Mon May 04 22:16:46 2009 -0700
     2.3 @@ -119,6 +119,8 @@
     2.4      public final Type stringBuilderType;
     2.5      public final Type cloneableType;
     2.6      public final Type serializableType;
     2.7 +    public final Type methodHandleType;
     2.8 +    public final Type invokeDynamicType;
     2.9      public final Type throwableType;
    2.10      public final Type errorType;
    2.11      public final Type illegalArgumentExceptionType;
    2.12 @@ -289,6 +291,24 @@
    2.13          }
    2.14      }
    2.15  
    2.16 +    public void synthesizeMHTypeIfMissing(final Type type) {
    2.17 +        final Completer completer = type.tsym.completer;
    2.18 +        if (completer != null) {
    2.19 +            type.tsym.completer = new Completer() {
    2.20 +                public void complete(Symbol sym) throws CompletionFailure {
    2.21 +                    try {
    2.22 +                        completer.complete(sym);
    2.23 +                    } catch (CompletionFailure e) {
    2.24 +                        sym.flags_field |= (PUBLIC | ABSTRACT);
    2.25 +                        ((ClassType) sym.type).supertype_field = objectType;
    2.26 +                        // do not bother to create MH.type if not visibly declared
    2.27 +                        // this sym just accumulates invoke(...) methods
    2.28 +                    }
    2.29 +                }
    2.30 +            };
    2.31 +        }
    2.32 +    }
    2.33 +
    2.34      public void synthesizeBoxTypeIfMissing(final Type type) {
    2.35          ClassSymbol sym = reader.enterClass(boxedName[type.tag]);
    2.36          final Completer completer = sym.completer;
    2.37 @@ -405,6 +425,8 @@
    2.38          cloneableType = enterClass("java.lang.Cloneable");
    2.39          throwableType = enterClass("java.lang.Throwable");
    2.40          serializableType = enterClass("java.io.Serializable");
    2.41 +        methodHandleType = enterClass("java.dyn.MethodHandle");
    2.42 +        invokeDynamicType = enterClass("java.dyn.InvokeDynamic");
    2.43          errorType = enterClass("java.lang.Error");
    2.44          illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
    2.45          exceptionType = enterClass("java.lang.Exception");
    2.46 @@ -441,6 +463,8 @@
    2.47  
    2.48          synthesizeEmptyInterfaceIfMissing(cloneableType);
    2.49          synthesizeEmptyInterfaceIfMissing(serializableType);
    2.50 +        synthesizeMHTypeIfMissing(methodHandleType);
    2.51 +        synthesizeMHTypeIfMissing(invokeDynamicType);
    2.52          synthesizeBoxTypeIfMissing(doubleType);
    2.53          synthesizeBoxTypeIfMissing(floatType);
    2.54  
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Apr 30 15:04:50 2009 -0700
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon May 04 22:16:46 2009 -0700
     3.3 @@ -118,6 +118,7 @@
     3.4          relax = (options.get("-retrofit") != null ||
     3.5                   options.get("-relax") != null);
     3.6          useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null;
     3.7 +        allowInvokedynamic = options.get("invokedynamic") != null;
     3.8      }
     3.9  
    3.10      /** Switch: relax some constraints for retrofit mode.
    3.11 @@ -149,6 +150,10 @@
    3.12       */
    3.13      boolean allowAnonOuterThis;
    3.14  
    3.15 +    /** Switch: allow invokedynamic syntax
    3.16 +     */
    3.17 +    boolean allowInvokedynamic;
    3.18 +
    3.19      /**
    3.20       * Switch: warn about use of variable before declaration?
    3.21       * RFE: 6425594
    3.22 @@ -438,14 +443,22 @@
    3.23      }
    3.24  
    3.25      /** Attribute a type argument list, returning a list of types.
    3.26 +     *  Caller is responsible for calling checkRefTypes.
    3.27       */
    3.28 -    List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) {
    3.29 +    List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) {
    3.30          ListBuffer<Type> argtypes = new ListBuffer<Type>();
    3.31          for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
    3.32 -            argtypes.append(chk.checkRefType(l.head.pos(), attribType(l.head, env)));
    3.33 +            argtypes.append(attribType(l.head, env));
    3.34          return argtypes.toList();
    3.35      }
    3.36  
    3.37 +    /** Attribute a type argument list, returning a list of types.
    3.38 +     *  Check that all the types are references.
    3.39 +     */
    3.40 +    List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) {
    3.41 +        List<Type> types = attribAnyTypes(trees, env);
    3.42 +        return chk.checkRefTypes(trees, types);
    3.43 +    }
    3.44  
    3.45      /**
    3.46       * Attribute type variables (of generic classes or methods).
    3.47 @@ -1194,6 +1207,7 @@
    3.48  
    3.49          // The types of the actual method type arguments.
    3.50          List<Type> typeargtypes = null;
    3.51 +        boolean typeargtypesNonRefOK = false;
    3.52  
    3.53          Name methName = TreeInfo.name(tree.meth);
    3.54  
    3.55 @@ -1281,7 +1295,7 @@
    3.56              // Otherwise, we are seeing a regular method call.
    3.57              // Attribute the arguments, yielding list of argument types, ...
    3.58              argtypes = attribArgs(tree.args, localEnv);
    3.59 -            typeargtypes = attribTypes(tree.typeargs, localEnv);
    3.60 +            typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
    3.61  
    3.62              // ... and attribute the method using as a prototype a methodtype
    3.63              // whose formal argument types is exactly the list of actual
    3.64 @@ -1318,6 +1332,20 @@
    3.65                                restype.tsym);
    3.66              }
    3.67  
    3.68 +            // as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
    3.69 +            // has type <T>, and T can be a primitive type.
    3.70 +            if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
    3.71 +              Type selt = ((JCFieldAccess) tree.meth).selected.type;
    3.72 +              if ((selt == syms.methodHandleType && methName == names.invoke) || selt == syms.invokeDynamicType) {
    3.73 +                  assert types.isSameType(restype, typeargtypes.head) : mtype;
    3.74 +                  typeargtypesNonRefOK = true;
    3.75 +              }
    3.76 +            }
    3.77 +
    3.78 +            if (!typeargtypesNonRefOK) {
    3.79 +                chk.checkRefTypes(tree.typeargs, typeargtypes);
    3.80 +            }
    3.81 +
    3.82              // Check that value of resulting type is admissible in the
    3.83              // current context.  Also, capture the return type
    3.84              result = check(tree, capture(restype), VAL, pkind, pt);
     4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Apr 30 15:04:50 2009 -0700
     4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon May 04 22:16:46 2009 -0700
     4.3 @@ -207,6 +207,12 @@
     4.4       *  @param found      The type that was found.
     4.5       */
     4.6      Type typeTagError(DiagnosticPosition pos, Object required, Object found) {
     4.7 +        // this error used to be raised by the parser,
     4.8 +        // but has been delayed to this point:
     4.9 +        if (found instanceof Type && ((Type)found).tag == VOID) {
    4.10 +            log.error(pos, "illegal.start.of.type");
    4.11 +            return syms.errType;
    4.12 +        }
    4.13          log.error(pos, "type.found.req", found, required);
    4.14          return types.createErrorType(found instanceof Type ? (Type)found : syms.errType);
    4.15      }
    4.16 @@ -547,6 +553,20 @@
    4.17          }
    4.18      }
    4.19  
    4.20 +    /** Check that each type is a reference type, i.e. a class, interface or array type
    4.21 +     *  or a type variable.
    4.22 +     *  @param trees         Original trees, used for error reporting.
    4.23 +     *  @param types         The types to be checked.
    4.24 +     */
    4.25 +    List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
    4.26 +        List<JCExpression> tl = trees;
    4.27 +        for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
    4.28 +            l.head = checkRefType(tl.head.pos(), l.head);
    4.29 +            tl = tl.tail;
    4.30 +        }
    4.31 +        return types;
    4.32 +    }
    4.33 +
    4.34      /** Check that type is a null or reference type.
    4.35       *  @param pos           Position to be used for error reporting.
    4.36       *  @param t             The type to be checked.
     5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Apr 30 15:04:50 2009 -0700
     5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon May 04 22:16:46 2009 -0700
     5.3 @@ -67,6 +67,7 @@
     5.4      JCDiagnostic.Factory diags;
     5.5      public final boolean boxingEnabled; // = source.allowBoxing();
     5.6      public final boolean varargsEnabled; // = source.allowVarargs();
     5.7 +    public final boolean allowInvokedynamic; // = options.get("invokedynamic");
     5.8      private final boolean debugResolve;
     5.9  
    5.10      public static Resolve instance(Context context) {
    5.11 @@ -104,6 +105,7 @@
    5.12          varargsEnabled = source.allowVarargs();
    5.13          Options options = Options.instance(context);
    5.14          debugResolve = options.get("debugresolve") != null;
    5.15 +        allowInvokedynamic = options.get("invokedynamic") != null;
    5.16      }
    5.17  
    5.18      /** error symbols, which are returned when resolution fails
    5.19 @@ -881,6 +883,79 @@
    5.20          return bestSoFar;
    5.21      }
    5.22  
    5.23 +    /** Find or create an implicit method of exactly the given type (after erasure).
    5.24 +     *  Searches in a side table, not the main scope of the site.
    5.25 +     *  This emulates the lookup process required by JSR 292 in JVM.
    5.26 +     *  @param env       The current environment.
    5.27 +     *  @param site      The original type from where the selection
    5.28 +     *                   takes place.
    5.29 +     *  @param name      The method's name.
    5.30 +     *  @param argtypes  The method's value arguments.
    5.31 +     *  @param typeargtypes The method's type arguments
    5.32 +     */
    5.33 +    Symbol findImplicitMethod(Env<AttrContext> env,
    5.34 +                              Type site,
    5.35 +                              Name name,
    5.36 +                              List<Type> argtypes,
    5.37 +                              List<Type> typeargtypes) {
    5.38 +        assert allowInvokedynamic;
    5.39 +        assert site == syms.invokeDynamicType || (site == syms.methodHandleType && name == names.invoke);
    5.40 +        ClassSymbol c = (ClassSymbol) site.tsym;
    5.41 +        Scope implicit = c.members().next;
    5.42 +        if (implicit == null) {
    5.43 +            c.members().next = implicit = new Scope(c);
    5.44 +        }
    5.45 +        Type restype;
    5.46 +        if (typeargtypes.isEmpty()) {
    5.47 +            restype = syms.objectType;
    5.48 +        } else {
    5.49 +            restype = typeargtypes.head;
    5.50 +            if (!typeargtypes.tail.isEmpty())
    5.51 +                return methodNotFound;
    5.52 +        }
    5.53 +        List<Type> paramtypes = Type.map(argtypes, implicitArgType);
    5.54 +        MethodType mtype = new MethodType(paramtypes,
    5.55 +                                          restype,
    5.56 +                                          List.<Type>nil(),
    5.57 +                                          syms.methodClass);
    5.58 +        int flags = PUBLIC | ABSTRACT;
    5.59 +        if (site == syms.invokeDynamicType)  flags |= STATIC;
    5.60 +        Symbol m = null;
    5.61 +        for (Scope.Entry e = implicit.lookup(name);
    5.62 +             e.scope != null;
    5.63 +             e = e.next()) {
    5.64 +            Symbol sym = e.sym;
    5.65 +            assert sym.kind == MTH;
    5.66 +            if (types.isSameType(mtype, sym.type)
    5.67 +                && (sym.flags() & STATIC) == (flags & STATIC)) {
    5.68 +                m = sym;
    5.69 +                break;
    5.70 +            }
    5.71 +        }
    5.72 +        if (m == null) {
    5.73 +            // create the desired method
    5.74 +            m = new MethodSymbol(flags, name, mtype, c);
    5.75 +            implicit.enter(m);
    5.76 +        }
    5.77 +        assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(),
    5.78 +                                   false, false, Warner.noWarnings);
    5.79 +        assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings);
    5.80 +        return m;
    5.81 +    }
    5.82 +    //where
    5.83 +        Mapping implicitArgType = new Mapping ("implicitArgType") {
    5.84 +                public Type apply(Type t) { return implicitArgType(t); }
    5.85 +            };
    5.86 +        Type implicitArgType(Type argType) {
    5.87 +            argType = types.erasure(argType);
    5.88 +            if (argType.tag == BOT)
    5.89 +                // nulls type as the marker type Null (which has no instances)
    5.90 +                // TO DO: figure out how to access java.lang.Null safely, else throw nice error
    5.91 +                //argType = types.boxedClass(syms.botType).type;
    5.92 +                argType = types.boxedClass(syms.voidType).type;  // REMOVE
    5.93 +            return argType;
    5.94 +        }
    5.95 +
    5.96      /** Load toplevel or member class with given fully qualified name and
    5.97       *  verify that it is accessible.
    5.98       *  @param env       The current environment.
    5.99 @@ -1265,6 +1340,14 @@
   5.100              methodResolutionCache.put(steps.head, sym);
   5.101              steps = steps.tail;
   5.102          }
   5.103 +        if (sym.kind >= AMBIGUOUS &&
   5.104 +            allowInvokedynamic &&
   5.105 +            (site == syms.invokeDynamicType ||
   5.106 +             site == syms.methodHandleType && name == names.invoke)) {
   5.107 +            // lookup failed; supply an exactly-typed implicit method
   5.108 +            sym = findImplicitMethod(env, site, name, argtypes, typeargtypes);
   5.109 +            env.info.varArgs = false;
   5.110 +        }
   5.111          if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
   5.112              MethodResolutionPhase errPhase =
   5.113                      firstErroneousResolutionPhase();
     6.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ByteCodes.java	Thu Apr 30 15:04:50 2009 -0700
     6.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ByteCodes.java	Mon May 04 22:16:46 2009 -0700
     6.3 @@ -225,7 +225,7 @@
     6.4          invokespecial   = 183,
     6.5          invokestatic    = 184,
     6.6          invokeinterface = 185,
     6.7 -        // ___unused___ = 186,
     6.8 +        invokedynamic   = 186,
     6.9          new_            = 187,
    6.10          newarray        = 188,
    6.11          anewarray       = 189,
     7.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Apr 30 15:04:50 2009 -0700
     7.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon May 04 22:16:46 2009 -0700
     7.3 @@ -2309,6 +2309,7 @@
     7.4                      String binaryName = fileManager.inferBinaryName(currentLoc, fo);
     7.5                      String simpleName = binaryName.substring(binaryName.lastIndexOf(".") + 1);
     7.6                      if (SourceVersion.isIdentifier(simpleName) ||
     7.7 +                        fo.getKind() == JavaFileObject.Kind.CLASS ||
     7.8                          simpleName.equals("package-info"))
     7.9                          includeClassFile(p, fo);
    7.10                      break;
     8.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Thu Apr 30 15:04:50 2009 -0700
     8.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Mon May 04 22:16:46 2009 -0700
     8.3 @@ -456,6 +456,19 @@
     8.4          state.push(mtype.getReturnType());
     8.5      }
     8.6  
     8.7 +    /** Emit an invokedynamic instruction.
     8.8 +     */
     8.9 +    public void emitInvokedynamic(int desc, Type mtype) {
    8.10 +        // N.B. this format is under consideration by the JSR 292 EG
    8.11 +        int argsize = width(mtype.getParameterTypes());
    8.12 +        emitop(invokedynamic);
    8.13 +        if (!alive) return;
    8.14 +        emit2(desc);
    8.15 +        emit2(0);
    8.16 +        state.pop(argsize);
    8.17 +        state.push(mtype.getReturnType());
    8.18 +    }
    8.19 +
    8.20      /** Emit an opcode with no operand field.
    8.21       */
    8.22      public void emitop0(int op) {
    8.23 @@ -2156,7 +2169,7 @@
    8.24              mnem[invokespecial] = "invokespecial";
    8.25              mnem[invokestatic] = "invokestatic";
    8.26              mnem[invokeinterface] = "invokeinterface";
    8.27 -            // mnem[___unused___] = "___unused___";
    8.28 +            mnem[invokedynamic] = "invokedynamic";
    8.29              mnem[new_] = "new_";
    8.30              mnem[newarray] = "newarray";
    8.31              mnem[anewarray] = "anewarray";
     9.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Apr 30 15:04:50 2009 -0700
     9.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon May 04 22:16:46 2009 -0700
     9.3 @@ -119,6 +119,7 @@
     9.4              : options.get("-g:vars") != null;
     9.5          genCrt = options.get("-Xjcov") != null;
     9.6          debugCode = options.get("debugcode") != null;
     9.7 +        allowInvokedynamic = options.get("invokedynamic") != null;
     9.8  
     9.9          generateIproxies =
    9.10              target.requiresIproxy() ||
    9.11 @@ -155,6 +156,7 @@
    9.12      private final boolean varDebugInfo;
    9.13      private final boolean genCrt;
    9.14      private final boolean debugCode;
    9.15 +    private final boolean allowInvokedynamic;
    9.16  
    9.17      /** Default limit of (approximate) size of finalizer to inline.
    9.18       *  Zero means always use jsr.  100 or greater means never use
    9.19 @@ -2140,6 +2142,9 @@
    9.20              }
    9.21              result = items.
    9.22                  makeImmediateItem(sym.type, ((VarSymbol) sym).getConstValue());
    9.23 +        } else if (allowInvokedynamic && sym.kind == MTH && ssym == syms.invokeDynamicType.tsym) {
    9.24 +            base.drop();
    9.25 +            result = items.makeDynamicItem(sym);
    9.26          } else {
    9.27              if (!accessSuper)
    9.28                  sym = binaryQualifier(sym, tree.selected.type);
    10.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Items.java	Thu Apr 30 15:04:50 2009 -0700
    10.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Items.java	Mon May 04 22:16:46 2009 -0700
    10.3 @@ -139,6 +139,13 @@
    10.4          return new StaticItem(member);
    10.5      }
    10.6  
    10.7 +    /** Make an item representing a dynamically invoked method.
    10.8 +     *  @param member   The represented symbol.
    10.9 +     */
   10.10 +    Item makeDynamicItem(Symbol member) {
   10.11 +        return new DynamicItem(member);
   10.12 +    }
   10.13 +
   10.14      /** Make an item representing an instance variable or method.
   10.15       *  @param member       The represented symbol.
   10.16       *  @param nonvirtual   Is the reference not virtual? (true for constructors
   10.17 @@ -457,6 +464,38 @@
   10.18          }
   10.19      }
   10.20  
   10.21 +    /** An item representing a dynamic call site.
   10.22 +     */
   10.23 +    class DynamicItem extends StaticItem {
   10.24 +        DynamicItem(Symbol member) {
   10.25 +            super(member);
   10.26 +            assert member.owner == syms.invokeDynamicType.tsym;
   10.27 +        }
   10.28 +
   10.29 +        Item load() {
   10.30 +            assert false;
   10.31 +            return null;
   10.32 +        }
   10.33 +
   10.34 +        void store() {
   10.35 +            assert false;
   10.36 +        }
   10.37 +
   10.38 +        Item invoke() {
   10.39 +            // assert target.hasNativeInvokeDynamic();
   10.40 +            MethodType mtype = (MethodType)member.erasure(types);
   10.41 +            int rescode = Code.typecode(mtype.restype);
   10.42 +            ClassFile.NameAndType descr = new ClassFile.NameAndType(member.name, mtype);
   10.43 +            code.emitInvokedynamic(pool.put(descr), mtype);
   10.44 +            return stackItem[rescode];
   10.45 +        }
   10.46 +
   10.47 +        public String toString() {
   10.48 +            return "dynamic(" + member + ")";
   10.49 +        }
   10.50 +    }
   10.51 +
   10.52 +
   10.53      /** An item representing an instance variable or method.
   10.54       */
   10.55      class MemberItem extends Item {
    11.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Target.java	Thu Apr 30 15:04:50 2009 -0700
    11.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java	Mon May 04 22:16:46 2009 -0700
    11.3 @@ -253,6 +253,12 @@
    11.4          return compareTo(JDK1_5) >= 0;
    11.5      }
    11.6  
    11.7 +    /** Does the VM support an invokedynamic instruction?
    11.8 +     */
    11.9 +    public boolean hasInvokedynamic() {
   11.10 +        return compareTo(JDK1_7) >= 0;
   11.11 +    }
   11.12 +
   11.13      /** Although we may not have support for class literals, should we
   11.14       *  avoid initializing the class that the literal refers to?
   11.15       *  See 4468823
    12.1 --- a/src/share/classes/com/sun/tools/javac/main/Main.java	Thu Apr 30 15:04:50 2009 -0700
    12.2 +++ b/src/share/classes/com/sun/tools/javac/main/Main.java	Mon May 04 22:16:46 2009 -0700
    12.3 @@ -268,14 +268,19 @@
    12.4                      }
    12.5                      return null;
    12.6                  } else {
    12.7 -                    options.put("-target", source.requiredTarget().name);
    12.8 +                    target = source.requiredTarget();
    12.9 +                    options.put("-target", target.name);
   12.10                  }
   12.11              } else {
   12.12                  if (targetString == null && !source.allowGenerics()) {
   12.13 -                    options.put("-target", Target.JDK1_4.name);
   12.14 +                    target = Target.JDK1_4;
   12.15 +                    options.put("-target", target.name);
   12.16                  }
   12.17              }
   12.18          }
   12.19 +        if (target.hasInvokedynamic()) {
   12.20 +            options.put("invokedynamic",  "invokedynamic");
   12.21 +        }
   12.22          return filenames.toList();
   12.23      }
   12.24      // where
    13.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Apr 30 15:04:50 2009 -0700
    13.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon May 04 22:16:46 2009 -0700
    13.3 @@ -1034,7 +1034,13 @@
    13.4                      return illegal(pos);
    13.5                  }
    13.6              } else {
    13.7 -                return illegal();
    13.8 +                // Support the corner case of myMethodHandle.<void>invoke() by passing
    13.9 +                // a void type (like other primitive types) to the next phase.
   13.10 +                // The error will be reported in Attr.attribTypes or Attr.visitApply.
   13.11 +                JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID));
   13.12 +                S.nextToken();
   13.13 +                return ti;
   13.14 +                //return illegal();
   13.15              }
   13.16              break;
   13.17          default:
    14.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Thu Apr 30 15:04:50 2009 -0700
    14.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Mon May 04 22:16:46 2009 -0700
    14.3 @@ -317,7 +317,7 @@
    14.4  
    14.5      /** Read next character in character or string literal and copy into sbuf.
    14.6       */
    14.7 -    private void scanLitChar() {
    14.8 +    private void scanLitChar(boolean forBytecodeName) {
    14.9          if (ch == '\\') {
   14.10              if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
   14.11                  bp++;
   14.12 @@ -357,6 +357,18 @@
   14.13                      putChar('\"'); scanChar(); break;
   14.14                  case '\\':
   14.15                      putChar('\\'); scanChar(); break;
   14.16 +                case '|': case ',': case '?': case '%':
   14.17 +                case '^': case '_': case '{': case '}':
   14.18 +                case '!': case '-': case '=':
   14.19 +                    if (forBytecodeName) {
   14.20 +                        // Accept escape sequences for dangerous bytecode chars.
   14.21 +                        // This is illegal in normal Java string or character literals.
   14.22 +                        // Note that the escape sequence itself is passed through.
   14.23 +                        putChar('\\'); putChar(ch); scanChar();
   14.24 +                    } else {
   14.25 +                        lexError(bp, "illegal.esc.char");
   14.26 +                    }
   14.27 +                    break;
   14.28                  default:
   14.29                      lexError(bp, "illegal.esc.char");
   14.30                  }
   14.31 @@ -365,6 +377,24 @@
   14.32              putChar(ch); scanChar();
   14.33          }
   14.34      }
   14.35 +    private void scanLitChar() {
   14.36 +        scanLitChar(false);
   14.37 +    }
   14.38 +
   14.39 +    /** Read next character in an exotic name #"foo"
   14.40 +     */
   14.41 +    private void scanBytecodeNameChar() {
   14.42 +        switch (ch) {
   14.43 +        // reject any "dangerous" char which is illegal somewhere in the JVM spec
   14.44 +        // cf. http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm
   14.45 +        case '/': case '.': case ';':  // illegal everywhere
   14.46 +        case '<': case '>':  // illegal in methods, dangerous in classes
   14.47 +        case '[':  // illegal in classes
   14.48 +            lexError(bp, "illegal.bytecode.ident.char", String.valueOf((int)ch));
   14.49 +            break;
   14.50 +        }
   14.51 +        scanLitChar(true);
   14.52 +    }
   14.53  
   14.54      /** Read fractional part of hexadecimal floating point number.
   14.55       */
   14.56 @@ -915,6 +945,26 @@
   14.57                          lexError(pos, "unclosed.str.lit");
   14.58                      }
   14.59                      return;
   14.60 +                case '#':
   14.61 +                    scanChar();
   14.62 +                    if (ch == '\"') {
   14.63 +                        scanChar();
   14.64 +                        if (ch == '\"')
   14.65 +                            lexError(pos, "empty.bytecode.ident");
   14.66 +                        while (ch != '\"' && ch != CR && ch != LF && bp < buflen) {
   14.67 +                            scanBytecodeNameChar();
   14.68 +                        }
   14.69 +                        if (ch == '\"') {
   14.70 +                            name = names.fromChars(sbuf, 0, sp);
   14.71 +                            token = IDENTIFIER;  // even if #"int" or #"do"
   14.72 +                            scanChar();
   14.73 +                        } else {
   14.74 +                            lexError(pos, "unclosed.bytecode.ident");
   14.75 +                        }
   14.76 +                    } else {
   14.77 +                        lexError("illegal.char", String.valueOf((int)'#'));
   14.78 +                    }
   14.79 +                    return;
   14.80                  default:
   14.81                      if (isSpecial(ch)) {
   14.82                          scanOperator();
    15.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Apr 30 15:04:50 2009 -0700
    15.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon May 04 22:16:46 2009 -0700
    15.3 @@ -144,6 +144,8 @@
    15.4  
    15.5  compiler.err.else.without.if=\
    15.6      ''else'' without ''if''
    15.7 +compiler.err.empty.bytecode.ident=\
    15.8 +    empty bytecode identifier
    15.9  compiler.err.empty.char.lit=\
   15.10      empty character literal
   15.11  compiler.err.encl.class.required=\
   15.12 @@ -186,6 +188,8 @@
   15.13  
   15.14  compiler.err.icls.cant.have.static.decl=\
   15.15      inner classes cannot have static declarations
   15.16 +compiler.err.illegal.bytecode.ident.char=\
   15.17 +    illegal bytecode identifier character: \\{0}
   15.18  compiler.err.illegal.char=\
   15.19      illegal character: \\{0}
   15.20  compiler.err.illegal.char.for.encoding=\
   15.21 @@ -445,6 +449,8 @@
   15.22  compiler.err.types.incompatible.diff.ret=\
   15.23      types {0} and {1} are incompatible; both define {2}, but with unrelated return types
   15.24  
   15.25 +compiler.err.unclosed.bytecode.ident=\
   15.26 +    unclosed bytecode identifier
   15.27  compiler.err.unclosed.char.lit=\
   15.28      unclosed character literal
   15.29  compiler.err.unclosed.comment=\
    16.1 --- a/src/share/classes/com/sun/tools/javac/util/Names.java	Thu Apr 30 15:04:50 2009 -0700
    16.2 +++ b/src/share/classes/com/sun/tools/javac/util/Names.java	Mon May 04 22:16:46 2009 -0700
    16.3 @@ -73,6 +73,8 @@
    16.4      public final Name java_io_Serializable;
    16.5      public final Name serialVersionUID;
    16.6      public final Name java_lang_Enum;
    16.7 +    public final Name java_dyn_MethodHandle;
    16.8 +    public final Name java_dyn_InvokeDynamic;
    16.9      public final Name package_info;
   16.10      public final Name ConstantValue;
   16.11      public final Name LineNumberTable;
   16.12 @@ -111,6 +113,7 @@
   16.13      public final Name value;
   16.14      public final Name getMessage;
   16.15      public final Name getClass;
   16.16 +    public final Name invoke;
   16.17      public final Name TYPE;
   16.18      public final Name FIELD;
   16.19      public final Name METHOD;
   16.20 @@ -175,6 +178,8 @@
   16.21          java_lang_Cloneable = fromString("java.lang.Cloneable");
   16.22          java_io_Serializable = fromString("java.io.Serializable");
   16.23          java_lang_Enum = fromString("java.lang.Enum");
   16.24 +        java_dyn_MethodHandle = fromString("java.dyn.MethodHandle");
   16.25 +        java_dyn_InvokeDynamic = fromString("java.dyn.InvokeDynamic");
   16.26          package_info = fromString("package-info");
   16.27          serialVersionUID = fromString("serialVersionUID");
   16.28          ConstantValue = fromString("ConstantValue");
   16.29 @@ -216,6 +221,7 @@
   16.30          value = fromString("value");
   16.31          getMessage = fromString("getMessage");
   16.32          getClass = fromString("getClass");
   16.33 +        invoke = fromString("invoke");
   16.34  
   16.35          TYPE = fromString("TYPE");
   16.36          FIELD = fromString("FIELD");
    17.1 --- a/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Thu Apr 30 15:04:50 2009 -0700
    17.2 +++ b/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Mon May 04 22:16:46 2009 -0700
    17.3 @@ -339,7 +339,7 @@
    17.4              cp = name.codePointAt(k);
    17.5              if ((cc == '/' && !Character.isJavaIdentifierStart(cp))
    17.6                      || (cp != '/' && !Character.isJavaIdentifierPart(cp))) {
    17.7 -                return "\"" + name + "\"";
    17.8 +                return "\"" + addEscapes(name) + "\"";
    17.9              }
   17.10              cc = cp;
   17.11          }
   17.12 @@ -347,6 +347,33 @@
   17.13          return name;
   17.14      }
   17.15  
   17.16 +    /* If name requires escapes, put them in, so it can be a string body. */
   17.17 +    private static String addEscapes(String name) {
   17.18 +        String esc = "\\\"\n\t";
   17.19 +        String rep = "\\\"nt";
   17.20 +        StringBuilder buf = null;
   17.21 +        int nextk = 0;
   17.22 +        int len = name.length();
   17.23 +        for (int k = 0; k < len; k++) {
   17.24 +            char cp = name.charAt(k);
   17.25 +            int n = esc.indexOf(cp);
   17.26 +            if (n >= 0) {
   17.27 +                if (buf == null)
   17.28 +                    buf = new StringBuilder(len * 2);
   17.29 +                if (nextk < k)
   17.30 +                    buf.append(name, nextk, k);
   17.31 +                buf.append('\\');
   17.32 +                buf.append(rep.charAt(n));
   17.33 +                nextk = k+1;
   17.34 +            }
   17.35 +        }
   17.36 +        if (buf == null)
   17.37 +            return name;
   17.38 +        if (nextk < len)
   17.39 +            buf.append(name, nextk, len);
   17.40 +        return buf.toString();
   17.41 +    }
   17.42 +
   17.43      private ClassWriter classWriter;
   17.44      private Options options;
   17.45  }
    18.1 --- a/src/share/classes/sun/tools/javap/JavapPrinter.java	Thu Apr 30 15:04:50 2009 -0700
    18.2 +++ b/src/share/classes/sun/tools/javap/JavapPrinter.java	Mon May 04 22:16:46 2009 -0700
    18.3 @@ -475,6 +475,13 @@
    18.4              return 5;
    18.5          }
    18.6  
    18.7 +        case opc_invokedynamic: {
    18.8 +            int index = getUShort(pc+1);
    18.9 +            out.print("\t#"+index+"; //");
   18.10 +            PrintConstant(index);
   18.11 +            return 5;
   18.12 +        }
   18.13 +
   18.14          case opc_multianewarray: {
   18.15              int index = getUShort(pc+1), dimensions=getUbyte(pc+3);
   18.16              out.print("\t#"+index+",  "+dimensions+"; //");
    19.1 --- a/src/share/classes/sun/tools/javap/RuntimeConstants.java	Thu Apr 30 15:04:50 2009 -0700
    19.2 +++ b/src/share/classes/sun/tools/javap/RuntimeConstants.java	Mon May 04 22:16:46 2009 -0700
    19.3 @@ -318,7 +318,7 @@
    19.4      public static final int opc_invokespecial            = 183;
    19.5      public static final int opc_invokestatic             = 184;
    19.6      public static final int opc_invokeinterface          = 185;
    19.7 -//    public static final int opc_xxxunusedxxx             = 186;
    19.8 +    public static final int opc_invokedynamic            = 186;
    19.9      public static final int opc_new                      = 187;
   19.10      public static final int opc_newarray                 = 188;
   19.11      public static final int opc_anewarray                = 189;
   19.12 @@ -549,7 +549,7 @@
   19.13          "invokespecial", //     was "invokenonvirtual",
   19.14          "invokestatic",
   19.15          "invokeinterface",
   19.16 -        "bytecode 186", //"xxxunusedxxx",
   19.17 +        "invokedynamic",
   19.18          "new",
   19.19          "newarray",
   19.20          "anewarray",
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/tools/javac/meth/InvokeDyn.java	Mon May 04 22:16:46 2009 -0700
    20.3 @@ -0,0 +1,59 @@
    20.4 +/*
    20.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.
   20.11 + *
   20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.15 + * version 2 for more details (a copy is included in the LICENSE file that
   20.16 + * accompanied this code).
   20.17 + *
   20.18 + * You should have received a copy of the GNU General Public License version
   20.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.21 + *
   20.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   20.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   20.24 + * have any questions.
   20.25 + */
   20.26 +
   20.27 +/*
   20.28 + * @test
   20.29 + * @bug 6754038
   20.30 + * @summary Generate call sites for method handle
   20.31 + * @author jrose
   20.32 + *
   20.33 + * @library ..
   20.34 + * @compile -source 7 -target 7 InvokeDyn.java
   20.35 + */
   20.36 +//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
   20.37 +
   20.38 +/*
   20.39 + * Standalone testing:
   20.40 + * <code>
   20.41 + * $ cd $MY_REPO_DIR/langtools
   20.42 + * $ (cd make; make)
   20.43 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java
   20.44 + * $ javap -c -classpath dist meth.InvokeDyn
   20.45 + * </code>
   20.46 + */
   20.47 +
   20.48 +package meth;
   20.49 +
   20.50 +import java.dyn.InvokeDynamic;
   20.51 +
   20.52 +public class InvokeDyn {
   20.53 +    void test() {
   20.54 +        Object x = "hello";
   20.55 +        InvokeDynamic.greet(x, "world", 123);
   20.56 +        InvokeDynamic.greet(x, "mundus", 456);
   20.57 +        InvokeDynamic.greet(x, "kosmos", 789);
   20.58 +        InvokeDynamic.<String>cogitate(10.11121, 3.14);
   20.59 +        InvokeDynamic.<void>#"yow: what I mean to say is, please treat this one specially"(null);
   20.60 +        InvokeDynamic.<int>invoke("goodbye");
   20.61 +    }
   20.62 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/tools/javac/meth/InvokeMH.java	Mon May 04 22:16:46 2009 -0700
    21.3 @@ -0,0 +1,75 @@
    21.4 +/*
    21.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.7 + *
    21.8 + * This code is free software; you can redistribute it and/or modify it
    21.9 + * under the terms of the GNU General Public License version 2 only, as
   21.10 + * published by the Free Software Foundation.
   21.11 + *
   21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   21.15 + * version 2 for more details (a copy is included in the LICENSE file that
   21.16 + * accompanied this code).
   21.17 + *
   21.18 + * You should have received a copy of the GNU General Public License version
   21.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   21.21 + *
   21.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   21.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   21.24 + * have any questions.
   21.25 + */
   21.26 +
   21.27 +/*
   21.28 + * @test
   21.29 + * @bug 6754038
   21.30 + * @summary Generate call sites for method handle
   21.31 + * @author jrose
   21.32 + *
   21.33 + * @compile -source 7 -target 7 InvokeMH.java
   21.34 + */
   21.35 +
   21.36 +/*
   21.37 + * Standalone testing:
   21.38 + * <code>
   21.39 + * $ cd $MY_REPO_DIR/langtools
   21.40 + * $ (cd make; make)
   21.41 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeMH.java
   21.42 + * $ javap -c -classpath dist meth.InvokeMH
   21.43 + * </code>
   21.44 + */
   21.45 +
   21.46 +package meth;
   21.47 +
   21.48 +import java.dyn.MethodHandle;
   21.49 +
   21.50 +public class InvokeMH {
   21.51 +    void test(MethodHandle mh_SiO,
   21.52 +              MethodHandle mh_vS,
   21.53 +              MethodHandle mh_vi,
   21.54 +              MethodHandle mh_vv) {
   21.55 +        Object o; String s; int i;  // for return type testing
   21.56 +
   21.57 +        // next five must have sig = (String,int)Object
   21.58 +        mh_SiO.invoke("world", 123);
   21.59 +        mh_SiO.invoke("mundus", 456);
   21.60 +        Object k = "kosmos";
   21.61 +        mh_SiO.invoke((String)k, 789);
   21.62 +        o = mh_SiO.invoke((String)null, 000);
   21.63 +        o = mh_SiO.<Object>invoke("arda", -123);
   21.64 +
   21.65 +        // sig = ()String
   21.66 +        s = mh_vS.<String>invoke();
   21.67 +
   21.68 +        // sig = ()int
   21.69 +        i = mh_vi.<int>invoke();
   21.70 +        o = mh_vi.<int>invoke();
   21.71 +        //s = mh_vi.<int>invoke(); //BAD
   21.72 +        mh_vi.<int>invoke();
   21.73 +
   21.74 +        // sig = ()void
   21.75 +        //o = mh_vv.<void>invoke(); //BAD
   21.76 +        mh_vv.<void>invoke();
   21.77 +    }
   21.78 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/test/tools/javac/meth/MakeNegTests.sh	Mon May 04 22:16:46 2009 -0700
    22.3 @@ -0,0 +1,98 @@
    22.4 +#!/bin/sh
    22.5 +
    22.6 +#
    22.7 +# Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    22.8 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.9 +#
   22.10 +# This code is free software; you can redistribute it and/or modify it
   22.11 +# under the terms of the GNU General Public License version 2 only, as
   22.12 +# published by the Free Software Foundation.
   22.13 +#
   22.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
   22.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.17 +# version 2 for more details (a copy is included in the LICENSE file that
   22.18 +# accompanied this code).
   22.19 +#
   22.20 +# You should have received a copy of the GNU General Public License version
   22.21 +# 2 along with this work; if not, write to the Free Software Foundation,
   22.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.23 +#
   22.24 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22.25 +# CA 95054 USA or visit www.sun.com if you need additional information or
   22.26 +# have any questions.
   22.27 +#
   22.28 +
   22.29 +# @test
   22.30 +# @bug 6754038
   22.31 +# @summary Verify correct rejection of strongly typed return values
   22.32 +# @run shell MakeNegTests.sh
   22.33 +
   22.34 +default_template=InvokeMH.java
   22.35 +javacflags='-source 7 -target 7'
   22.36 +# the rest of this file is a generic "//BAD"-line tester
   22.37 +
   22.38 +: ${TESTSRC=.} ${TESTCLASSES=.}
   22.39 +javac="${TESTJAVA+${TESTJAVA}/bin/}javac"
   22.40 +
   22.41 +verbose=false quiet=false
   22.42 +
   22.43 +main() {
   22.44 +  case "${@-}" in
   22.45 +  *.java*)
   22.46 +    for template in "$@"; do
   22.47 +      expand_and_test "$template"
   22.48 +    done;;
   22.49 +  *) expand_and_test "${TESTSRC}/$default_template";;
   22.50 +  esac
   22.51 +}
   22.52 +
   22.53 +expand_and_test() {
   22.54 +  template=$1
   22.55 +  expand "$@"
   22.56 +  testneg "$@"
   22.57 +}
   22.58 +
   22.59 +expand() {
   22.60 +  template=$1
   22.61 +  badlines=` grep -n < "$template" '//BAD' `
   22.62 +  badcount=` echo "$badlines" | wc -l `
   22.63 +  [ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; }
   22.64 +  $quiet || echo "Expanding $badcount negative test cases from $template:"
   22.65 +  $quiet || echo "$badlines"
   22.66 +  badnums=` echo "$badlines" | sed 's/:.*//' `
   22.67 +  casestem=` getcasestem "$template" `
   22.68 +  tclassname=` basename "$template" .java `
   22.69 +  rm -f "$casestem"*.java
   22.70 +  for badnum in $badnums; do
   22.71 +    casefile="$casestem"${badnum}.java
   22.72 +    cclassname=` basename "$casefile" .java `
   22.73 +    sed < "$template" > "$casefile" "
   22.74 +      s|@compile|@compile/fail|
   22.75 +      / @[a-z]/s|@|##|
   22.76 +      ${badnum}s:^ *[/*]*:    :
   22.77 +      s/${tclassname}/${cclassname}/g
   22.78 +    "
   22.79 +    $verbose && diff -u "$template" "$casefile"
   22.80 +  done
   22.81 +}
   22.82 +
   22.83 +getcasestem() {
   22.84 +  echo "$1" | sed 's/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/'
   22.85 +}
   22.86 +
   22.87 +testneg() {
   22.88 +  template=$1
   22.89 +  for casefile in ` getcasestem "$template" `*.java; do
   22.90 +    $quiet || echo -------- $javac $javacflags "$casefile"
   22.91 +    $javac $javacflags "$casefile" > "$casefile".errlog 2>&1 && {
   22.92 +      echo "*** Compilation unexpectedly succeeded:  $casefile"
   22.93 +      exit 1
   22.94 +    }
   22.95 +    $quiet || echo "Compilation failed as expected"
   22.96 +    $quiet || head ` $verbose || echo -3 ` < "$casefile".errlog
   22.97 +    rm "$casefile".errlog
   22.98 +  done
   22.99 +}
  22.100 +
  22.101 +main "$@"
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/test/tools/javac/quid/MakeNegTests.sh	Mon May 04 22:16:46 2009 -0700
    23.3 @@ -0,0 +1,97 @@
    23.4 +#!/bin/sh
    23.5 +
    23.6 +#
    23.7 +# Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    23.8 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.9 +#
   23.10 +# This code is free software; you can redistribute it and/or modify it
   23.11 +# under the terms of the GNU General Public License version 2 only, as
   23.12 +# published by the Free Software Foundation.
   23.13 +#
   23.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
   23.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   23.17 +# version 2 for more details (a copy is included in the LICENSE file that
   23.18 +# accompanied this code).
   23.19 +#
   23.20 +# You should have received a copy of the GNU General Public License version
   23.21 +# 2 along with this work; if not, write to the Free Software Foundation,
   23.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   23.23 +#
   23.24 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   23.25 +# CA 95054 USA or visit www.sun.com if you need additional information or
   23.26 +# have any questions.
   23.27 +#
   23.28 +
   23.29 +# @test
   23.30 +# @bug 6746458
   23.31 +# @summary Verify correct rejection of illegal quoted identifiers.
   23.32 +# @run shell MakeNegTests.sh
   23.33 +
   23.34 +default_template=QuotedIdent.java
   23.35 +# the rest of this file is a generic "//BAD"-line tester
   23.36 +
   23.37 +: ${TESTSRC=.} ${TESTCLASSES=.}
   23.38 +javac="${TESTJAVA+${TESTJAVA}/bin/}javac"
   23.39 +
   23.40 +verbose=false quiet=false
   23.41 +
   23.42 +main() {
   23.43 +  case "${@-}" in
   23.44 +  *.java*)
   23.45 +    for template in "$@"; do
   23.46 +      expand_and_test "$template"
   23.47 +    done;;
   23.48 +  *) expand_and_test "${TESTSRC}/$default_template";;
   23.49 +  esac
   23.50 +}
   23.51 +
   23.52 +expand_and_test() {
   23.53 +  template=$1
   23.54 +  expand "$@"
   23.55 +  testneg "$@"
   23.56 +}
   23.57 +
   23.58 +expand() {
   23.59 +  template=$1
   23.60 +  badlines=` grep -n < "$template" '//BAD' `
   23.61 +  badcount=` echo "$badlines" | wc -l `
   23.62 +  [ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; }
   23.63 +  $quiet || echo "Expanding $badcount negative test cases from $template:"
   23.64 +  $quiet || echo "$badlines"
   23.65 +  badnums=` echo "$badlines" | sed 's/:.*//' `
   23.66 +  casestem=` getcasestem "$template" `
   23.67 +  tclassname=` basename "$template" .java `
   23.68 +  rm "$casestem"*.java
   23.69 +  for badnum in $badnums; do
   23.70 +    casefile="$casestem"${badnum}.java
   23.71 +    cclassname=` basename "$casefile" .java `
   23.72 +    sed < "$template" > "$casefile" "
   23.73 +      s|@compile|@compile/fail|
   23.74 +      / @[a-z]/s|@|##|
   23.75 +      ${badnum}s:^ *[/*]*:    :
   23.76 +      s/${tclassname}/${cclassname}/g
   23.77 +    "
   23.78 +    $verbose && diff -u "$template" "$casefile"
   23.79 +  done
   23.80 +}
   23.81 +
   23.82 +getcasestem() {
   23.83 +  echo "$1" | sed 's/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/'
   23.84 +}
   23.85 +
   23.86 +testneg() {
   23.87 +  template=$1
   23.88 +  for casefile in ` getcasestem "$template" `*.java; do
   23.89 +    $quiet || echo -------- $javac "$casefile"
   23.90 +    $javac "$casefile" > "$casefile".errlog 2>&1 && {
   23.91 +      echo "*** Compilation unexpectedly succeeded:  $casefile"
   23.92 +      exit 1
   23.93 +    }
   23.94 +    $quiet || echo "Compilation failed as expected"
   23.95 +    $quiet || head ` $verbose || echo -3 ` < "$casefile".errlog
   23.96 +    rm "$casefile".errlog
   23.97 +  done
   23.98 +}
   23.99 +
  23.100 +main "$@"
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/test/tools/javac/quid/QuotedIdent.java	Mon May 04 22:16:46 2009 -0700
    24.3 @@ -0,0 +1,132 @@
    24.4 +/*
    24.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.7 + *
    24.8 + * This code is free software; you can redistribute it and/or modify it
    24.9 + * under the terms of the GNU General Public License version 2 only, as
   24.10 + * published by the Free Software Foundation.
   24.11 + *
   24.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   24.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   24.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   24.15 + * version 2 for more details (a copy is included in the LICENSE file that
   24.16 + * accompanied this code).
   24.17 + *
   24.18 + * You should have received a copy of the GNU General Public License version
   24.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   24.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24.21 + *
   24.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   24.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   24.24 + * have any questions.
   24.25 + */
   24.26 +
   24.27 +/*
   24.28 + * @test
   24.29 + * @bug 6746458
   24.30 + * @summary Verify correct lexing of quoted identifiers.
   24.31 + * @author jrose
   24.32 + *
   24.33 + * @library ..
   24.34 + * @run main quid.QuotedIdent
   24.35 + */
   24.36 +
   24.37 +/*
   24.38 + * Standalone testing:
   24.39 + * <code>
   24.40 + * $ cd $MY_REPO_DIR/langtools
   24.41 + * $ (cd make; make)
   24.42 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/quid/QuotedIdent.java
   24.43 + * $ java -version  # should print 1.6 or later
   24.44 + * $ java -cp dist quid.QuotedIdent
   24.45 + * </code>
   24.46 + */
   24.47 +
   24.48 +package quid;
   24.49 +
   24.50 +public class QuotedIdent {
   24.51 +    static void check(int testid, String have, String expect)
   24.52 +                throws RuntimeException {
   24.53 +        if ((have == null && have != expect) ||
   24.54 +                (have != null && !have.equals(expect))) {
   24.55 +            String msg =
   24.56 +                "TEST " + testid + ": HAVE \"" +
   24.57 +                have + "\" EXPECT \"" + expect + "\"";
   24.58 +            System.out.println("StringConversion: " + msg);
   24.59 +            throw new RuntimeException(msg);
   24.60 +        }
   24.61 +    }
   24.62 +
   24.63 +    // negative tests:
   24.64 +    //static class #"" { } //BAD empty ident name
   24.65 +    //static class #"<foo>" { } //BAD bad char in ident name
   24.66 +    /*static class /*(//BAD ident name interrupted by newline) #"jump:
   24.67 +    " { } /* uncomment previous line to attempt class w/ bad name */
   24.68 +
   24.69 +    static class #"int" extends Number {
   24.70 +        final int #"int";
   24.71 +        #"int"(int #"int") {
   24.72 +            this.#"int" = #"int";
   24.73 +        }
   24.74 +        static #"int" valueOf(int #"int") {
   24.75 +            return new #"int"(#"int");
   24.76 +        }
   24.77 +        public int intValue() { return #"int"; }
   24.78 +        public long longValue() { return #"int"; }
   24.79 +        public float floatValue() { return #"int"; }
   24.80 +        public double doubleValue() { return #"int"; }
   24.81 +        public String toString() { return String.valueOf(#"int"); }
   24.82 +    }
   24.83 +
   24.84 +    class #"*86" {
   24.85 +        String #"555-1212"() { return "[*86.555-1212]"; }
   24.86 +    }
   24.87 +    static#"*86"#"MAKE-*86"() {   // note close spacing
   24.88 +        return new QuotedIdent().new#"*86"();
   24.89 +    }
   24.90 +
   24.91 +    static String bar() { return "[bar]"; }
   24.92 +
   24.93 +    public static void main(String[] args) throws Exception {
   24.94 +        String s;
   24.95 +
   24.96 +        String #"sticky \' wicket" = "wicked ' stick";
   24.97 +        s = #"sticky ' wicket";
   24.98 +        check(11, s, "wicked \' stick");
   24.99 +        check(12, #"s", s);
  24.100 +        check(13, #"\163", s);
  24.101 +
  24.102 +        s = #"QuotedIdent".bar();
  24.103 +        check(21, s, "[bar]");
  24.104 +
  24.105 +        s = #"int".valueOf(123).toString();
  24.106 +        check(22, s, "123");
  24.107 +
  24.108 +        s = #"MAKE-*86"().#"555-1212"();
  24.109 +        check(23, s, "[*86.555-1212]");
  24.110 +
  24.111 +        class#"{{{inmost}}}" { }
  24.112 +        s = new#"{{{inmost}}}"().getClass().getName();
  24.113 +        if (!s.endsWith("{{{inmost}}}"))
  24.114 +            check(24, s, "should end with \"{{{inmost}}}\"");
  24.115 +
  24.116 +        s = #"Yog-Shoggoth".#"(nameless ululation)";
  24.117 +        check(25, s, "Tekeli-li!");
  24.118 +
  24.119 +        s = #"int".class.getName();
  24.120 +        check(31, s, QuotedIdent.class.getName()+"$int");
  24.121 +
  24.122 +        Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
  24.123 +        if (x86 != #"*86".class)
  24.124 +            check(32, "reflected "+x86, "static "+#"*86".class);
  24.125 +
  24.126 +        s = (String) x86.getDeclaredMethod("555-1212").invoke(#"MAKE-*86"());
  24.127 +        check(31, s, "[*86.555-1212]");
  24.128 +
  24.129 +        System.out.println("OK");
  24.130 +    }
  24.131 +}
  24.132 +
  24.133 +interface #"Yog-Shoggoth" {
  24.134 +    final String #"(nameless ululation)" = "Tekeli-li!";
  24.135 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/test/tools/javac/quid/QuotedIdent2.java	Mon May 04 22:16:46 2009 -0700
    25.3 @@ -0,0 +1,81 @@
    25.4 +/*
    25.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 + *
    25.8 + * This code is free software; you can redistribute it and/or modify it
    25.9 + * under the terms of the GNU General Public License version 2 only, as
   25.10 + * published by the Free Software Foundation.
   25.11 + *
   25.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   25.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.15 + * version 2 for more details (a copy is included in the LICENSE file that
   25.16 + * accompanied this code).
   25.17 + *
   25.18 + * You should have received a copy of the GNU General Public License version
   25.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   25.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.21 + *
   25.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   25.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   25.24 + * have any questions.
   25.25 + */
   25.26 +
   25.27 +/*
   25.28 + * @test
   25.29 + * @bug 6746458
   25.30 + * @summary Verify correct separate compilation of classes with extended identifiers.
   25.31 + * @author jrose
   25.32 + *
   25.33 + * @library ..
   25.34 + * @run main quid.QuotedIdent2
   25.35 + */
   25.36 +/*
   25.37 + * Standalone testing:
   25.38 + * <code>
   25.39 + * $ cd $MY_REPO_DIR/langtools
   25.40 + * $ (cd make; make)
   25.41 + * $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/quid/QuotedIdent.java
   25.42 + * $ ./dist/bootstrap/bin/javac -d dist -cp dist test/tools/javac/quid/QuotedIdent2.java
   25.43 + * $ java -version  # should print 1.6 or later
   25.44 + * $ java -cp dist QuotedIdent2
   25.45 + * </code>
   25.46 + */
   25.47 +
   25.48 +package quid;
   25.49 +
   25.50 +import quid.QuotedIdent.*;
   25.51 +import quid.QuotedIdent.#"*86";
   25.52 +import static quid.QuotedIdent.#"MAKE-*86";
   25.53 +
   25.54 +public class QuotedIdent2 {
   25.55 +    static void check(int testid, String have, String expect)
   25.56 +                throws RuntimeException {
   25.57 +        QuotedIdent.check(testid, have, expect);
   25.58 +    }
   25.59 +
   25.60 +    public static void main(String[] args) throws Exception {
   25.61 +        String s;
   25.62 +
   25.63 +        s = #"int".valueOf(123).toString();
   25.64 +        check(22, s, "123");
   25.65 +
   25.66 +        s = #"MAKE-*86"().#"555-1212"();
   25.67 +        check(23, s, "[*86.555-1212]");
   25.68 +
   25.69 +        s = #"Yog-Shoggoth".#"(nameless ululation)";
   25.70 +        check(25, s, "Tekeli-li!");
   25.71 +
   25.72 +        s = QuotedIdent.#"int".class.getName();
   25.73 +        check(31, s, QuotedIdent.class.getName()+"$int");
   25.74 +
   25.75 +        Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
   25.76 +        if (x86 != #"*86".class)
   25.77 +            check(32, "reflected "+x86, "static "+#"*86".class);
   25.78 +
   25.79 +        s = (String) x86.getDeclaredMethod("555-1212").invoke(QuotedIdent.#"MAKE-*86"());
   25.80 +        check(31, s, "[*86.555-1212]");
   25.81 +
   25.82 +        System.out.println("OK");
   25.83 +    }
   25.84 +}

mercurial