mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-09 04:59:33 +00:00
Merge
This commit is contained in:
commit
5b708c4ff5
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
@ -331,7 +331,7 @@
|
||||
executable="${dist.bin.dir}/javac"
|
||||
srcdir="test/tools/javac/diags"
|
||||
destdir="${build.dir}/diag-examples/classes"
|
||||
includes="Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
|
||||
includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
|
||||
sourcepath=""
|
||||
classpath="${dist.lib.dir}/javac.jar"
|
||||
includeAntRuntime="no"
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class DeferredLintHandler {
|
||||
protected static final Context.Key<DeferredLintHandler> deferredLintHandlerKey =
|
||||
new Context.Key<DeferredLintHandler>();
|
||||
|
||||
public static DeferredLintHandler instance(Context context) {
|
||||
DeferredLintHandler instance = context.get(deferredLintHandlerKey);
|
||||
if (instance == null)
|
||||
instance = new DeferredLintHandler(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected DeferredLintHandler(Context context) {
|
||||
context.put(deferredLintHandlerKey, this);
|
||||
}
|
||||
|
||||
private DeferredLintHandler() {}
|
||||
|
||||
public interface LintLogger {
|
||||
void report();
|
||||
}
|
||||
|
||||
private DiagnosticPosition currentPos;
|
||||
private Map<DiagnosticPosition, ListBuffer<LintLogger>> loggersQueue = new HashMap<DiagnosticPosition, ListBuffer<LintLogger>>();
|
||||
|
||||
public void report(LintLogger logger) {
|
||||
ListBuffer<LintLogger> loggers = loggersQueue.get(currentPos);
|
||||
Assert.checkNonNull(loggers);
|
||||
loggers.append(logger);
|
||||
}
|
||||
|
||||
public void flush(DiagnosticPosition pos) {
|
||||
ListBuffer<LintLogger> loggers = loggersQueue.get(pos);
|
||||
if (loggers != null) {
|
||||
for (LintLogger lintLogger : loggers) {
|
||||
lintLogger.report();
|
||||
}
|
||||
loggersQueue.remove(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public DeferredLintHandler setPos(DiagnosticPosition currentPos) {
|
||||
this.currentPos = currentPos;
|
||||
loggersQueue.put(currentPos, ListBuffer.<LintLogger>lb());
|
||||
return this;
|
||||
}
|
||||
|
||||
public static final DeferredLintHandler immediateHandler = new DeferredLintHandler() {
|
||||
@Override
|
||||
public void report(LintLogger logger) {
|
||||
logger.report();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -237,7 +237,7 @@ public class Flags {
|
||||
|
||||
/**
|
||||
* Flag that marks a signature-polymorphic invoke method.
|
||||
* (These occur inside java.dyn.MethodHandle.)
|
||||
* (These occur inside java.lang.invoke.MethodHandle.)
|
||||
*/
|
||||
public static final long POLYMORPHIC_SIGNATURE = 1L<<40;
|
||||
|
||||
@ -252,6 +252,11 @@ public class Flags {
|
||||
*/
|
||||
public static final long EFFECTIVELY_FINAL = 1L<<42;
|
||||
|
||||
/**
|
||||
* Flag that marks non-override equivalent methods with the same signature
|
||||
*/
|
||||
public static final long CLASH = 1L<<43;
|
||||
|
||||
/** Modifier masks.
|
||||
*/
|
||||
public static final int
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -106,7 +106,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
}
|
||||
|
||||
/**
|
||||
* * Get a localized string represenation for all the symbols in the input list.
|
||||
* * Get a localized string representation for all the symbols in the input list.
|
||||
*
|
||||
* @param ts symbols to be displayed
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
|
||||
@ -72,49 +72,10 @@ public class Scope {
|
||||
*/
|
||||
int nelems = 0;
|
||||
|
||||
/** A timestamp - useful to quickly check whether a scope has changed or not
|
||||
*/
|
||||
public ScopeCounter scopeCounter;
|
||||
|
||||
static ScopeCounter dummyCounter = new ScopeCounter() {
|
||||
@Override
|
||||
public void inc() {
|
||||
//do nothing
|
||||
}
|
||||
};
|
||||
|
||||
/** A list of scopes to be notified if items are to be removed from this scope.
|
||||
*/
|
||||
List<Scope> listeners = List.nil();
|
||||
|
||||
public static class ScopeCounter {
|
||||
protected static final Context.Key<ScopeCounter> scopeCounterKey =
|
||||
new Context.Key<ScopeCounter>();
|
||||
|
||||
public static ScopeCounter instance(Context context) {
|
||||
ScopeCounter instance = context.get(scopeCounterKey);
|
||||
if (instance == null)
|
||||
instance = new ScopeCounter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected ScopeCounter(Context context) {
|
||||
context.put(scopeCounterKey, this);
|
||||
}
|
||||
|
||||
private ScopeCounter() {};
|
||||
|
||||
private long val = 0;
|
||||
|
||||
public void inc() {
|
||||
val++;
|
||||
}
|
||||
|
||||
public long val() {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/** Use as a "not-found" result for lookup.
|
||||
* Also used to mark deleted entries in the table.
|
||||
*/
|
||||
@ -126,35 +87,30 @@ public class Scope {
|
||||
|
||||
/** A value for the empty scope.
|
||||
*/
|
||||
public static final Scope emptyScope = new Scope(null, null, new Entry[]{}, dummyCounter);
|
||||
public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
|
||||
|
||||
/** Construct a new scope, within scope next, with given owner, using
|
||||
* given table. The table's length must be an exponent of 2.
|
||||
*/
|
||||
private Scope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) {
|
||||
private Scope(Scope next, Symbol owner, Entry[] table) {
|
||||
this.next = next;
|
||||
Assert.check(emptyScope == null || owner != null);
|
||||
this.owner = owner;
|
||||
this.table = table;
|
||||
this.hashMask = table.length - 1;
|
||||
this.scopeCounter = scopeCounter;
|
||||
}
|
||||
|
||||
/** Convenience constructor used for dup and dupUnshared. */
|
||||
private Scope(Scope next, Symbol owner, Entry[] table) {
|
||||
this(next, owner, table, next.scopeCounter);
|
||||
this.nelems = next.nelems;
|
||||
private Scope(Scope next, Symbol owner, Entry[] table, int nelems) {
|
||||
this(next, owner, table);
|
||||
this.nelems = nelems;
|
||||
}
|
||||
|
||||
/** Construct a new scope, within scope next, with given owner,
|
||||
* using a fresh table of length INITIAL_SIZE.
|
||||
*/
|
||||
public Scope(Symbol owner) {
|
||||
this(owner, dummyCounter);
|
||||
}
|
||||
|
||||
protected Scope(Symbol owner, ScopeCounter scopeCounter) {
|
||||
this(null, owner, new Entry[INITIAL_SIZE], scopeCounter);
|
||||
this(null, owner, new Entry[INITIAL_SIZE]);
|
||||
}
|
||||
|
||||
/** Construct a fresh scope within this scope, with same owner,
|
||||
@ -172,7 +128,7 @@ public class Scope {
|
||||
* of fresh tables.
|
||||
*/
|
||||
public Scope dup(Symbol newOwner) {
|
||||
Scope result = new Scope(this, newOwner, this.table);
|
||||
Scope result = new Scope(this, newOwner, this.table, this.nelems);
|
||||
shared++;
|
||||
// System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
|
||||
// new Error().printStackTrace(System.out);
|
||||
@ -184,7 +140,7 @@ public class Scope {
|
||||
* the table of its outer scope.
|
||||
*/
|
||||
public Scope dupUnshared() {
|
||||
return new Scope(this, this.owner, this.table.clone());
|
||||
return new Scope(this, this.owner, this.table.clone(), this.nelems);
|
||||
}
|
||||
|
||||
/** Remove all entries of this scope from its table, if shared
|
||||
@ -263,7 +219,6 @@ public class Scope {
|
||||
Entry e = makeEntry(sym, old, elems, s, origin);
|
||||
table[hash] = e;
|
||||
elems = e;
|
||||
scopeCounter.inc();
|
||||
}
|
||||
|
||||
Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
|
||||
@ -278,8 +233,6 @@ public class Scope {
|
||||
Entry e = lookup(sym.name);
|
||||
if (e.scope == null) return;
|
||||
|
||||
scopeCounter.inc();
|
||||
|
||||
// remove e from table and shadowed list;
|
||||
int i = getIndex(sym.name);
|
||||
Entry te = table[i];
|
||||
@ -559,7 +512,7 @@ public class Scope {
|
||||
public static final Entry[] emptyTable = new Entry[0];
|
||||
|
||||
public DelegatedScope(Scope outer) {
|
||||
super(outer, outer.owner, emptyTable, outer.scopeCounter);
|
||||
super(outer, outer.owner, emptyTable);
|
||||
delegatee = outer;
|
||||
}
|
||||
public Scope dup() {
|
||||
@ -585,22 +538,10 @@ public class Scope {
|
||||
}
|
||||
}
|
||||
|
||||
/** A class scope, for which a scope counter should be provided */
|
||||
public static class ClassScope extends Scope {
|
||||
|
||||
ClassScope(Scope next, Symbol owner, Entry[] table, ScopeCounter scopeCounter) {
|
||||
super(next, owner, table, scopeCounter);
|
||||
}
|
||||
|
||||
public ClassScope(Symbol owner, ScopeCounter scopeCounter) {
|
||||
super(owner, scopeCounter);
|
||||
}
|
||||
}
|
||||
|
||||
/** An error scope, for which the owner should be an error symbol. */
|
||||
public static class ErrorScope extends Scope {
|
||||
ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
|
||||
super(next, /*owner=*/errSymbol, table, dummyCounter);
|
||||
super(next, /*owner=*/errSymbol, table);
|
||||
}
|
||||
public ErrorScope(Symbol errSymbol) {
|
||||
super(errSymbol);
|
||||
|
||||
@ -729,6 +729,10 @@ public abstract class Symbol implements Element {
|
||||
*/
|
||||
public Pool pool;
|
||||
|
||||
/** members closure cache (set by Types.membersClosure)
|
||||
*/
|
||||
Scope membersClosure;
|
||||
|
||||
public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
|
||||
super(flags, name, type, owner);
|
||||
this.members_field = null;
|
||||
@ -961,22 +965,12 @@ public abstract class Symbol implements Element {
|
||||
}
|
||||
|
||||
public void setLazyConstValue(final Env<AttrContext> env,
|
||||
final Log log,
|
||||
final Attr attr,
|
||||
final JCTree.JCExpression initializer)
|
||||
{
|
||||
setData(new Callable<Object>() {
|
||||
public Object call() {
|
||||
JavaFileObject source = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
Type itype = attr.attribExpr(initializer, env, type);
|
||||
if (itype.constValue() != null)
|
||||
return attr.coerce(itype, type).constValue();
|
||||
else
|
||||
return null;
|
||||
} finally {
|
||||
log.useSource(source);
|
||||
}
|
||||
return attr.attribLazyConstantValue(env, initializer, type);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1010,6 +1004,7 @@ public abstract class Symbol implements Element {
|
||||
try {
|
||||
data = eval.call();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
throw new AssertionError(ex);
|
||||
}
|
||||
}
|
||||
@ -1231,7 +1226,7 @@ public abstract class Symbol implements Element {
|
||||
};
|
||||
|
||||
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
|
||||
MethodSymbol res = types.implementation(this, origin, types, checkResult, implFilter);
|
||||
MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
|
||||
if (res != null)
|
||||
return res;
|
||||
// if origin is derived from a raw type, we might have missed
|
||||
|
||||
@ -74,7 +74,6 @@ public class Symtab {
|
||||
public final JCNoType voidType = new JCNoType(TypeTags.VOID);
|
||||
|
||||
private final Names names;
|
||||
private final Scope.ScopeCounter scopeCounter;
|
||||
private final ClassReader reader;
|
||||
private final Target target;
|
||||
|
||||
@ -124,7 +123,9 @@ public class Symtab {
|
||||
public final Type stringBuilderType;
|
||||
public final Type cloneableType;
|
||||
public final Type serializableType;
|
||||
public final Type transientMethodHandleType; // transient - 292
|
||||
public final Type methodHandleType;
|
||||
public final Type transientPolymorphicSignatureType; // transient - 292
|
||||
public final Type polymorphicSignatureType;
|
||||
public final Type throwableType;
|
||||
public final Type errorType;
|
||||
@ -341,7 +342,6 @@ public class Symtab {
|
||||
context.put(symtabKey, this);
|
||||
|
||||
names = Names.instance(context);
|
||||
scopeCounter = Scope.ScopeCounter.instance(context);
|
||||
target = Target.instance(context);
|
||||
|
||||
// Create the unknown type
|
||||
@ -388,7 +388,7 @@ public class Symtab {
|
||||
|
||||
// Create class to hold all predefined constants and operations.
|
||||
predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
|
||||
Scope scope = new Scope.ClassScope(predefClass, scopeCounter);
|
||||
Scope scope = new Scope(predefClass);
|
||||
predefClass.members_field = scope;
|
||||
|
||||
// Enter symbols for basic types.
|
||||
@ -419,8 +419,10 @@ public class Symtab {
|
||||
cloneableType = enterClass("java.lang.Cloneable");
|
||||
throwableType = enterClass("java.lang.Throwable");
|
||||
serializableType = enterClass("java.io.Serializable");
|
||||
methodHandleType = enterClass("java.dyn.MethodHandle");
|
||||
polymorphicSignatureType = enterClass("java.dyn.MethodHandle$PolymorphicSignature");
|
||||
transientMethodHandleType = enterClass("java.dyn.MethodHandle"); // transient - 292
|
||||
methodHandleType = enterClass("java.lang.invoke.MethodHandle");
|
||||
transientPolymorphicSignatureType = enterClass("java.dyn.MethodHandle$PolymorphicSignature"); // transient - 292
|
||||
polymorphicSignatureType = enterClass("java.lang.invoke.MethodHandle$PolymorphicSignature");
|
||||
errorType = enterClass("java.lang.Error");
|
||||
illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
|
||||
exceptionType = enterClass("java.lang.Exception");
|
||||
@ -464,6 +466,7 @@ public class Symtab {
|
||||
|
||||
synthesizeEmptyInterfaceIfMissing(cloneableType);
|
||||
synthesizeEmptyInterfaceIfMissing(serializableType);
|
||||
synthesizeEmptyInterfaceIfMissing(transientPolymorphicSignatureType); // transient - 292
|
||||
synthesizeEmptyInterfaceIfMissing(polymorphicSignatureType);
|
||||
synthesizeBoxTypeIfMissing(doubleType);
|
||||
synthesizeBoxTypeIfMissing(floatType);
|
||||
@ -478,7 +481,7 @@ public class Symtab {
|
||||
proprietarySymbol.completer = null;
|
||||
proprietarySymbol.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
|
||||
proprietarySymbol.erasure_field = proprietaryType;
|
||||
proprietarySymbol.members_field = new Scope.ClassScope(proprietarySymbol, scopeCounter);
|
||||
proprietarySymbol.members_field = new Scope(proprietarySymbol);
|
||||
proprietaryType.typarams_field = List.nil();
|
||||
proprietaryType.allparams_field = List.nil();
|
||||
proprietaryType.supertype_field = annotationType;
|
||||
@ -490,7 +493,7 @@ public class Symtab {
|
||||
ClassType arrayClassType = (ClassType)arrayClass.type;
|
||||
arrayClassType.supertype_field = objectType;
|
||||
arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
|
||||
arrayClass.members_field = new Scope.ClassScope(arrayClass, scopeCounter);
|
||||
arrayClass.members_field = new Scope(arrayClass);
|
||||
lengthVar = new VarSymbol(
|
||||
PUBLIC | FINAL,
|
||||
names.length,
|
||||
|
||||
@ -36,6 +36,7 @@ import com.sun.tools.javac.code.Attribute.RetentionPolicy;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
import com.sun.tools.javac.comp.Check;
|
||||
|
||||
import static com.sun.tools.javac.code.Scope.*;
|
||||
import static com.sun.tools.javac.code.Type.*;
|
||||
import static com.sun.tools.javac.code.TypeTags.*;
|
||||
import static com.sun.tools.javac.code.Symbol.*;
|
||||
@ -70,7 +71,6 @@ public class Types {
|
||||
new Context.Key<Types>();
|
||||
|
||||
final Symtab syms;
|
||||
final Scope.ScopeCounter scopeCounter;
|
||||
final JavacMessages messages;
|
||||
final Names names;
|
||||
final boolean allowBoxing;
|
||||
@ -91,7 +91,6 @@ public class Types {
|
||||
protected Types(Context context) {
|
||||
context.put(typesKey, this);
|
||||
syms = Symtab.instance(context);
|
||||
scopeCounter = Scope.ScopeCounter.instance(context);
|
||||
names = Names.instance(context);
|
||||
allowBoxing = Source.instance(context).allowBoxing();
|
||||
reader = ClassReader.instance(context);
|
||||
@ -2024,26 +2023,22 @@ public class Types {
|
||||
final MethodSymbol cachedImpl;
|
||||
final Filter<Symbol> implFilter;
|
||||
final boolean checkResult;
|
||||
final Scope.ScopeCounter scopeCounter;
|
||||
|
||||
public Entry(MethodSymbol cachedImpl,
|
||||
Filter<Symbol> scopeFilter,
|
||||
boolean checkResult,
|
||||
Scope.ScopeCounter scopeCounter) {
|
||||
boolean checkResult) {
|
||||
this.cachedImpl = cachedImpl;
|
||||
this.implFilter = scopeFilter;
|
||||
this.checkResult = checkResult;
|
||||
this.scopeCounter = scopeCounter;
|
||||
}
|
||||
|
||||
boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, Scope.ScopeCounter scopeCounter) {
|
||||
boolean matches(Filter<Symbol> scopeFilter, boolean checkResult) {
|
||||
return this.implFilter == scopeFilter &&
|
||||
this.checkResult == checkResult &&
|
||||
this.scopeCounter.val() >= scopeCounter.val();
|
||||
this.checkResult == checkResult;
|
||||
}
|
||||
}
|
||||
|
||||
MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter, Scope.ScopeCounter scopeCounter) {
|
||||
MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
|
||||
SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
|
||||
Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
|
||||
if (cache == null) {
|
||||
@ -2052,9 +2047,9 @@ public class Types {
|
||||
}
|
||||
Entry e = cache.get(origin);
|
||||
if (e == null ||
|
||||
!e.matches(implFilter, checkResult, scopeCounter)) {
|
||||
!e.matches(implFilter, checkResult)) {
|
||||
MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter);
|
||||
cache.put(origin, new Entry(impl, implFilter, checkResult, scopeCounter));
|
||||
cache.put(origin, new Entry(impl, implFilter, checkResult));
|
||||
return impl;
|
||||
}
|
||||
else {
|
||||
@ -2081,11 +2076,55 @@ public class Types {
|
||||
|
||||
private ImplementationCache implCache = new ImplementationCache();
|
||||
|
||||
public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
|
||||
return implCache.get(ms, origin, checkResult, implFilter, scopeCounter);
|
||||
public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
|
||||
return implCache.get(ms, origin, checkResult, implFilter);
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
|
||||
public Scope membersClosure(Type site) {
|
||||
return membersClosure.visit(site);
|
||||
}
|
||||
|
||||
UnaryVisitor<Scope> membersClosure = new UnaryVisitor<Scope>() {
|
||||
|
||||
public Scope visitType(Type t, Void s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scope visitClassType(ClassType t, Void s) {
|
||||
ClassSymbol csym = (ClassSymbol)t.tsym;
|
||||
if (csym.membersClosure == null) {
|
||||
Scope membersClosure = new Scope(csym);
|
||||
for (Type i : interfaces(t)) {
|
||||
enterAll(visit(i), membersClosure);
|
||||
}
|
||||
enterAll(visit(supertype(t)), membersClosure);
|
||||
enterAll(csym.members(), membersClosure);
|
||||
csym.membersClosure = membersClosure;
|
||||
}
|
||||
return csym.membersClosure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scope visitTypeVar(TypeVar t, Void s) {
|
||||
return visit(t.getUpperBound());
|
||||
}
|
||||
|
||||
public void enterAll(Scope s, Scope to) {
|
||||
if (s == null) return;
|
||||
List<Symbol> syms = List.nil();
|
||||
for (Scope.Entry e = s.elems ; e != null ; e = e.sibling) {
|
||||
syms = syms.prepend(e.sym);
|
||||
}
|
||||
for (Symbol sym : syms) {
|
||||
to.enter(sym);
|
||||
}
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
/**
|
||||
* Does t have the same arguments as s? It is assumed that both
|
||||
* types are (possibly polymorphic) method types. Monomorphic
|
||||
@ -2259,6 +2298,13 @@ public class Types {
|
||||
|
||||
@Override
|
||||
public Type visitForAll(ForAll t, Void ignored) {
|
||||
if (Type.containsAny(to, t.tvars)) {
|
||||
//perform alpha-renaming of free-variables in 't'
|
||||
//if 'to' types contain variables that are free in 't'
|
||||
List<Type> freevars = newInstances(t.tvars);
|
||||
t = new ForAll(freevars,
|
||||
Types.this.subst(t.qtype, t.tvars, freevars));
|
||||
}
|
||||
List<Type> tvars1 = substBounds(t.tvars, from, to);
|
||||
Type qtype1 = subst(t.qtype);
|
||||
if (tvars1 == t.tvars && qtype1 == t.qtype) {
|
||||
|
||||
@ -83,6 +83,7 @@ public class Attr extends JCTree.Visitor {
|
||||
final Types types;
|
||||
final JCDiagnostic.Factory diags;
|
||||
final Annotate annotate;
|
||||
final DeferredLintHandler deferredLintHandler;
|
||||
|
||||
public static Attr instance(Context context) {
|
||||
Attr instance = context.get(attrKey);
|
||||
@ -108,6 +109,7 @@ public class Attr extends JCTree.Visitor {
|
||||
types = Types.instance(context);
|
||||
diags = JCDiagnostic.Factory.instance(context);
|
||||
annotate = Annotate.instance(context);
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
|
||||
Options options = Options.instance(context);
|
||||
|
||||
@ -125,7 +127,6 @@ public class Attr extends JCTree.Visitor {
|
||||
findDiamonds = options.get("findDiamond") != null &&
|
||||
source.allowDiamond();
|
||||
useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
|
||||
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
|
||||
}
|
||||
|
||||
/** Switch: relax some constraints for retrofit mode.
|
||||
@ -173,12 +174,6 @@ public class Attr extends JCTree.Visitor {
|
||||
*/
|
||||
boolean useBeforeDeclarationWarning;
|
||||
|
||||
/**
|
||||
* Switch: allow lint infrastructure to control proprietary
|
||||
* API warnings.
|
||||
*/
|
||||
boolean enableSunApiLintControl;
|
||||
|
||||
/**
|
||||
* Switch: allow strings in switch?
|
||||
*/
|
||||
@ -581,6 +576,41 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute a "lazy constant value".
|
||||
* @param env The env for the const value
|
||||
* @param initializer The initializer for the const value
|
||||
* @param type The expected type, or null
|
||||
* @see VarSymbol#setlazyConstValue
|
||||
*/
|
||||
public Object attribLazyConstantValue(Env<AttrContext> env,
|
||||
JCTree.JCExpression initializer,
|
||||
Type type) {
|
||||
|
||||
// in case no lint value has been set up for this env, scan up
|
||||
// env stack looking for smallest enclosing env for which it is set.
|
||||
Env<AttrContext> lintEnv = env;
|
||||
while (lintEnv.info.lint == null)
|
||||
lintEnv = lintEnv.next;
|
||||
|
||||
// Having found the enclosing lint value, we can initialize the lint value for this class
|
||||
env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags());
|
||||
|
||||
Lint prevLint = chk.setLint(env.info.lint);
|
||||
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||
|
||||
try {
|
||||
Type itype = attribExpr(initializer, env, type);
|
||||
if (itype.constValue() != null)
|
||||
return coerce(itype, type).constValue();
|
||||
else
|
||||
return null;
|
||||
} finally {
|
||||
env.info.lint = prevLint;
|
||||
log.useSource(prevSource);
|
||||
}
|
||||
}
|
||||
|
||||
/** Attribute type reference in an `extends' or `implements' clause.
|
||||
* Supertypes of anonymous inner classes are usually already attributed.
|
||||
*
|
||||
@ -672,13 +702,18 @@ public class Attr extends JCTree.Visitor {
|
||||
Lint prevLint = chk.setLint(lint);
|
||||
MethodSymbol prevMethod = chk.setMethod(m);
|
||||
try {
|
||||
deferredLintHandler.flush(tree.pos());
|
||||
chk.checkDeprecatedAnnotation(tree.pos(), m);
|
||||
|
||||
attribBounds(tree.typarams);
|
||||
|
||||
// If we override any other methods, check that we do so properly.
|
||||
// JLS ???
|
||||
chk.checkClashes(tree.pos(), env.enclClass.type, m);
|
||||
if (m.isStatic()) {
|
||||
chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
|
||||
} else {
|
||||
chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
|
||||
}
|
||||
chk.checkOverride(tree, m);
|
||||
|
||||
// Create a new environment with local scope
|
||||
@ -814,6 +849,7 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
// Check that the variable's declared type is well-formed.
|
||||
chk.validate(tree.vartype, env);
|
||||
deferredLintHandler.flush(tree.pos());
|
||||
|
||||
try {
|
||||
chk.checkDeprecatedAnnotation(tree.pos(), v);
|
||||
@ -1959,7 +1995,9 @@ public class Attr extends JCTree.Visitor {
|
||||
tree.pos(), tree.getTag() - JCTree.ASGOffset, env,
|
||||
owntype, operand);
|
||||
|
||||
if (operator.kind == MTH) {
|
||||
if (operator.kind == MTH &&
|
||||
!owntype.isErroneous() &&
|
||||
!operand.isErroneous()) {
|
||||
chk.checkOperator(tree.pos(),
|
||||
(OperatorSymbol)operator,
|
||||
tree.getTag() - JCTree.ASGOffset,
|
||||
@ -1984,7 +2022,8 @@ public class Attr extends JCTree.Visitor {
|
||||
rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype);
|
||||
|
||||
Type owntype = types.createErrorType(tree.type);
|
||||
if (operator.kind == MTH) {
|
||||
if (operator.kind == MTH &&
|
||||
!argtype.isErroneous()) {
|
||||
owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC)
|
||||
? tree.arg.type
|
||||
: operator.type.getReturnType();
|
||||
@ -2020,7 +2059,9 @@ public class Attr extends JCTree.Visitor {
|
||||
rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right);
|
||||
|
||||
Type owntype = types.createErrorType(tree.type);
|
||||
if (operator.kind == MTH) {
|
||||
if (operator.kind == MTH &&
|
||||
!left.isErroneous() &&
|
||||
!right.isErroneous()) {
|
||||
owntype = operator.type.getReturnType();
|
||||
int opc = chk.checkOperator(tree.lhs.pos(),
|
||||
(OperatorSymbol)operator,
|
||||
@ -2337,7 +2378,6 @@ public class Attr extends JCTree.Visitor {
|
||||
int pkind) {
|
||||
DiagnosticPosition pos = tree.pos();
|
||||
Name name = tree.name;
|
||||
|
||||
switch (site.tag) {
|
||||
case PACKAGE:
|
||||
return rs.access(
|
||||
@ -2543,17 +2583,10 @@ public class Attr extends JCTree.Visitor {
|
||||
// Test (1): emit a `deprecation' warning if symbol is deprecated.
|
||||
// (for constructors, the error was given when the constructor was
|
||||
// resolved)
|
||||
if (sym.name != names.init &&
|
||||
(sym.flags() & DEPRECATED) != 0 &&
|
||||
(env.info.scope.owner.flags() & DEPRECATED) == 0 &&
|
||||
sym.outermostClass() != env.info.scope.owner.outermostClass())
|
||||
chk.warnDeprecated(tree.pos(), sym);
|
||||
|
||||
if ((sym.flags() & PROPRIETARY) != 0) {
|
||||
if (enableSunApiLintControl)
|
||||
chk.warnSunApi(tree.pos(), "sun.proprietary", sym);
|
||||
else
|
||||
log.strictWarning(tree.pos(), "sun.proprietary", sym);
|
||||
if (sym.name != names.init) {
|
||||
chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym);
|
||||
chk.checkSunAPI(tree.pos(), sym);
|
||||
}
|
||||
|
||||
// Test (3): if symbol is a variable, check that its type and
|
||||
@ -3156,7 +3189,7 @@ public class Attr extends JCTree.Visitor {
|
||||
if (sym == null ||
|
||||
sym.kind != VAR ||
|
||||
((VarSymbol) sym).getConstValue() == null)
|
||||
log.error(l.head.pos(), "icls.cant.have.static.decl", sym.location());
|
||||
log.error(l.head.pos(), "icls.cant.have.static.decl", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -68,6 +68,7 @@ public class Check {
|
||||
private final boolean skipAnnotations;
|
||||
private boolean warnOnSyntheticConflicts;
|
||||
private boolean suppressAbortOnBadClassFile;
|
||||
private boolean enableSunApiLintControl;
|
||||
private final TreeInfo treeinfo;
|
||||
|
||||
// The set of lint options currently in effect. It is initialized
|
||||
@ -109,13 +110,13 @@ public class Check {
|
||||
skipAnnotations = options.isSet("skipAnnotations");
|
||||
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
|
||||
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
|
||||
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
|
||||
|
||||
Target target = Target.instance(context);
|
||||
syntheticNameChar = target.syntheticNameChar();
|
||||
|
||||
boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
|
||||
boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
|
||||
boolean verboseVarargs = lint.isEnabled(LintCategory.VARARGS);
|
||||
boolean verboseSunApi = lint.isEnabled(LintCategory.SUNAPI);
|
||||
boolean enforceMandatoryWarnings = source.enforceMandatoryWarnings();
|
||||
|
||||
@ -123,10 +124,10 @@ public class Check {
|
||||
enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
|
||||
uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
|
||||
enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
|
||||
unsafeVarargsHandler = new MandatoryWarningHandler(log, verboseVarargs,
|
||||
enforceMandatoryWarnings, "varargs", LintCategory.VARARGS);
|
||||
sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi,
|
||||
enforceMandatoryWarnings, "sunapi", null);
|
||||
|
||||
deferredLintHandler = DeferredLintHandler.immediateHandler;
|
||||
}
|
||||
|
||||
/** Switch: generics enabled?
|
||||
@ -166,14 +167,14 @@ public class Check {
|
||||
*/
|
||||
private MandatoryWarningHandler uncheckedHandler;
|
||||
|
||||
/** A handler for messages about unchecked or unsafe vararg method decl.
|
||||
*/
|
||||
private MandatoryWarningHandler unsafeVarargsHandler;
|
||||
|
||||
/** A handler for messages about using proprietary API.
|
||||
*/
|
||||
private MandatoryWarningHandler sunApiHandler;
|
||||
|
||||
/** A handler for deferred lint warnings.
|
||||
*/
|
||||
private DeferredLintHandler deferredLintHandler;
|
||||
|
||||
/* *************************************************************************
|
||||
* Errors and Warnings
|
||||
**************************************************************************/
|
||||
@ -184,6 +185,12 @@ public class Check {
|
||||
return prev;
|
||||
}
|
||||
|
||||
DeferredLintHandler setDeferredLintHandler(DeferredLintHandler newDeferredLintHandler) {
|
||||
DeferredLintHandler prev = deferredLintHandler;
|
||||
deferredLintHandler = newDeferredLintHandler;
|
||||
return prev;
|
||||
}
|
||||
|
||||
MethodSymbol setMethod(MethodSymbol newMethod) {
|
||||
MethodSymbol prev = method;
|
||||
method = newMethod;
|
||||
@ -800,8 +807,9 @@ public class Check {
|
||||
Type actual = types.subst(args.head,
|
||||
type.tsym.type.getTypeArguments(),
|
||||
tvars_buf.toList());
|
||||
if (!checkExtends(actual, (TypeVar)tvars.head) &&
|
||||
!tvars.head.getUpperBound().isErroneous()) {
|
||||
if (!isTypeArgErroneous(actual) &&
|
||||
!tvars.head.getUpperBound().isErroneous() &&
|
||||
!checkExtends(actual, (TypeVar)tvars.head)) {
|
||||
return args.head;
|
||||
}
|
||||
args = args.tail;
|
||||
@ -814,14 +822,39 @@ public class Check {
|
||||
for (Type arg : types.capture(type).getTypeArguments()) {
|
||||
if (arg.tag == TYPEVAR &&
|
||||
arg.getUpperBound().isErroneous() &&
|
||||
!tvars.head.getUpperBound().isErroneous()) {
|
||||
!tvars.head.getUpperBound().isErroneous() &&
|
||||
!isTypeArgErroneous(args.head)) {
|
||||
return args.head;
|
||||
}
|
||||
tvars = tvars.tail;
|
||||
args = args.tail;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
//where
|
||||
boolean isTypeArgErroneous(Type t) {
|
||||
return isTypeArgErroneous.visit(t);
|
||||
}
|
||||
|
||||
Types.UnaryVisitor<Boolean> isTypeArgErroneous = new Types.UnaryVisitor<Boolean>() {
|
||||
public Boolean visitType(Type t, Void s) {
|
||||
return t.isErroneous();
|
||||
}
|
||||
@Override
|
||||
public Boolean visitTypeVar(TypeVar t, Void s) {
|
||||
return visit(t.getUpperBound());
|
||||
}
|
||||
@Override
|
||||
public Boolean visitCapturedType(CapturedType t, Void s) {
|
||||
return visit(t.getUpperBound()) ||
|
||||
visit(t.getLowerBound());
|
||||
}
|
||||
@Override
|
||||
public Boolean visitWildcardType(WildcardType t, Void s) {
|
||||
return visit(t.type);
|
||||
}
|
||||
};
|
||||
|
||||
/** Check that given modifiers are legal for given symbol and
|
||||
* return modifiers together with any implicit modififiers for that symbol.
|
||||
@ -1094,6 +1127,7 @@ public class Check {
|
||||
log.error(tree.pos(), "improperly.formed.type.param.missing");
|
||||
}
|
||||
}
|
||||
|
||||
public void visitSelectInternal(JCFieldAccess tree) {
|
||||
if (tree.type.tsym.isStatic() &&
|
||||
tree.selected.type.isParameterized()) {
|
||||
@ -1463,11 +1497,8 @@ public class Check {
|
||||
}
|
||||
|
||||
// Warn if a deprecated method overridden by a non-deprecated one.
|
||||
if ((other.flags() & DEPRECATED) != 0
|
||||
&& (m.flags() & DEPRECATED) == 0
|
||||
&& m.outermostClass() != other.outermostClass()
|
||||
&& !isDeprecatedOverrideIgnorable(other, origin)) {
|
||||
warnDeprecated(TreeInfo.diagnosticPositionFor(m, tree), other);
|
||||
if (!isDeprecatedOverrideIgnorable(other, origin)) {
|
||||
checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
|
||||
}
|
||||
}
|
||||
// where
|
||||
@ -1648,7 +1679,7 @@ public class Check {
|
||||
"(" + types.memberType(t2, s2).getParameterTypes() + ")");
|
||||
return s2;
|
||||
}
|
||||
} else if (!checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
|
||||
} else if (checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
|
||||
log.error(pos,
|
||||
"name.clash.same.erasure.no.override",
|
||||
s1, s1.location(),
|
||||
@ -1730,18 +1761,10 @@ public class Check {
|
||||
}
|
||||
|
||||
private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
|
||||
if (s1.kind == MTH &&
|
||||
s1.isInheritedIn(origin, types) &&
|
||||
(s1.flags() & SYNTHETIC) == 0 &&
|
||||
!s2.isConstructor()) {
|
||||
Type er1 = s2.erasure(types);
|
||||
Type er2 = s1.erasure(types);
|
||||
if (types.isSameTypes(er1.getParameterTypes(),
|
||||
er2.getParameterTypes())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
ClashFilter cf = new ClashFilter(origin.type);
|
||||
return (cf.accepts(s1) &&
|
||||
cf.accepts(s2) &&
|
||||
types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
|
||||
}
|
||||
|
||||
|
||||
@ -2080,52 +2103,82 @@ public class Check {
|
||||
* @param site The class whose methods are checked.
|
||||
* @param sym The method symbol to be checked.
|
||||
*/
|
||||
void checkClashes(DiagnosticPosition pos, Type site, Symbol sym) {
|
||||
List<Type> supertypes = types.closure(site);
|
||||
for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
|
||||
for (List<Type> m = supertypes; m.nonEmpty(); m = m.tail) {
|
||||
checkClashes(pos, l.head, m.head, site, sym);
|
||||
void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
|
||||
ClashFilter cf = new ClashFilter(site);
|
||||
//for each method m1 that is a member of 'site'...
|
||||
for (Scope.Entry e1 = types.membersClosure(site).lookup(sym.name, cf) ;
|
||||
e1.scope != null ; e1 = e1.next(cf)) {
|
||||
//...find another method m2 that is overridden (directly or indirectly)
|
||||
//by method 'sym' in 'site'
|
||||
for (Scope.Entry e2 = types.membersClosure(site).lookup(sym.name, cf) ;
|
||||
e2.scope != null ; e2 = e2.next(cf)) {
|
||||
if (e1.sym == e2.sym || !sym.overrides(e2.sym, site.tsym, types, false)) continue;
|
||||
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
|
||||
//a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
|
||||
if (!types.isSubSignature(sym.type, types.memberType(site, e1.sym)) &&
|
||||
types.hasSameArgs(e1.sym.erasure(types), e2.sym.erasure(types))) {
|
||||
sym.flags_field |= CLASH;
|
||||
String key = e2.sym == sym ?
|
||||
"name.clash.same.erasure.no.override" :
|
||||
"name.clash.same.erasure.no.override.1";
|
||||
log.error(pos,
|
||||
key,
|
||||
sym, sym.location(),
|
||||
e1.sym, e1.sym.location(),
|
||||
e2.sym, e2.sym.location());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Reports an error whenever 'sym' seen as a member of type 't1' clashes with
|
||||
* some unrelated method defined in 't2'.
|
||||
/** Check that all static methods accessible from 'site' are
|
||||
* mutually compatible (JLS 8.4.8).
|
||||
*
|
||||
* @param pos Position to be used for error reporting.
|
||||
* @param site The class whose methods are checked.
|
||||
* @param sym The method symbol to be checked.
|
||||
*/
|
||||
private void checkClashes(DiagnosticPosition pos, Type t1, Type t2, Type site, Symbol s1) {
|
||||
void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
|
||||
ClashFilter cf = new ClashFilter(site);
|
||||
s1 = ((MethodSymbol)s1).implementedIn(t1.tsym, types);
|
||||
if (s1 == null) return;
|
||||
Type st1 = types.memberType(site, s1);
|
||||
for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name, cf); e2.scope != null; e2 = e2.next(cf)) {
|
||||
Symbol s2 = e2.sym;
|
||||
if (s1 == s2) continue;
|
||||
Type st2 = types.memberType(site, s2);
|
||||
if (!types.overrideEquivalent(st1, st2) &&
|
||||
!checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
|
||||
//for each method m1 that is a member of 'site'...
|
||||
for (Scope.Entry e = types.membersClosure(site).lookup(sym.name, cf) ;
|
||||
e.scope != null ; e = e.next(cf)) {
|
||||
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
|
||||
//a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
|
||||
if (!types.isSubSignature(sym.type, types.memberType(site, e.sym)) &&
|
||||
types.hasSameArgs(e.sym.erasure(types), sym.erasure(types))) {
|
||||
log.error(pos,
|
||||
"name.clash.same.erasure.no.override",
|
||||
s1, s1.location(),
|
||||
s2, s2.location());
|
||||
}
|
||||
}
|
||||
}
|
||||
//where
|
||||
private class ClashFilter implements Filter<Symbol> {
|
||||
"name.clash.same.erasure.no.hide",
|
||||
sym, sym.location(),
|
||||
e.sym, e.sym.location());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type site;
|
||||
//where
|
||||
private class ClashFilter implements Filter<Symbol> {
|
||||
|
||||
ClashFilter(Type site) {
|
||||
this.site = site;
|
||||
}
|
||||
Type site;
|
||||
|
||||
public boolean accepts(Symbol s) {
|
||||
return s.kind == MTH &&
|
||||
(s.flags() & SYNTHETIC) == 0 &&
|
||||
s.isInheritedIn(site.tsym, types) &&
|
||||
!s.isConstructor();
|
||||
}
|
||||
}
|
||||
ClashFilter(Type site) {
|
||||
this.site = site;
|
||||
}
|
||||
|
||||
boolean shouldSkip(Symbol s) {
|
||||
return (s.flags() & CLASH) != 0 &&
|
||||
s.owner == site.tsym;
|
||||
}
|
||||
|
||||
public boolean accepts(Symbol s) {
|
||||
return s.kind == MTH &&
|
||||
(s.flags() & SYNTHETIC) == 0 &&
|
||||
!shouldSkip(s) &&
|
||||
s.isInheritedIn(site.tsym, types) &&
|
||||
!s.isConstructor();
|
||||
}
|
||||
}
|
||||
|
||||
/** Report a conflict between a user symbol and a synthetic symbol.
|
||||
*/
|
||||
@ -2410,6 +2463,32 @@ public class Check {
|
||||
}
|
||||
}
|
||||
|
||||
void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
|
||||
if ((s.flags() & DEPRECATED) != 0 &&
|
||||
(other.flags() & DEPRECATED) == 0 &&
|
||||
s.outermostClass() != other.outermostClass()) {
|
||||
deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
|
||||
@Override
|
||||
public void report() {
|
||||
warnDeprecated(pos, s);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
|
||||
if ((s.flags() & PROPRIETARY) != 0) {
|
||||
deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
|
||||
public void report() {
|
||||
if (enableSunApiLintControl)
|
||||
warnSunApi(pos, "sun.proprietary", s);
|
||||
else
|
||||
log.strictWarning(pos, "sun.proprietary", s);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* *************************************************************************
|
||||
* Check for recursive annotation elements.
|
||||
**************************************************************************/
|
||||
@ -2535,9 +2614,9 @@ public class Check {
|
||||
Type right) {
|
||||
if (operator.opcode == ByteCodes.error) {
|
||||
log.error(pos,
|
||||
"operator.cant.be.applied",
|
||||
"operator.cant.be.applied.1",
|
||||
treeinfo.operatorName(tag),
|
||||
List.of(left, right));
|
||||
left, right);
|
||||
}
|
||||
return operator.opcode;
|
||||
}
|
||||
@ -2581,21 +2660,35 @@ public class Check {
|
||||
if (sym.owner.name == names.any) return false;
|
||||
for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
|
||||
if (sym != e.sym &&
|
||||
sym.kind == e.sym.kind &&
|
||||
sym.name != names.error &&
|
||||
(sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
|
||||
if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS))
|
||||
(e.sym.flags() & CLASH) == 0 &&
|
||||
sym.kind == e.sym.kind &&
|
||||
sym.name != names.error &&
|
||||
(sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
|
||||
if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
|
||||
varargsDuplicateError(pos, sym, e.sym);
|
||||
else if (sym.kind == MTH && !types.overrideEquivalent(sym.type, e.sym.type))
|
||||
return true;
|
||||
} else if (sym.kind == MTH && !hasSameSignature(sym.type, e.sym.type)) {
|
||||
duplicateErasureError(pos, sym, e.sym);
|
||||
else
|
||||
sym.flags_field |= CLASH;
|
||||
return true;
|
||||
} else {
|
||||
duplicateError(pos, e.sym);
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//where
|
||||
boolean hasSameSignature(Type mt1, Type mt2) {
|
||||
if (mt1.tag == FORALL && mt2.tag == FORALL) {
|
||||
ForAll fa1 = (ForAll)mt1;
|
||||
ForAll fa2 = (ForAll)mt2;
|
||||
mt2 = types.subst(fa2, fa2.tvars, fa1.tvars);
|
||||
}
|
||||
return types.hasSameArgs(mt1.asMethodType(), mt2.asMethodType());
|
||||
}
|
||||
|
||||
/** Report duplicate declaration error.
|
||||
*/
|
||||
void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
|
||||
|
||||
@ -95,7 +95,6 @@ public class Enter extends JCTree.Visitor {
|
||||
|
||||
Log log;
|
||||
Symtab syms;
|
||||
Scope.ScopeCounter scopeCounter;
|
||||
Check chk;
|
||||
TreeMaker make;
|
||||
ClassReader reader;
|
||||
@ -123,7 +122,6 @@ public class Enter extends JCTree.Visitor {
|
||||
reader = ClassReader.instance(context);
|
||||
make = TreeMaker.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
scopeCounter = Scope.ScopeCounter.instance(context);
|
||||
chk = Check.instance(context);
|
||||
memberEnter = MemberEnter.instance(context);
|
||||
types = Types.instance(context);
|
||||
@ -192,7 +190,7 @@ public class Enter extends JCTree.Visitor {
|
||||
*/
|
||||
public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
|
||||
Env<AttrContext> localEnv =
|
||||
env.dup(tree, env.info.dup(new Scope.ClassScope(tree.sym, scopeCounter)));
|
||||
env.dup(tree, env.info.dup(new Scope(tree.sym)));
|
||||
localEnv.enclClass = tree;
|
||||
localEnv.outer = env;
|
||||
localEnv.info.isSelfCall = false;
|
||||
@ -328,7 +326,7 @@ public class Enter extends JCTree.Visitor {
|
||||
c.flatname = names.fromString(tree.packge + "." + name);
|
||||
c.sourcefile = tree.sourcefile;
|
||||
c.completer = null;
|
||||
c.members_field = new Scope.ClassScope(c, scopeCounter);
|
||||
c.members_field = new Scope(c);
|
||||
tree.packge.package_info = c;
|
||||
}
|
||||
classEnter(tree.defs, topEnv);
|
||||
@ -396,7 +394,7 @@ public class Enter extends JCTree.Visitor {
|
||||
c.completer = memberEnter;
|
||||
c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
|
||||
c.sourcefile = env.toplevel.sourcefile;
|
||||
c.members_field = new Scope.ClassScope(c, scopeCounter);
|
||||
c.members_field = new Scope(c);
|
||||
|
||||
ClassType ct = (ClassType)c.type;
|
||||
if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -485,11 +485,8 @@ public class Infer {
|
||||
@Override
|
||||
public Type inst(List<Type> inferred, Types types) throws NoInstanceException {
|
||||
List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
|
||||
if (!rs.argumentsAcceptable(capturedArgs, formals,
|
||||
allowBoxing, useVarargs, warn)) {
|
||||
// inferred method is not applicable
|
||||
throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes);
|
||||
}
|
||||
// check that actuals conform to inferred formals
|
||||
checkArgumentsAcceptable(env, capturedArgs, formals, allowBoxing, useVarargs, warn);
|
||||
// check that inferred bounds conform to their bounds
|
||||
checkWithinBounds(all_tvars,
|
||||
types.subst(inferredTypes, tvars, inferred), warn);
|
||||
@ -500,17 +497,27 @@ public class Infer {
|
||||
}};
|
||||
return mt2;
|
||||
}
|
||||
else if (!rs.argumentsAcceptable(capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) {
|
||||
// inferred method is not applicable
|
||||
throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", mt.getParameterTypes(), argtypes);
|
||||
}
|
||||
else {
|
||||
// check that actuals conform to inferred formals
|
||||
checkArgumentsAcceptable(env, capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn);
|
||||
// return instantiated version of method type
|
||||
return mt;
|
||||
}
|
||||
}
|
||||
//where
|
||||
|
||||
private void checkArgumentsAcceptable(Env<AttrContext> env, List<Type> actuals, List<Type> formals,
|
||||
boolean allowBoxing, boolean useVarargs, Warner warn) {
|
||||
try {
|
||||
rs.checkRawArgumentsAcceptable(env, actuals, formals,
|
||||
allowBoxing, useVarargs, warn);
|
||||
}
|
||||
catch (Resolve.InapplicableMethodException ex) {
|
||||
// inferred method is not applicable
|
||||
throw invalidInstanceException.setMessage(ex.getDiagnostic());
|
||||
}
|
||||
}
|
||||
|
||||
/** Try to instantiate argument type `that' to given type `to'.
|
||||
* If this fails, try to insantiate `that' to `to' where
|
||||
* every occurrence of a type variable in `tvars' is replaced
|
||||
|
||||
@ -68,7 +68,6 @@ public class Lower extends TreeTranslator {
|
||||
private Names names;
|
||||
private Log log;
|
||||
private Symtab syms;
|
||||
private Scope.ScopeCounter scopeCounter;
|
||||
private Resolve rs;
|
||||
private Check chk;
|
||||
private Attr attr;
|
||||
@ -91,7 +90,6 @@ public class Lower extends TreeTranslator {
|
||||
names = Names.instance(context);
|
||||
log = Log.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
scopeCounter = Scope.ScopeCounter.instance(context);
|
||||
rs = Resolve.instance(context);
|
||||
chk = Check.instance(context);
|
||||
attr = Attr.instance(context);
|
||||
@ -571,7 +569,7 @@ public class Lower extends TreeTranslator {
|
||||
c.flatname = chk.localClassName(c);
|
||||
c.sourcefile = owner.sourcefile;
|
||||
c.completer = null;
|
||||
c.members_field = new Scope.ClassScope(c, scopeCounter);
|
||||
c.members_field = new Scope(c);
|
||||
c.flags_field = flags;
|
||||
ClassType ctype = (ClassType) c.type;
|
||||
ctype.supertype_field = syms.objectType;
|
||||
|
||||
@ -67,7 +67,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
private final Check chk;
|
||||
private final Attr attr;
|
||||
private final Symtab syms;
|
||||
private final Scope.ScopeCounter scopeCounter;
|
||||
private final TreeMaker make;
|
||||
private final ClassReader reader;
|
||||
private final Todo todo;
|
||||
@ -75,9 +74,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
private final Types types;
|
||||
private final JCDiagnostic.Factory diags;
|
||||
private final Target target;
|
||||
private final DeferredLintHandler deferredLintHandler;
|
||||
|
||||
private final boolean skipAnnotations;
|
||||
private final boolean allowSimplifiedVarargs;
|
||||
|
||||
public static MemberEnter instance(Context context) {
|
||||
MemberEnter instance = context.get(memberEnterKey);
|
||||
@ -94,7 +93,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
chk = Check.instance(context);
|
||||
attr = Attr.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
scopeCounter = Scope.ScopeCounter.instance(context);
|
||||
make = TreeMaker.instance(context);
|
||||
reader = ClassReader.instance(context);
|
||||
todo = Todo.instance(context);
|
||||
@ -102,10 +100,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
types = Types.instance(context);
|
||||
diags = JCDiagnostic.Factory.instance(context);
|
||||
target = Target.instance(context);
|
||||
deferredLintHandler = DeferredLintHandler.instance(context);
|
||||
Options options = Options.instance(context);
|
||||
skipAnnotations = options.isSet("skipAnnotations");
|
||||
Source source = Source.instance(context);
|
||||
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
|
||||
}
|
||||
|
||||
/** A queue for classes whose members still need to be entered into the
|
||||
@ -571,10 +568,16 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
tree.sym = m;
|
||||
Env<AttrContext> localEnv = methodEnv(tree, env);
|
||||
|
||||
// Compute the method type
|
||||
m.type = signature(tree.typarams, tree.params,
|
||||
tree.restype, tree.thrown,
|
||||
localEnv);
|
||||
DeferredLintHandler prevLintHandler =
|
||||
chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
|
||||
try {
|
||||
// Compute the method type
|
||||
m.type = signature(tree.typarams, tree.params,
|
||||
tree.restype, tree.thrown,
|
||||
localEnv);
|
||||
} finally {
|
||||
chk.setDeferredLintHandler(prevLintHandler);
|
||||
}
|
||||
|
||||
// Set m.params
|
||||
ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>();
|
||||
@ -618,7 +621,14 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
localEnv = env.dup(tree, env.info.dup());
|
||||
localEnv.info.staticLevel++;
|
||||
}
|
||||
attr.attribType(tree.vartype, localEnv);
|
||||
DeferredLintHandler prevLintHandler =
|
||||
chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
|
||||
try {
|
||||
attr.attribType(tree.vartype, localEnv);
|
||||
} finally {
|
||||
chk.setDeferredLintHandler(prevLintHandler);
|
||||
}
|
||||
|
||||
if ((tree.mods.flags & VARARGS) != 0) {
|
||||
//if we are entering a varargs parameter, we need to replace its type
|
||||
//(a plain array type) with the more precise VarargsType --- we need
|
||||
@ -637,7 +647,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) {
|
||||
Env<AttrContext> initEnv = getInitEnv(tree, env);
|
||||
initEnv.info.enclVar = v;
|
||||
v.setLazyConstValue(initEnv(tree, initEnv), log, attr, tree.init);
|
||||
v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init);
|
||||
}
|
||||
}
|
||||
if (chk.checkUnique(tree.pos(), v, enclScope)) {
|
||||
@ -775,10 +785,11 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
&& s.owner.kind != MTH
|
||||
&& types.isSameType(c.type, syms.deprecatedType))
|
||||
s.flags_field |= Flags.DEPRECATED;
|
||||
// Internally to java.dyn, a @PolymorphicSignature annotation
|
||||
// Internally to java.lang.invoke, a @PolymorphicSignature annotation
|
||||
// acts like a classfile attribute.
|
||||
if (!c.type.isErroneous() &&
|
||||
types.isSameType(c.type, syms.polymorphicSignatureType)) {
|
||||
(types.isSameType(c.type, syms.polymorphicSignatureType) ||
|
||||
types.isSameType(c.type, syms.transientPolymorphicSignatureType))) {
|
||||
if (!target.hasMethodHandles()) {
|
||||
// Somebody is compiling JDK7 source code to a JDK6 target.
|
||||
// Make it an error, since it is unlikely but important.
|
||||
@ -1010,7 +1021,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
}
|
||||
|
||||
private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
|
||||
Scope baseScope = new Scope.ClassScope(tree.sym, scopeCounter);
|
||||
Scope baseScope = new Scope(tree.sym);
|
||||
//import already entered local classes into base scope
|
||||
for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) {
|
||||
if (e.sym.isLocal()) {
|
||||
|
||||
@ -278,7 +278,7 @@ public class Resolve {
|
||||
return true;
|
||||
else {
|
||||
Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
|
||||
return (s2 == null || s2 == sym ||
|
||||
return (s2 == null || s2 == sym || sym.owner == s2.owner ||
|
||||
s2.isPolymorphicSignatureGeneric() ||
|
||||
!types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
|
||||
}
|
||||
@ -331,7 +331,7 @@ public class Resolve {
|
||||
throws Infer.InferenceException {
|
||||
boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
|
||||
if (useVarargs && (m.flags() & VARARGS) == 0)
|
||||
throw inapplicableMethodException.setMessage(null);
|
||||
throw inapplicableMethodException.setMessage();
|
||||
Type mt = types.memberType(site, m);
|
||||
|
||||
// tvars is the list of formal type variables for which type arguments
|
||||
@ -386,7 +386,7 @@ public class Resolve {
|
||||
useVarargs,
|
||||
warn);
|
||||
|
||||
checkRawArgumentsAcceptable(argtypes, mt.getParameterTypes(),
|
||||
checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(),
|
||||
allowBoxing, useVarargs, warn);
|
||||
return mt;
|
||||
}
|
||||
@ -411,19 +411,21 @@ public class Resolve {
|
||||
|
||||
/** Check if a parameter list accepts a list of args.
|
||||
*/
|
||||
boolean argumentsAcceptable(List<Type> argtypes,
|
||||
boolean argumentsAcceptable(Env<AttrContext> env,
|
||||
List<Type> argtypes,
|
||||
List<Type> formals,
|
||||
boolean allowBoxing,
|
||||
boolean useVarargs,
|
||||
Warner warn) {
|
||||
try {
|
||||
checkRawArgumentsAcceptable(argtypes, formals, allowBoxing, useVarargs, warn);
|
||||
checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn);
|
||||
return true;
|
||||
} catch (InapplicableMethodException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void checkRawArgumentsAcceptable(List<Type> argtypes,
|
||||
void checkRawArgumentsAcceptable(Env<AttrContext> env,
|
||||
List<Type> argtypes,
|
||||
List<Type> formals,
|
||||
boolean allowBoxing,
|
||||
boolean useVarargs,
|
||||
@ -460,6 +462,14 @@ public class Resolve {
|
||||
elt);
|
||||
argtypes = argtypes.tail;
|
||||
}
|
||||
//check varargs element type accessibility
|
||||
if (!isAccessible(env, elt)) {
|
||||
Symbol location = env.enclClass.sym;
|
||||
throw inapplicableMethodException.setMessage("inaccessible.varargs.type",
|
||||
elt,
|
||||
Kinds.kindName(location),
|
||||
location);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -474,6 +484,10 @@ public class Resolve {
|
||||
this.diagnostic = null;
|
||||
this.diags = diags;
|
||||
}
|
||||
InapplicableMethodException setMessage() {
|
||||
this.diagnostic = null;
|
||||
return this;
|
||||
}
|
||||
InapplicableMethodException setMessage(String key) {
|
||||
this.diagnostic = key != null ? diags.fragment(key) : null;
|
||||
return this;
|
||||
@ -482,6 +496,10 @@ public class Resolve {
|
||||
this.diagnostic = key != null ? diags.fragment(key, args) : null;
|
||||
return this;
|
||||
}
|
||||
InapplicableMethodException setMessage(JCDiagnostic diag) {
|
||||
this.diagnostic = diag;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JCDiagnostic getDiagnostic() {
|
||||
return diagnostic;
|
||||
@ -712,13 +730,14 @@ public class Resolve {
|
||||
Type mt1 = types.memberType(site, m1);
|
||||
Type mt2 = types.memberType(site, m2);
|
||||
if (!types.overrideEquivalent(mt1, mt2))
|
||||
return new AmbiguityError(m1, m2);
|
||||
return ambiguityError(m1, m2);
|
||||
|
||||
// same signature; select (a) the non-bridge method, or
|
||||
// (b) the one that overrides the other, or (c) the concrete
|
||||
// one, or (d) merge both abstract signatures
|
||||
if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) {
|
||||
if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
|
||||
return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
|
||||
}
|
||||
|
||||
// if one overrides or hides the other, use it
|
||||
TypeSymbol m1Owner = (TypeSymbol)m1.owner;
|
||||
TypeSymbol m2Owner = (TypeSymbol)m2.owner;
|
||||
@ -738,24 +757,24 @@ public class Resolve {
|
||||
if (m2Abstract && !m1Abstract) return m1;
|
||||
// both abstract or both concrete
|
||||
if (!m1Abstract && !m2Abstract)
|
||||
return new AmbiguityError(m1, m2);
|
||||
return ambiguityError(m1, m2);
|
||||
// check that both signatures have the same erasure
|
||||
if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
|
||||
m2.erasure(types).getParameterTypes()))
|
||||
return new AmbiguityError(m1, m2);
|
||||
return ambiguityError(m1, m2);
|
||||
// both abstract, neither overridden; merge throws clause and result type
|
||||
Symbol mostSpecific;
|
||||
Type result2 = mt2.getReturnType();
|
||||
if (mt2.tag == FORALL)
|
||||
result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
|
||||
if (types.isSubtype(mt1.getReturnType(), result2)) {
|
||||
if (types.isSubtype(mt1.getReturnType(), result2))
|
||||
mostSpecific = m1;
|
||||
} else if (types.isSubtype(result2, mt1.getReturnType())) {
|
||||
else if (types.isSubtype(result2, mt1.getReturnType()))
|
||||
mostSpecific = m2;
|
||||
} else {
|
||||
else {
|
||||
// Theoretically, this can't happen, but it is possible
|
||||
// due to error recovery or mixing incompatible class files
|
||||
return new AmbiguityError(m1, m2);
|
||||
return ambiguityError(m1, m2);
|
||||
}
|
||||
MethodSymbol result = new MethodSymbol(
|
||||
mostSpecific.flags(),
|
||||
@ -777,7 +796,7 @@ public class Resolve {
|
||||
}
|
||||
if (m1SignatureMoreSpecific) return m1;
|
||||
if (m2SignatureMoreSpecific) return m2;
|
||||
return new AmbiguityError(m1, m2);
|
||||
return ambiguityError(m1, m2);
|
||||
case AMBIGUOUS:
|
||||
AmbiguityError e = (AmbiguityError)m2;
|
||||
Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
|
||||
@ -787,9 +806,9 @@ public class Resolve {
|
||||
if (err1 instanceof AmbiguityError &&
|
||||
err2 instanceof AmbiguityError &&
|
||||
((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
|
||||
return new AmbiguityError(m1, m2);
|
||||
return ambiguityError(m1, m2);
|
||||
else
|
||||
return new AmbiguityError(err1, err2);
|
||||
return ambiguityError(err1, err2);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
@ -844,6 +863,14 @@ public class Resolve {
|
||||
return to;
|
||||
}
|
||||
}
|
||||
//where
|
||||
Symbol ambiguityError(Symbol m1, Symbol m2) {
|
||||
if (((m1.flags() | m2.flags()) & CLASH) != 0) {
|
||||
return (m1.flags() & CLASH) == 0 ? m1 : m2;
|
||||
} else {
|
||||
return new AmbiguityError(m1, m2);
|
||||
}
|
||||
}
|
||||
|
||||
/** Find best qualified method matching given name, type and value
|
||||
* arguments.
|
||||
@ -1611,10 +1638,7 @@ public class Resolve {
|
||||
names.init, argtypes,
|
||||
typeargtypes, allowBoxing,
|
||||
useVarargs, false);
|
||||
if ((sym.flags() & DEPRECATED) != 0 &&
|
||||
(env.info.scope.owner.flags() & DEPRECATED) == 0 &&
|
||||
env.info.scope.owner.outermostClass() != sym.outermostClass())
|
||||
chk.warnDeprecated(pos, sym);
|
||||
chk.checkDeprecated(pos, env.info.scope.owner, sym);
|
||||
return sym;
|
||||
}
|
||||
|
||||
@ -1928,6 +1952,9 @@ public class Resolve {
|
||||
key, name, first, second);
|
||||
}
|
||||
boolean hasLocation = false;
|
||||
if (location == null) {
|
||||
location = site.tsym;
|
||||
}
|
||||
if (!location.name.isEmpty()) {
|
||||
if (location.kind == PCK && !site.tsym.exists()) {
|
||||
return diags.create(dkind, log.currentSource(), pos,
|
||||
@ -1945,7 +1972,7 @@ public class Resolve {
|
||||
return diags.create(dkind, log.currentSource(), pos,
|
||||
errKey, kindname, idname, //symbol kindname, name
|
||||
typeargtypes, argtypes, //type parameters and arguments (if any)
|
||||
getLocationDiag(location)); //location kindname, type
|
||||
getLocationDiag(location, site)); //location kindname, type
|
||||
}
|
||||
else {
|
||||
return diags.create(dkind, log.currentSource(), pos,
|
||||
@ -1966,15 +1993,18 @@ public class Resolve {
|
||||
}
|
||||
return key + suffix;
|
||||
}
|
||||
private JCDiagnostic getLocationDiag(Symbol location) {
|
||||
boolean isVar = location.kind == VAR;
|
||||
String key = isVar ?
|
||||
"location.1" :
|
||||
"location";
|
||||
return diags.fragment(key,
|
||||
private JCDiagnostic getLocationDiag(Symbol location, Type site) {
|
||||
if (location.kind == VAR) {
|
||||
return diags.fragment("location.1",
|
||||
kindName(location),
|
||||
location,
|
||||
isVar ? location.type : null);
|
||||
location.type);
|
||||
} else {
|
||||
return diags.fragment("location",
|
||||
typeKindName(site),
|
||||
site,
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2025,8 +2055,14 @@ public class Resolve {
|
||||
return null;
|
||||
|
||||
if (isOperator(name)) {
|
||||
return diags.create(dkind, log.currentSource(),
|
||||
pos, "operator.cant.be.applied", name, argtypes);
|
||||
boolean isUnaryOp = argtypes.size() == 1;
|
||||
String key = argtypes.size() == 1 ?
|
||||
"operator.cant.be.applied" :
|
||||
"operator.cant.be.applied.1";
|
||||
Type first = argtypes.head;
|
||||
Type second = !isUnaryOp ? argtypes.tail.head : null;
|
||||
return diags.create(dkind, log.currentSource(), pos,
|
||||
key, name, first, second);
|
||||
}
|
||||
else {
|
||||
Symbol ws = sym.asMemberOf(site, types);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,11 +28,11 @@ package com.sun.tools.javac.file;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.sun.tools.javac.util.Context;
|
||||
|
||||
/**
|
||||
* Caching implementation of FSInfo.
|
||||
*
|
||||
|
||||
@ -76,8 +76,6 @@ import static com.sun.tools.javac.main.OptionName.*;
|
||||
*/
|
||||
public class JavacFileManager extends BaseFileManager implements StandardJavaFileManager {
|
||||
|
||||
boolean useZipFileIndex;
|
||||
|
||||
public static char[] toArray(CharBuffer buffer) {
|
||||
if (buffer.hasArray())
|
||||
return ((CharBuffer)buffer.compact().flip()).array();
|
||||
@ -91,6 +89,9 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
|
||||
private FSInfo fsInfo;
|
||||
|
||||
private boolean useZipFileIndex;
|
||||
private ZipFileIndexCache zipFileIndexCache;
|
||||
|
||||
private final File uninited = new File("U N I N I T E D");
|
||||
|
||||
private final Set<JavaFileObject.Kind> sourceOrClass =
|
||||
@ -163,7 +164,11 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
|
||||
fsInfo = FSInfo.instance(context);
|
||||
|
||||
useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null;
|
||||
// retain check for system property for compatibility
|
||||
useZipFileIndex = options.isUnset("useJavaUtilZip")
|
||||
&& System.getProperty("useJavaUtilZip") == null;
|
||||
if (useZipFileIndex)
|
||||
zipFileIndexCache = ZipFileIndexCache.getSharedInstance();
|
||||
|
||||
mmappedIO = options.isSet("mmappedIO");
|
||||
ignoreSymbolFile = options.isSet("ignore.symbol.file");
|
||||
@ -526,7 +531,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
archive = new ZipArchive(this, zdir);
|
||||
} else {
|
||||
archive = new ZipFileIndexArchive(this,
|
||||
ZipFileIndex.getZipFileIndex(zipFileName,
|
||||
zipFileIndexCache.getZipFileIndex(zipFileName,
|
||||
null,
|
||||
usePreindexedCache,
|
||||
preindexCacheLocation,
|
||||
@ -538,7 +543,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
}
|
||||
else {
|
||||
archive = new ZipFileIndexArchive(this,
|
||||
ZipFileIndex.getZipFileIndex(zipFileName,
|
||||
zipFileIndexCache.getZipFileIndex(zipFileName,
|
||||
symbolFilePrefix,
|
||||
usePreindexedCache,
|
||||
preindexCacheLocation,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,11 +38,9 @@ import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.ZipException;
|
||||
@ -50,24 +48,28 @@ import java.util.zip.ZipException;
|
||||
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
|
||||
import com.sun.tools.javac.file.RelativePath.RelativeFile;
|
||||
|
||||
/** This class implements building of index of a zip archive and access to it's context.
|
||||
* It also uses prebuild index if available. It supports invocations where it will
|
||||
* serialize an optimized zip index file to disk.
|
||||
/**
|
||||
* This class implements the building of index of a zip archive and access to
|
||||
* its context. It also uses a prebuilt index if available.
|
||||
* It supports invocations where it will serialize an optimized zip index file
|
||||
* to disk.
|
||||
*
|
||||
* In oreder to use secondary index file make sure the option "usezipindex" is in the Options object,
|
||||
* when JavacFileManager is invoked. (You can pass "-XDusezipindex" on the command line.
|
||||
* In order to use a secondary index file, set "usezipindex" in the Options
|
||||
* object when JavacFileManager is invoked. (You can pass "-XDusezipindex" on
|
||||
* the command line.)
|
||||
*
|
||||
* Location where to look for/generate optimized zip index files can be provided using
|
||||
* "-XDcachezipindexdir=<directory>". If this flag is not provided, the dfault location is
|
||||
* the value of the "java.io.tmpdir" system property.
|
||||
* Location where to look for/generate optimized zip index files can be
|
||||
* provided using "-XDcachezipindexdir=<directory>". If this flag is not
|
||||
* provided, the default location is the value of the "java.io.tmpdir" system
|
||||
* property.
|
||||
*
|
||||
* If key "-XDwritezipindexfiles" is specified, there will be new optimized index file
|
||||
* created for each archive, used by the compiler for compilation, at location,
|
||||
* specified by "cachezipindexdir" option.
|
||||
* If "-XDwritezipindexfiles" is specified, there will be new optimized index
|
||||
* file created for each archive, used by the compiler for compilation, at the
|
||||
* location specified by the "cachezipindexdir" option.
|
||||
*
|
||||
* If nonBatchMode option is specified (-XDnonBatchMode) the compiler will use timestamp
|
||||
* checking to reindex the zip files if it is needed. In batch mode the timestamps are not checked
|
||||
* and the compiler uses the cached indexes.
|
||||
* If system property nonBatchMode option is specified the compiler will use
|
||||
* timestamp checking to reindex the zip files if it is needed. In batch mode
|
||||
* the timestamps are not checked and the compiler uses the cached indexes.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
@ -80,18 +82,18 @@ public class ZipFileIndex {
|
||||
|
||||
public final static long NOT_MODIFIED = Long.MIN_VALUE;
|
||||
|
||||
private static Map<File, ZipFileIndex> zipFileIndexCache = new HashMap<File, ZipFileIndex>();
|
||||
private static ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
|
||||
|
||||
private Map<RelativeDirectory, DirectoryEntry> directories = Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
|
||||
private Set<RelativeDirectory> allDirs = Collections.<RelativeDirectory>emptySet();
|
||||
private Map<RelativeDirectory, DirectoryEntry> directories =
|
||||
Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
|
||||
private Set<RelativeDirectory> allDirs =
|
||||
Collections.<RelativeDirectory>emptySet();
|
||||
|
||||
// ZipFileIndex data entries
|
||||
private File zipFile;
|
||||
final File zipFile;
|
||||
private Reference<File> absFileRef;
|
||||
private long zipFileLastModified = NOT_MODIFIED;
|
||||
long zipFileLastModified = NOT_MODIFIED;
|
||||
private RandomAccessFile zipRandomFile;
|
||||
private Entry[] entries;
|
||||
|
||||
@ -99,156 +101,24 @@ public class ZipFileIndex {
|
||||
private File zipIndexFile = null;
|
||||
private boolean triedToReadIndex = false;
|
||||
final RelativeDirectory symbolFilePrefix;
|
||||
private int symbolFilePrefixLength = 0;
|
||||
private final int symbolFilePrefixLength;
|
||||
private boolean hasPopulatedData = false;
|
||||
private long lastReferenceTimeStamp = NOT_MODIFIED;
|
||||
long lastReferenceTimeStamp = NOT_MODIFIED;
|
||||
|
||||
private boolean usePreindexedCache = false;
|
||||
private String preindexedCacheLocation = null;
|
||||
private final boolean usePreindexedCache;
|
||||
private final String preindexedCacheLocation;
|
||||
|
||||
private boolean writeIndex = false;
|
||||
|
||||
private Map <String, SoftReference<RelativeDirectory>> relativeDirectoryCache =
|
||||
private Map<String, SoftReference<RelativeDirectory>> relativeDirectoryCache =
|
||||
new HashMap<String, SoftReference<RelativeDirectory>>();
|
||||
|
||||
/**
|
||||
* Returns a list of all ZipFileIndex entries
|
||||
*
|
||||
* @return A list of ZipFileIndex entries, or an empty list
|
||||
*/
|
||||
public static List<ZipFileIndex> getZipFileIndexes() {
|
||||
return getZipFileIndexes(false);
|
||||
|
||||
public synchronized boolean isOpen() {
|
||||
return (zipRandomFile != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all ZipFileIndex entries
|
||||
*
|
||||
* @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise
|
||||
* all ZipFileEntry(s) are included into the list.
|
||||
* @return A list of ZipFileIndex entries, or an empty list
|
||||
*/
|
||||
public static List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) {
|
||||
List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>();
|
||||
lock.lock();
|
||||
try {
|
||||
zipFileIndexes.addAll(zipFileIndexCache.values());
|
||||
|
||||
if (openedOnly) {
|
||||
for(ZipFileIndex elem : zipFileIndexes) {
|
||||
if (!elem.isOpen()) {
|
||||
zipFileIndexes.remove(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return zipFileIndexes;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
lock.lock();
|
||||
try {
|
||||
return zipRandomFile != null;
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static ZipFileIndex getZipFileIndex(File zipFile,
|
||||
RelativeDirectory symbolFilePrefix,
|
||||
boolean useCache, String cacheLocation,
|
||||
boolean writeIndex) throws IOException {
|
||||
ZipFileIndex zi = null;
|
||||
lock.lock();
|
||||
try {
|
||||
zi = getExistingZipIndex(zipFile);
|
||||
|
||||
if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
|
||||
zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
|
||||
useCache, cacheLocation);
|
||||
zipFileIndexCache.put(zipFile, zi);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return zi;
|
||||
}
|
||||
|
||||
public static ZipFileIndex getExistingZipIndex(File zipFile) {
|
||||
lock.lock();
|
||||
try {
|
||||
return zipFileIndexCache.get(zipFile);
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
lock.lock();
|
||||
try {
|
||||
zipFileIndexCache.clear();
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearCache(long timeNotUsed) {
|
||||
lock.lock();
|
||||
try {
|
||||
Iterator<File> cachedFileIterator = zipFileIndexCache.keySet().iterator();
|
||||
while (cachedFileIterator.hasNext()) {
|
||||
File cachedFile = cachedFileIterator.next();
|
||||
ZipFileIndex cachedZipIndex = zipFileIndexCache.get(cachedFile);
|
||||
if (cachedZipIndex != null) {
|
||||
long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
|
||||
if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow...
|
||||
System.currentTimeMillis() > timeToTest) {
|
||||
zipFileIndexCache.remove(cachedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeFromCache(File file) {
|
||||
lock.lock();
|
||||
try {
|
||||
zipFileIndexCache.remove(file);
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets already opened list of ZipFileIndexes from an outside client
|
||||
* of the compiler. This functionality should be used in a non-batch clients of the compiler.
|
||||
*/
|
||||
public static void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException {
|
||||
lock.lock();
|
||||
try {
|
||||
if (zipFileIndexCache.isEmpty()) {
|
||||
throw new IllegalStateException("Setting opened indexes should be called only when the ZipFileCache is empty. Call JavacFileManager.flush() before calling this method.");
|
||||
}
|
||||
|
||||
for (ZipFileIndex zfi : indexes) {
|
||||
zipFileIndexCache.put(zfi.zipFile, zfi);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
|
||||
ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
|
||||
boolean useCache, String cacheLocation) throws IOException {
|
||||
this.zipFile = zipFile;
|
||||
this.symbolFilePrefix = symbolFilePrefix;
|
||||
@ -266,19 +136,22 @@ public class ZipFileIndex {
|
||||
checkIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ZipFileIndex[" + zipFile + "]";
|
||||
}
|
||||
|
||||
// Just in case...
|
||||
protected void finalize() {
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
closeFile();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private boolean isUpToDate() {
|
||||
if (zipFile != null &&
|
||||
((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified()) &&
|
||||
hasPopulatedData) {
|
||||
if (zipFile != null
|
||||
&& ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified())
|
||||
&& hasPopulatedData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -339,15 +212,9 @@ public class ZipFileIndex {
|
||||
allDirs = Collections.<RelativeDirectory>emptySet();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
lock.lock();
|
||||
try {
|
||||
writeIndex();
|
||||
closeFile();
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
public synchronized void close() {
|
||||
writeIndex();
|
||||
closeFile();
|
||||
}
|
||||
|
||||
private void closeFile() {
|
||||
@ -361,29 +228,24 @@ public class ZipFileIndex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ZipFileIndexEntry for an absolute path, if there is one.
|
||||
* Returns the ZipFileIndexEntry for a path, if there is one.
|
||||
*/
|
||||
Entry getZipIndexEntry(RelativePath path) {
|
||||
lock.lock();
|
||||
synchronized Entry getZipIndexEntry(RelativePath path) {
|
||||
try {
|
||||
checkIndex();
|
||||
DirectoryEntry de = directories.get(path.dirname());
|
||||
String lookFor = path.basename();
|
||||
return de == null ? null : de.getEntry(lookFor);
|
||||
return (de == null) ? null : de.getEntry(lookFor);
|
||||
}
|
||||
catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a javac List of filenames within an absolute path in the ZipFileIndex.
|
||||
* Returns a javac List of filenames within a directory in the ZipFileIndex.
|
||||
*/
|
||||
public com.sun.tools.javac.util.List<String> getFiles(RelativeDirectory path) {
|
||||
lock.lock();
|
||||
public synchronized com.sun.tools.javac.util.List<String> getFiles(RelativeDirectory path) {
|
||||
try {
|
||||
checkIndex();
|
||||
|
||||
@ -398,13 +260,9 @@ public class ZipFileIndex {
|
||||
catch (IOException e) {
|
||||
return com.sun.tools.javac.util.List.<String>nil();
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getDirectories(RelativeDirectory path) {
|
||||
lock.lock();
|
||||
public synchronized List<String> getDirectories(RelativeDirectory path) {
|
||||
try {
|
||||
checkIndex();
|
||||
|
||||
@ -420,13 +278,9 @@ public class ZipFileIndex {
|
||||
catch (IOException e) {
|
||||
return com.sun.tools.javac.util.List.<String>nil();
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Set<RelativeDirectory> getAllDirectories() {
|
||||
lock.lock();
|
||||
public synchronized Set<RelativeDirectory> getAllDirectories() {
|
||||
try {
|
||||
checkIndex();
|
||||
if (allDirs == Collections.EMPTY_SET) {
|
||||
@ -438,9 +292,6 @@ public class ZipFileIndex {
|
||||
catch (IOException e) {
|
||||
return Collections.<RelativeDirectory>emptySet();
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -450,8 +301,7 @@ public class ZipFileIndex {
|
||||
* @param path A path within the zip.
|
||||
* @return True if the path is a file or dir, false otherwise.
|
||||
*/
|
||||
public boolean contains(RelativePath path) {
|
||||
lock.lock();
|
||||
public synchronized boolean contains(RelativePath path) {
|
||||
try {
|
||||
checkIndex();
|
||||
return getZipIndexEntry(path) != null;
|
||||
@ -459,114 +309,69 @@ public class ZipFileIndex {
|
||||
catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public synchronized boolean isDirectory(RelativePath path) throws IOException {
|
||||
// The top level in a zip file is always a directory.
|
||||
if (path.getPath().length() == 0) {
|
||||
lastReferenceTimeStamp = System.currentTimeMillis();
|
||||
return true;
|
||||
}
|
||||
|
||||
checkIndex();
|
||||
return directories.get(path) != null;
|
||||
}
|
||||
|
||||
public synchronized long getLastModified(RelativeFile path) throws IOException {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException();
|
||||
return entry.getLastModified();
|
||||
}
|
||||
|
||||
public synchronized int length(RelativeFile path) throws IOException {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException();
|
||||
|
||||
if (entry.isDir) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] header = getHeader(entry);
|
||||
// entry is not compressed?
|
||||
if (get2ByteLittleEndian(header, 8) == 0) {
|
||||
return entry.compressedSize;
|
||||
} else {
|
||||
return entry.size;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDirectory(RelativePath path) throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
// The top level in a zip file is always a directory.
|
||||
if (path.getPath().length() == 0) {
|
||||
lastReferenceTimeStamp = System.currentTimeMillis();
|
||||
return true;
|
||||
}
|
||||
|
||||
checkIndex();
|
||||
return directories.get(path) != null;
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
public synchronized byte[] read(RelativeFile path) throws IOException {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException("Path not found in ZIP: " + path.path);
|
||||
return read(entry);
|
||||
}
|
||||
|
||||
public long getLastModified(RelativeFile path) throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException();
|
||||
return entry.getLastModified();
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
synchronized byte[] read(Entry entry) throws IOException {
|
||||
openFile();
|
||||
byte[] result = readBytes(entry);
|
||||
closeFile();
|
||||
return result;
|
||||
}
|
||||
|
||||
public int length(RelativeFile path) throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException();
|
||||
|
||||
if (entry.isDir) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte[] header = getHeader(entry);
|
||||
// entry is not compressed?
|
||||
if (get2ByteLittleEndian(header, 8) == 0) {
|
||||
return entry.compressedSize;
|
||||
} else {
|
||||
return entry.size;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
public synchronized int read(RelativeFile path, byte[] buffer) throws IOException {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException();
|
||||
return read(entry, buffer);
|
||||
}
|
||||
|
||||
public byte[] read(RelativeFile path) throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException("Path not found in ZIP: " + path.path);
|
||||
return read(entry);
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
byte[] read(Entry entry) throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
openFile();
|
||||
byte[] result = readBytes(entry);
|
||||
closeFile();
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int read(RelativeFile path, byte[] buffer) throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
Entry entry = getZipIndexEntry(path);
|
||||
if (entry == null)
|
||||
throw new FileNotFoundException();
|
||||
return read(entry, buffer);
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
int read(Entry entry, byte[] buffer)
|
||||
synchronized int read(Entry entry, byte[] buffer)
|
||||
throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
int result = readBytes(entry, buffer);
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
int result = readBytes(entry, buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
private byte[] readBytes(Entry entry) throws IOException {
|
||||
@ -638,21 +443,20 @@ public class ZipFileIndex {
|
||||
/*
|
||||
* Inflate using the java.util.zip.Inflater class
|
||||
*/
|
||||
private static Inflater inflater;
|
||||
private SoftReference<Inflater> inflaterRef;
|
||||
private int inflate(byte[] src, byte[] dest) {
|
||||
Inflater inflater = (inflaterRef == null ? null : inflaterRef.get());
|
||||
|
||||
// construct the inflater object or reuse an existing one
|
||||
if (inflater == null)
|
||||
inflater = new Inflater(true);
|
||||
inflaterRef = new SoftReference<Inflater>(inflater = new Inflater(true));
|
||||
|
||||
synchronized (inflater) {
|
||||
inflater.reset();
|
||||
inflater.setInput(src);
|
||||
try {
|
||||
return inflater.inflate(dest);
|
||||
} catch (DataFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
inflater.reset();
|
||||
inflater.setInput(src);
|
||||
try {
|
||||
return inflater.inflate(dest);
|
||||
} catch (DataFormatException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,14 +659,10 @@ public class ZipFileIndex {
|
||||
* @return long
|
||||
*/
|
||||
public long getZipFileLastModified() throws IOException {
|
||||
lock.lock();
|
||||
try {
|
||||
synchronized (this) {
|
||||
checkIndex();
|
||||
return zipFileLastModified;
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------
|
||||
@ -1028,8 +828,7 @@ public class ZipFileIndex {
|
||||
}
|
||||
|
||||
boolean ret = false;
|
||||
lock.lock();
|
||||
try {
|
||||
synchronized (this) {
|
||||
triedToReadIndex = true;
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
@ -1071,9 +870,6 @@ public class ZipFileIndex {
|
||||
readFromIndex = true;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1144,8 +940,8 @@ public class ZipFileIndex {
|
||||
raf.seek(currFP);
|
||||
|
||||
// Now write each of the files in the DirectoryEntry
|
||||
List<Entry> entries = de.getEntriesAsCollection();
|
||||
for (Entry zfie : entries) {
|
||||
List<Entry> list = de.getEntriesAsCollection();
|
||||
for (Entry zfie : list) {
|
||||
// Write the name bytes
|
||||
byte [] zfieNameBytes = zfie.name.getBytes("UTF-8");
|
||||
int zfieNameBytesLen = zfieNameBytes.length;
|
||||
@ -1191,13 +987,9 @@ public class ZipFileIndex {
|
||||
}
|
||||
|
||||
public boolean writeZipIndex() {
|
||||
lock.lock();
|
||||
try {
|
||||
synchronized (this) {
|
||||
return writeIndex();
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private File getIndexFile() {
|
||||
@ -1328,7 +1120,7 @@ public class ZipFileIndex {
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return isDir ? ("Dir:" + dir + " : " + name) :
|
||||
(dir + ":" + name);
|
||||
|
||||
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.file;
|
||||
|
||||
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/** A cache for ZipFileIndex objects. */
|
||||
public class ZipFileIndexCache {
|
||||
|
||||
private final Map<File, ZipFileIndex> map =
|
||||
new HashMap<File, ZipFileIndex>();
|
||||
|
||||
/** Get a shared instance of the cache. */
|
||||
private static ZipFileIndexCache sharedInstance;
|
||||
public synchronized static ZipFileIndexCache getSharedInstance() {
|
||||
if (sharedInstance == null)
|
||||
sharedInstance = new ZipFileIndexCache();
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
/** Get a context-specific instance of a cache. */
|
||||
public static ZipFileIndexCache instance(Context context) {
|
||||
ZipFileIndexCache instance = context.get(ZipFileIndexCache.class);
|
||||
if (instance == null)
|
||||
context.put(ZipFileIndexCache.class, instance = new ZipFileIndexCache());
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all ZipFileIndex entries
|
||||
*
|
||||
* @return A list of ZipFileIndex entries, or an empty list
|
||||
*/
|
||||
public List<ZipFileIndex> getZipFileIndexes() {
|
||||
return getZipFileIndexes(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all ZipFileIndex entries
|
||||
*
|
||||
* @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise
|
||||
* all ZipFileEntry(s) are included into the list.
|
||||
* @return A list of ZipFileIndex entries, or an empty list
|
||||
*/
|
||||
public synchronized List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) {
|
||||
List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>();
|
||||
|
||||
zipFileIndexes.addAll(map.values());
|
||||
|
||||
if (openedOnly) {
|
||||
for(ZipFileIndex elem : zipFileIndexes) {
|
||||
if (!elem.isOpen()) {
|
||||
zipFileIndexes.remove(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return zipFileIndexes;
|
||||
}
|
||||
|
||||
public synchronized ZipFileIndex getZipFileIndex(File zipFile,
|
||||
RelativeDirectory symbolFilePrefix,
|
||||
boolean useCache, String cacheLocation,
|
||||
boolean writeIndex) throws IOException {
|
||||
ZipFileIndex zi = getExistingZipIndex(zipFile);
|
||||
|
||||
if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
|
||||
zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
|
||||
useCache, cacheLocation);
|
||||
map.put(zipFile, zi);
|
||||
}
|
||||
return zi;
|
||||
}
|
||||
|
||||
public synchronized ZipFileIndex getExistingZipIndex(File zipFile) {
|
||||
return map.get(zipFile);
|
||||
}
|
||||
|
||||
public synchronized void clearCache() {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public synchronized void clearCache(long timeNotUsed) {
|
||||
Iterator<File> cachedFileIterator = map.keySet().iterator();
|
||||
while (cachedFileIterator.hasNext()) {
|
||||
File cachedFile = cachedFileIterator.next();
|
||||
ZipFileIndex cachedZipIndex = map.get(cachedFile);
|
||||
if (cachedZipIndex != null) {
|
||||
long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
|
||||
if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow...
|
||||
System.currentTimeMillis() > timeToTest) {
|
||||
map.remove(cachedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeFromCache(File file) {
|
||||
map.remove(file);
|
||||
}
|
||||
|
||||
/** Sets already opened list of ZipFileIndexes from an outside client
|
||||
* of the compiler. This functionality should be used in a non-batch clients of the compiler.
|
||||
*/
|
||||
public synchronized void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException {
|
||||
if (map.isEmpty()) {
|
||||
String msg =
|
||||
"Setting opened indexes should be called only when the ZipFileCache is empty. "
|
||||
+ "Call JavacFileManager.flush() before calling this method.";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
|
||||
for (ZipFileIndex zfi : indexes) {
|
||||
map.put(zfi.zipFile, zfi);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,9 +138,6 @@ public class ClassReader implements Completer {
|
||||
/** The symbol table. */
|
||||
Symtab syms;
|
||||
|
||||
/** The scope counter */
|
||||
Scope.ScopeCounter scopeCounter;
|
||||
|
||||
Types types;
|
||||
|
||||
/** The name table. */
|
||||
@ -264,7 +261,6 @@ public class ClassReader implements Completer {
|
||||
|
||||
names = Names.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
scopeCounter = Scope.ScopeCounter.instance(context);
|
||||
types = Types.instance(context);
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
if (fileManager == null)
|
||||
@ -1321,7 +1317,9 @@ public class ClassReader implements Completer {
|
||||
sym.flags_field |= PROPRIETARY;
|
||||
else
|
||||
proxies.append(proxy);
|
||||
if (majorVersion >= V51.major && proxy.type.tsym == syms.polymorphicSignatureType.tsym) {
|
||||
if (majorVersion >= V51.major &&
|
||||
(proxy.type.tsym == syms.polymorphicSignatureType.tsym ||
|
||||
proxy.type.tsym == syms.transientPolymorphicSignatureType.tsym)) {
|
||||
sym.flags_field |= POLYMORPHIC_SIGNATURE;
|
||||
}
|
||||
}
|
||||
@ -1879,7 +1877,7 @@ public class ClassReader implements Completer {
|
||||
ClassType ct = (ClassType)c.type;
|
||||
|
||||
// allocate scope for members
|
||||
c.members_field = new Scope.ClassScope(c, scopeCounter);
|
||||
c.members_field = new Scope(c);
|
||||
|
||||
// prepare type variable table
|
||||
typevars = typevars.dup(currentOwner);
|
||||
|
||||
@ -39,7 +39,6 @@ import java.nio.file.FileVisitOption;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.Attributes;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -223,9 +222,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
Path path = pathIter.next();
|
||||
if (pathIter.hasNext())
|
||||
throw new IllegalArgumentException("path too long for directory");
|
||||
if (!path.exists())
|
||||
throw new FileNotFoundException(path + ": does not exist");
|
||||
else if (!isDirectory(path))
|
||||
if (!isDirectory(path))
|
||||
throw new IOException(path + ": not a directory");
|
||||
}
|
||||
|
||||
@ -326,7 +323,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
private void list(Path path, String packageName, final Set<Kind> kinds,
|
||||
boolean recurse, final ListBuffer<JavaFileObject> results)
|
||||
throws IOException {
|
||||
if (!path.exists())
|
||||
if (!Files.exists(path))
|
||||
return;
|
||||
|
||||
final Path pathDir;
|
||||
@ -341,7 +338,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
String sep = path.getFileSystem().getSeparator();
|
||||
Path packageDir = packageName.isEmpty() ? pathDir
|
||||
: pathDir.resolve(packageName.replace(".", sep));
|
||||
if (!packageDir.exists())
|
||||
if (!Files.exists(packageDir))
|
||||
return;
|
||||
|
||||
/* Alternate impl of list, superceded by use of Files.walkFileTree */
|
||||
@ -353,7 +350,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
// DirectoryStream<Path> ds = dir.newDirectoryStream();
|
||||
// try {
|
||||
// for (Path p: ds) {
|
||||
// String name = p.getName().toString();
|
||||
// String name = p.getFileName().toString();
|
||||
// if (isDirectory(p)) {
|
||||
// if (recurse && SourceVersion.isIdentifier(name)) {
|
||||
// queue.add(p);
|
||||
@ -376,7 +373,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
|
||||
Path name = dir.getName();
|
||||
Path name = dir.getFileName();
|
||||
if (name == null || SourceVersion.isIdentifier(name.toString())) // JSR 292?
|
||||
return FileVisitResult.CONTINUE;
|
||||
else
|
||||
@ -385,7 +382,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||
if (attrs.isRegularFile() && kinds.contains(getKind(file.getName().toString()))) {
|
||||
if (attrs.isRegularFile() && kinds.contains(getKind(file.getFileName().toString()))) {
|
||||
JavaFileObject fe =
|
||||
PathFileObject.createDirectoryPathFileObject(
|
||||
JavacPathFileManager.this, file, pathDir);
|
||||
@ -431,13 +428,13 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
for (Path p: getLocation(location)) {
|
||||
if (isDirectory(p)) {
|
||||
Path f = resolve(p, relativePath);
|
||||
if (f.exists())
|
||||
if (Files.exists(f))
|
||||
return PathFileObject.createDirectoryPathFileObject(this, f, p);
|
||||
} else {
|
||||
FileSystem fs = getFileSystem(p);
|
||||
if (fs != null) {
|
||||
Path file = getPath(fs, relativePath);
|
||||
if (file.exists())
|
||||
if (Files.exists(file))
|
||||
return PathFileObject.createJarPathFileObject(this, file);
|
||||
}
|
||||
}
|
||||
@ -504,7 +501,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
private FileSystem getFileSystem(Path p) throws IOException {
|
||||
FileSystem fs = fileSystems.get(p);
|
||||
if (fs == null) {
|
||||
fs = FileSystems.newFileSystem(p, Collections.<String,Void>emptyMap(), null);
|
||||
fs = FileSystems.newFileSystem(p, null);
|
||||
fileSystems.put(p, fs);
|
||||
}
|
||||
return fs;
|
||||
@ -530,7 +527,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
}
|
||||
|
||||
private static boolean isDirectory(Path path) throws IOException {
|
||||
BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
|
||||
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
|
||||
return attrs.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,6 @@ import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.Attributes;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.NestingKind;
|
||||
@ -153,7 +152,7 @@ abstract class PathFileObject implements JavaFileObject {
|
||||
|
||||
@Override
|
||||
public Kind getKind() {
|
||||
return BaseFileManager.getKind(path.getName().toString());
|
||||
return BaseFileManager.getKind(path.getFileName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -164,14 +163,14 @@ abstract class PathFileObject implements JavaFileObject {
|
||||
return false;
|
||||
}
|
||||
String sn = simpleName + kind.extension;
|
||||
String pn = path.getName().toString();
|
||||
String pn = path.getFileName().toString();
|
||||
if (pn.equals(sn)) {
|
||||
return true;
|
||||
}
|
||||
if (pn.equalsIgnoreCase(sn)) {
|
||||
try {
|
||||
// allow for Windows
|
||||
return path.toRealPath(false).getName().toString().equals(sn);
|
||||
return path.toRealPath(false).getFileName().toString().equals(sn);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
@ -200,13 +199,13 @@ abstract class PathFileObject implements JavaFileObject {
|
||||
|
||||
@Override
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return path.newInputStream();
|
||||
return Files.newInputStream(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
ensureParentDirectoriesExist();
|
||||
return path.newOutputStream();
|
||||
return Files.newOutputStream(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -242,14 +241,13 @@ abstract class PathFileObject implements JavaFileObject {
|
||||
@Override
|
||||
public Writer openWriter() throws IOException {
|
||||
ensureParentDirectoriesExist();
|
||||
return new OutputStreamWriter(path.newOutputStream(), fileManager.getEncodingName());
|
||||
return new OutputStreamWriter(Files.newOutputStream(path), fileManager.getEncodingName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified() {
|
||||
try {
|
||||
BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
|
||||
return attrs.lastModifiedTime().toMillis();
|
||||
return Files.getLastModifiedTime(path).toMillis();
|
||||
} catch (IOException e) {
|
||||
return -1;
|
||||
}
|
||||
@ -258,7 +256,7 @@ abstract class PathFileObject implements JavaFileObject {
|
||||
@Override
|
||||
public boolean delete() {
|
||||
try {
|
||||
path.delete();
|
||||
Files.delete(path);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
@ -267,7 +265,7 @@ abstract class PathFileObject implements JavaFileObject {
|
||||
|
||||
public boolean isSameFile(PathFileObject other) {
|
||||
try {
|
||||
return path.isSameFile(other.path);
|
||||
return Files.isSameFile(path, other.path);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
@ -296,8 +294,7 @@ abstract class PathFileObject implements JavaFileObject {
|
||||
|
||||
private long size() {
|
||||
try {
|
||||
BasicFileAttributes attrs = Attributes.readBasicFileAttributes(path);
|
||||
return attrs.size();
|
||||
return Files.size(path);
|
||||
} catch (IOException e) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ public class JavacParser implements Parser {
|
||||
*/
|
||||
boolean allowAnnotations;
|
||||
|
||||
/** Switch: should we recognize automatic resource management?
|
||||
/** Switch: should we recognize try-with-resources?
|
||||
*/
|
||||
boolean allowTWR;
|
||||
|
||||
@ -1639,7 +1639,7 @@ public class JavacParser implements Parser {
|
||||
* | WHILE ParExpression Statement
|
||||
* | DO Statement WHILE ParExpression ";"
|
||||
* | TRY Block ( Catches | [Catches] FinallyPart )
|
||||
* | TRY "(" ResourceSpecification ")" Block [Catches] [FinallyPart]
|
||||
* | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart]
|
||||
* | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
|
||||
* | SYNCHRONIZED ParExpression Block
|
||||
* | RETURN [Expression] ";"
|
||||
@ -2182,31 +2182,24 @@ public class JavacParser implements Parser {
|
||||
ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
|
||||
defs.append(resource());
|
||||
while (S.token() == SEMI) {
|
||||
// All but last of multiple declarators subsume a semicolon
|
||||
// All but last of multiple declarators must subsume a semicolon
|
||||
storeEnd(defs.elems.last(), S.endPos());
|
||||
int semiColonPos = S.pos();
|
||||
S.nextToken();
|
||||
if (S.token() == RPAREN) { // Optional trailing semicolon
|
||||
// after last resource
|
||||
break;
|
||||
}
|
||||
defs.append(resource());
|
||||
}
|
||||
return defs.toList();
|
||||
}
|
||||
|
||||
/** Resource =
|
||||
* VariableModifiers Type VariableDeclaratorId = Expression
|
||||
* | Expression
|
||||
/** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
|
||||
*/
|
||||
JCTree resource() {
|
||||
int pos = S.pos();
|
||||
if (S.token() == FINAL || S.token() == MONKEYS_AT) {
|
||||
return variableDeclaratorRest(pos, optFinal(0), parseType(),
|
||||
ident(), true, null);
|
||||
} else {
|
||||
JCExpression t = term(EXPR | TYPE);
|
||||
if ((lastmode & TYPE) != 0 && S.token() == IDENTIFIER)
|
||||
return variableDeclaratorRest(pos, toP(F.at(pos).Modifiers(Flags.FINAL)), t,
|
||||
ident(), true, null);
|
||||
else
|
||||
return t;
|
||||
}
|
||||
return variableDeclaratorRest(S.pos(), optFinal(Flags.FINAL),
|
||||
parseType(), ident(), true, null);
|
||||
}
|
||||
|
||||
/** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
|
||||
|
||||
@ -138,7 +138,7 @@ public class Scanner implements Lexer {
|
||||
source = fac.source;
|
||||
allowBinaryLiterals = source.allowBinaryLiterals();
|
||||
allowHexFloats = source.allowHexFloats();
|
||||
allowUnderscoresInLiterals = source.allowBinaryLiterals();
|
||||
allowUnderscoresInLiterals = source.allowUnderscoresInLiterals();
|
||||
}
|
||||
|
||||
private static final boolean hexFloatsWork = hexFloatsWork();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -465,9 +465,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public List<JCImport> getImports() {
|
||||
ListBuffer<JCImport> imports = new ListBuffer<JCImport>();
|
||||
for (JCTree tree : defs) {
|
||||
if (tree.getTag() == IMPORT)
|
||||
int tag = tree.getTag();
|
||||
if (tag == IMPORT)
|
||||
imports.append((JCImport)tree);
|
||||
else
|
||||
else if (tag != SKIP)
|
||||
break;
|
||||
}
|
||||
return imports.toList();
|
||||
|
||||
@ -73,7 +73,8 @@ public class Names {
|
||||
public final Name java_io_Serializable;
|
||||
public final Name serialVersionUID;
|
||||
public final Name java_lang_Enum;
|
||||
public final Name java_dyn_MethodHandle;
|
||||
public final Name transient_java_dyn_MethodHandle; // transient - 292
|
||||
public final Name java_lang_invoke_MethodHandle;
|
||||
public final Name package_info;
|
||||
public final Name ConstantValue;
|
||||
public final Name LineNumberTable;
|
||||
@ -183,7 +184,8 @@ public class Names {
|
||||
java_lang_Cloneable = fromString("java.lang.Cloneable");
|
||||
java_io_Serializable = fromString("java.io.Serializable");
|
||||
java_lang_Enum = fromString("java.lang.Enum");
|
||||
java_dyn_MethodHandle = fromString("java.dyn.MethodHandle");
|
||||
transient_java_dyn_MethodHandle = fromString("java.dyn.MethodHandle"); //transient - 292
|
||||
java_lang_invoke_MethodHandle = fromString("java.lang.invoke.MethodHandle");
|
||||
package_info = fromString("package-info");
|
||||
serialVersionUID = fromString("serialVersionUID");
|
||||
ConstantValue = fromString("ConstantValue");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -159,18 +159,26 @@ public interface Element {
|
||||
Set<Modifier> getModifiers();
|
||||
|
||||
/**
|
||||
* Returns the simple (unqualified) name of this element.
|
||||
* The name of a generic type does not include any reference
|
||||
* to its formal type parameters.
|
||||
* For example, the simple name of the type element
|
||||
* {@code java.util.Set<E>} is {@code "Set"}.
|
||||
* If this element represents an unnamed package, an empty name is
|
||||
* returned. If it represents a constructor, the name "{@code
|
||||
* <init>}" is returned. If it represents a static initializer,
|
||||
* the name "{@code <clinit>}" is returned. If it represents an
|
||||
* anonymous class or instance initializer, an empty name is
|
||||
* Returns the simple (unqualified) name of this element. The
|
||||
* name of a generic type does not include any reference to its
|
||||
* formal type parameters.
|
||||
*
|
||||
* For example, the simple name of the type element {@code
|
||||
* java.util.Set<E>} is {@code "Set"}.
|
||||
*
|
||||
* If this element represents an unnamed {@linkplain
|
||||
* PackageElement#getSimpleName package}, an empty name is
|
||||
* returned.
|
||||
*
|
||||
* If it represents a {@linkplain ExecutableElement#getSimpleName
|
||||
* constructor}, the name "{@code <init>}" is returned. If it
|
||||
* represents a {@linkplain ExecutableElement#getSimpleName static
|
||||
* initializer}, the name "{@code <clinit>}" is returned.
|
||||
*
|
||||
* If it represents an {@linkplain TypeElement#getSimpleName
|
||||
* anonymous class} or {@linkplain ExecutableElement#getSimpleName
|
||||
* instance initializer}, an empty name is returned.
|
||||
*
|
||||
* @return the simple name of this element
|
||||
*/
|
||||
Name getSimpleName();
|
||||
@ -182,9 +190,18 @@ public interface Element {
|
||||
* <li> If this element is one whose declaration is lexically enclosed
|
||||
* immediately within the declaration of another element, that other
|
||||
* element is returned.
|
||||
* <li> If this is a top-level type, its package is returned.
|
||||
* <li> If this is a package, {@code null} is returned.
|
||||
* <li> If this is a type parameter, {@code null} is returned.
|
||||
*
|
||||
* <li> If this is a {@linkplain TypeElement#getEnclosingElement
|
||||
* top-level type}, its package is returned.
|
||||
*
|
||||
* <li> If this is a {@linkplain
|
||||
* PackageElement#getEnclosingElement package}, {@code null} is
|
||||
* returned.
|
||||
|
||||
* <li> If this is a {@linkplain
|
||||
* TypeParameterElement#getEnclosingElement type parameter},
|
||||
* {@code null} is returned.
|
||||
|
||||
* </ul>
|
||||
*
|
||||
* @return the enclosing element, or {@code null} if there is none
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -97,4 +97,17 @@ public interface ExecutableElement extends Element, Parameterizable {
|
||||
* @return the default value, or {@code null} if none
|
||||
*/
|
||||
AnnotationValue getDefaultValue();
|
||||
|
||||
/**
|
||||
* Returns the simple name of a constructor, method, or
|
||||
* initializer. For a constructor, the name {@code "<init>"} is
|
||||
* returned, for a static initializer, the name {@code "<clinit>"}
|
||||
* is returned, and for an anonymous class or instance
|
||||
* initializer, an empty name is returned.
|
||||
*
|
||||
* @return the simple name of a constructor, method, or
|
||||
* initializer
|
||||
*/
|
||||
@Override
|
||||
Name getSimpleName();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -47,6 +47,16 @@ public interface PackageElement extends Element, QualifiedNameable {
|
||||
*/
|
||||
Name getQualifiedName();
|
||||
|
||||
/**
|
||||
* Returns the simple name of this package. For an unnamed
|
||||
* package, an empty name is returned
|
||||
*
|
||||
* @return the simple name of this package or an empty name if
|
||||
* this is an unnamed package
|
||||
*/
|
||||
@Override
|
||||
Name getSimpleName();
|
||||
|
||||
/**
|
||||
* Returns {@code true} is this is an unnamed package and {@code
|
||||
* false} otherwise.
|
||||
@ -56,4 +66,13 @@ public interface PackageElement extends Element, QualifiedNameable {
|
||||
* @jls3 7.4.2 Unnamed Packages
|
||||
*/
|
||||
boolean isUnnamed();
|
||||
|
||||
/**
|
||||
* Returns {@code null} since a package is not enclosed by another
|
||||
* element.
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
Element getEnclosingElement();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -105,6 +105,19 @@ public interface TypeElement extends Element, Parameterizable, QualifiedNameable
|
||||
*/
|
||||
Name getQualifiedName();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the simple name of this type element.
|
||||
*
|
||||
* For an anonymous class, an empty name is returned.
|
||||
*
|
||||
* @return the simple name of this class or interface,
|
||||
* an empty name for an anonymous class
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
Name getSimpleName();
|
||||
|
||||
/**
|
||||
* Returns the direct superclass of this type element.
|
||||
* If this type element represents an interface or the class
|
||||
@ -132,4 +145,16 @@ public interface TypeElement extends Element, Parameterizable, QualifiedNameable
|
||||
* if there are none
|
||||
*/
|
||||
List<? extends TypeParameterElement> getTypeParameters();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the package of a top-level type and returns the
|
||||
* immediately lexically enclosing element for a {@linkplain
|
||||
* NestingKind#isNested nested} type.
|
||||
*
|
||||
* @return the package of a top-level type, the immediately
|
||||
* lexically enclosing element for a nested type
|
||||
*/
|
||||
@Override
|
||||
Element getEnclosingElement();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -62,4 +62,12 @@ public interface TypeParameterElement extends Element {
|
||||
* there are none
|
||||
*/
|
||||
List<? extends TypeMirror> getBounds();
|
||||
|
||||
/**
|
||||
* Returns {@code null}.
|
||||
*
|
||||
* @return {@code null}
|
||||
*/
|
||||
@Override
|
||||
Element getEnclosingElement();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,17 +28,16 @@ package javax.lang.model.element;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a field, {@code enum} constant, method or constructor
|
||||
* parameter, local variable, or exception parameter.
|
||||
* parameter, local variable, resource variable, or exception
|
||||
* parameter.
|
||||
*
|
||||
* @author Joseph D. Darcy
|
||||
* @author Scott Seligman
|
||||
* @author Peter von der Ahé
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public interface VariableElement extends Element {
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.lang.model.type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a disjunctive type.
|
||||
*
|
||||
* As of the {@link javax.lang.model.SourceVersion#RELEASE_7
|
||||
* RELEASE_7} source version, disjunctive types can appear as the type
|
||||
* of a multi-catch exception parameter.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface DisjunctiveType extends TypeMirror {
|
||||
|
||||
/**
|
||||
* Return the alternatives comprising this disjunctive type.
|
||||
*
|
||||
* The alternatives are formally referred to as <i>disjuncts</i>.
|
||||
*
|
||||
* @return the alternatives comprising this disjunctive type.
|
||||
*/
|
||||
List<? extends TypeMirror> getAlternatives();
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -137,7 +137,14 @@ public enum TypeKind {
|
||||
* An implementation-reserved type.
|
||||
* This is not the type you are looking for.
|
||||
*/
|
||||
OTHER;
|
||||
OTHER,
|
||||
|
||||
/**
|
||||
* A disjunctive type.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
DISJUNCTIVE;
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this kind corresponds to a primitive
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -162,4 +162,14 @@ public interface TypeVisitor<R, P> {
|
||||
* a visitor implementation may optionally throw this exception
|
||||
*/
|
||||
R visitUnknown(TypeMirror t, P p);
|
||||
|
||||
/**
|
||||
* Visits a disjunctive type.
|
||||
*
|
||||
* @param t the type to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @return a visitor-specified result
|
||||
* @since 1.7
|
||||
*/
|
||||
R visitDisjunctive(DisjunctiveType t, P p);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,7 +29,8 @@ import javax.lang.model.type.*;
|
||||
|
||||
/**
|
||||
* A skeletal visitor of types with default behavior appropriate for
|
||||
* the version 6 language level.
|
||||
* the {@link javax.lang.model.SourceVersion#RELEASE_6 RELEASE_6}
|
||||
* source version.
|
||||
*
|
||||
* <p> <b>WARNING:</b> The {@code TypeVisitor} interface implemented
|
||||
* by this class may have methods added to it in the future to
|
||||
@ -94,6 +95,20 @@ public abstract class AbstractTypeVisitor6<R, P> implements TypeVisitor<R, P> {
|
||||
return t.accept(this, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a {@code DisjunctiveType} element by calling {@code
|
||||
* visitUnknown}.
|
||||
|
||||
* @param t {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code visitUnknown}
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public R visitDisjunctive(DisjunctiveType t, P p) {
|
||||
return visitUnknown(t, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,7 +29,8 @@ import javax.lang.model.type.*;
|
||||
|
||||
/**
|
||||
* A skeletal visitor of types with default behavior appropriate for
|
||||
* the version 7 language level.
|
||||
* the {@link javax.lang.model.SourceVersion#RELEASE_7 RELEASE_7}
|
||||
* source version.
|
||||
*
|
||||
* <p> <b>WARNING:</b> The {@code TypeVisitor} interface implemented
|
||||
* by this class may have methods added to it in the future to
|
||||
@ -64,4 +65,13 @@ public abstract class AbstractTypeVisitor7<R, P> extends AbstractTypeVisitor6<R,
|
||||
protected AbstractTypeVisitor7() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a {@code DisjunctiveType} in a manner defined by a subclass.
|
||||
*
|
||||
* @param t {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of the visit as defined by a subclass
|
||||
*/
|
||||
public abstract R visitDisjunctive(DisjunctiveType t, P p);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -199,7 +199,8 @@ public class ElementKindVisitor6<R, P>
|
||||
* Visits a variable element, dispatching to the visit method for
|
||||
* the specific {@linkplain ElementKind kind} of variable, {@code
|
||||
* ENUM_CONSTANT}, {@code EXCEPTION_PARAMETER}, {@code FIELD},
|
||||
* {@code LOCAL_VARIABLE}, or {@code PARAMETER}.
|
||||
* {@code LOCAL_VARIABLE}, {@code PARAMETER}, or {@code RESOURCE_VARIABLE}.
|
||||
*
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of the kind-specific visit method
|
||||
@ -223,10 +224,12 @@ public class ElementKindVisitor6<R, P>
|
||||
case PARAMETER:
|
||||
return visitVariableAsParameter(e, p);
|
||||
|
||||
case RESOURCE_VARIABLE:
|
||||
return visitVariableAsResourceVariable(e, p);
|
||||
|
||||
default:
|
||||
throw new AssertionError("Bad kind " + k + " for VariableElement" + e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -289,6 +292,20 @@ public class ElementKindVisitor6<R, P>
|
||||
return defaultAction(e, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a {@code RESOURCE_VARIABLE} variable element by calling
|
||||
* {@code visitUnknown}.
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @return the result of {@code visitUnknown}
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public R visitVariableAsResourceVariable(VariableElement e, P p) {
|
||||
return visitUnknown(e, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an executable element, dispatching to the visit method
|
||||
* for the specific {@linkplain ElementKind kind} of executable,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,7 +34,7 @@ import javax.lang.model.SourceVersion;
|
||||
/**
|
||||
* A visitor of program elements based on their {@linkplain
|
||||
* ElementKind kind} with default behavior appropriate for the {@link
|
||||
* SourceVersion#RELEASE_6 RELEASE_6} source version. For {@linkplain
|
||||
* SourceVersion#RELEASE_7 RELEASE_7} source version. For {@linkplain
|
||||
* Element elements} <tt><i>XYZ</i></tt> that may have more than one
|
||||
* kind, the <tt>visit<i>XYZ</i></tt> methods in this class delegate
|
||||
* to the <tt>visit<i>XYZKind</i></tt> method corresponding to the
|
||||
@ -94,4 +94,17 @@ public class ElementKindVisitor7<R, P> extends ElementKindVisitor6<R, P> {
|
||||
protected ElementKindVisitor7(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a {@code RESOURCE_VARIABLE} variable element by calling
|
||||
* {@code defaultAction}.
|
||||
*
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
*/
|
||||
@Override
|
||||
public R visitVariableAsResourceVariable(VariableElement e, P p) {
|
||||
return defaultAction(e, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -152,8 +152,8 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
* {@inheritDoc} This implementation scans the enclosed elements.
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of scanning
|
||||
*/
|
||||
public R visitPackage(PackageElement e, P p) {
|
||||
@ -163,8 +163,8 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
* {@inheritDoc} This implementation scans the enclosed elements.
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of scanning
|
||||
*/
|
||||
public R visitType(TypeElement e, P p) {
|
||||
@ -172,21 +172,28 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} This implementation scans the enclosed elements.
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* This implementation scans the enclosed elements, unless the
|
||||
* element is a {@code RESOURCE_VARIABLE} in which case {@code
|
||||
* visitUnknown} is called.
|
||||
*
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of scanning
|
||||
*/
|
||||
public R visitVariable(VariableElement e, P p) {
|
||||
return scan(e.getEnclosedElements(), p);
|
||||
if (e.getKind() != ElementKind.RESOURCE_VARIABLE)
|
||||
return scan(e.getEnclosedElements(), p);
|
||||
else
|
||||
return visitUnknown(e, p);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} This implementation scans the parameters.
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of scanning
|
||||
*/
|
||||
public R visitExecutable(ExecutableElement e, P p) {
|
||||
@ -196,8 +203,8 @@ public class ElementScanner6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
/**
|
||||
* {@inheritDoc} This implementation scans the enclosed elements.
|
||||
*
|
||||
* @param e the element to visit
|
||||
* @param p a visitor-specified parameter
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of scanning
|
||||
*/
|
||||
public R visitTypeParameter(TypeParameterElement e, P p) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -105,4 +105,16 @@ public class ElementScanner7<R, P> extends ElementScanner6<R, P> {
|
||||
protected ElementScanner7(R defaultValue){
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation scans the enclosed elements.
|
||||
*
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of scanning
|
||||
*/
|
||||
@Override
|
||||
public R visitVariable(VariableElement e, P p) {
|
||||
return scan(e.getEnclosedElements(), p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,8 +36,8 @@ import javax.annotation.processing.SupportedSourceVersion;
|
||||
/**
|
||||
* A simple visitor for annotation values with default behavior
|
||||
* appropriate for the {@link SourceVersion#RELEASE_7 RELEASE_7}
|
||||
* source version. Visit methods call {@link
|
||||
* #defaultAction} passing their arguments to {@code defaultAction}'s
|
||||
* source version. Visit methods call {@link #defaultAction
|
||||
* defaultAction} passing their arguments to {@code defaultAction}'s
|
||||
* corresponding parameters.
|
||||
*
|
||||
* <p> Methods in this class may be overridden subject to their
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,8 +38,11 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* source version.
|
||||
*
|
||||
* Visit methods corresponding to {@code RELEASE_6} language
|
||||
* constructs call {@link #defaultAction}, passing their arguments to
|
||||
* {@code defaultAction}'s corresponding parameters.
|
||||
* constructs call {@link #defaultAction defaultAction}, passing their
|
||||
* arguments to {@code defaultAction}'s corresponding parameters.
|
||||
*
|
||||
* For constructs introduced in {@code RELEASE_7} and later, {@code
|
||||
* visitUnknown} is called instead.
|
||||
*
|
||||
* <p> Methods in this class may be overridden subject to their
|
||||
* general contract. Note that annotating methods in concrete
|
||||
@ -137,14 +140,21 @@ public class SimpleElementVisitor6<R, P> extends AbstractElementVisitor6<R, P> {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} This implementation calls {@code defaultAction}.
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* This implementation calls {@code defaultAction}, unless the
|
||||
* element is a {@code RESOURCE_VARIABLE} in which case {@code
|
||||
* visitUnknown} is called.
|
||||
*
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
* @return the result of {@code defaultAction} or {@code visitUnknown}
|
||||
*/
|
||||
public R visitVariable(VariableElement e, P p) {
|
||||
return defaultAction(e, p);
|
||||
if (e.getKind() != ElementKind.RESOURCE_VARIABLE)
|
||||
return defaultAction(e, p);
|
||||
else
|
||||
return visitUnknown(e, p);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,9 +36,10 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* appropriate for the {@link SourceVersion#RELEASE_7 RELEASE_7}
|
||||
* source version.
|
||||
*
|
||||
* Visit methods corresponding to {@code RELEASE_7} language
|
||||
* constructs call {@link #defaultAction}, passing their arguments to
|
||||
* {@code defaultAction}'s corresponding parameters.
|
||||
* Visit methods corresponding to {@code RELEASE_7} and earlier
|
||||
* language constructs call {@link #defaultAction defaultAction},
|
||||
* passing their arguments to {@code defaultAction}'s corresponding
|
||||
* parameters.
|
||||
*
|
||||
* <p> Methods in this class may be overridden subject to their
|
||||
* general contract. Note that annotating methods in concrete
|
||||
@ -89,4 +90,16 @@ public class SimpleElementVisitor7<R, P> extends SimpleElementVisitor6<R, P> {
|
||||
protected SimpleElementVisitor7(R defaultValue){
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation calls {@code defaultAction}.
|
||||
*
|
||||
* @param e {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
*/
|
||||
@Override
|
||||
public R visitVariable(VariableElement e, P p) {
|
||||
return defaultAction(e, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,8 +36,11 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* {@link SourceVersion#RELEASE_6 RELEASE_6} source version.
|
||||
*
|
||||
* Visit methods corresponding to {@code RELEASE_6} language
|
||||
* constructs call {@link #defaultAction}, passing their arguments to
|
||||
* {@code defaultAction}'s corresponding parameters.
|
||||
* constructs call {@link #defaultAction defaultAction}, passing their
|
||||
* arguments to {@code defaultAction}'s corresponding parameters.
|
||||
*
|
||||
* For constructs introduced in {@code RELEASE_7} and later, {@code
|
||||
* visitUnknown} is called instead.
|
||||
*
|
||||
* <p> Methods in this class may be overridden subject to their
|
||||
* general contract. Note that annotating methods in concrete
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,9 +34,10 @@ import static javax.lang.model.SourceVersion.*;
|
||||
* A simple visitor of types with default behavior appropriate for the
|
||||
* {@link SourceVersion#RELEASE_7 RELEASE_7} source version.
|
||||
*
|
||||
* Visit methods corresponding to {@code RELEASE_7} language
|
||||
* constructs call {@link #defaultAction}, passing their arguments to
|
||||
* {@code defaultAction}'s corresponding parameters.
|
||||
* Visit methods corresponding to {@code RELEASE_7} and earlier
|
||||
* language constructs call {@link #defaultAction defaultAction},
|
||||
* passing their arguments to {@code defaultAction}'s corresponding
|
||||
* parameters.
|
||||
*
|
||||
* <p> Methods in this class may be overridden subject to their
|
||||
* general contract. Note that annotating methods in concrete
|
||||
@ -88,4 +89,17 @@ public class SimpleTypeVisitor7<R, P> extends SimpleTypeVisitor6<R, P> {
|
||||
protected SimpleTypeVisitor7(R defaultValue){
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation visits a {@code DisjunctiveType} by calling
|
||||
* {@code defaultAction}.
|
||||
*
|
||||
* @param t {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
*/
|
||||
@Override
|
||||
public R visitDisjunctive(DisjunctiveType t, P p) {
|
||||
return defaultAction(t, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -92,4 +92,17 @@ public class TypeKindVisitor7<R, P> extends TypeKindVisitor6<R, P> {
|
||||
protected TypeKindVisitor7(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation visits a {@code DisjunctiveType} by calling
|
||||
* {@code defaultAction}.
|
||||
*
|
||||
* @param t {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
*/
|
||||
@Override
|
||||
public R visitDisjunctive(DisjunctiveType t, P p) {
|
||||
return defaultAction(t, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
||||
20
langtools/test/tools/javac/5017953/T5017953.java
Normal file
20
langtools/test/tools/javac/5017953/T5017953.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 5017953
|
||||
* @summary spurious cascaded diagnostics when name not found
|
||||
* @compile/fail/ref=T5017953.out -XDrawDiagnostics T5017953.java
|
||||
*/
|
||||
|
||||
class T5017953 {
|
||||
|
||||
int f = 0;
|
||||
void test(int i) {}
|
||||
|
||||
{ test(NonExistentClass.f ++);
|
||||
test(1 + NonExistentClass.f);
|
||||
test(NonExistentClass.f + 1);
|
||||
test(NonExistentClass.f + NonExistentClass.f);
|
||||
test(NonExistentClass.f += 1);
|
||||
test(f += NonExistentClass.f);
|
||||
}
|
||||
}
|
||||
8
langtools/test/tools/javac/5017953/T5017953.out
Normal file
8
langtools/test/tools/javac/5017953/T5017953.out
Normal file
@ -0,0 +1,8 @@
|
||||
T5017953.java:13:14: compiler.err.cant.resolve.location: kindname.variable, NonExistentClass, , , (compiler.misc.location: kindname.class, T5017953, null)
|
||||
T5017953.java:14:18: compiler.err.cant.resolve.location: kindname.variable, NonExistentClass, , , (compiler.misc.location: kindname.class, T5017953, null)
|
||||
T5017953.java:15:14: compiler.err.cant.resolve.location: kindname.variable, NonExistentClass, , , (compiler.misc.location: kindname.class, T5017953, null)
|
||||
T5017953.java:16:14: compiler.err.cant.resolve.location: kindname.variable, NonExistentClass, , , (compiler.misc.location: kindname.class, T5017953, null)
|
||||
T5017953.java:16:35: compiler.err.cant.resolve.location: kindname.variable, NonExistentClass, , , (compiler.misc.location: kindname.class, T5017953, null)
|
||||
T5017953.java:17:14: compiler.err.cant.resolve.location: kindname.variable, NonExistentClass, , , (compiler.misc.location: kindname.class, T5017953, null)
|
||||
T5017953.java:18:19: compiler.err.cant.resolve.location: kindname.variable, NonExistentClass, , , (compiler.misc.location: kindname.class, T5017953, null)
|
||||
7 errors
|
||||
@ -1,2 +1,2 @@
|
||||
T6491592.java:12:11: compiler.err.operator.cant.be.applied: +, java.lang.Object,compiler.misc.type.null
|
||||
T6491592.java:12:11: compiler.err.operator.cant.be.applied.1: +, java.lang.Object, compiler.misc.type.null
|
||||
1 error
|
||||
|
||||
@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 4279339
|
||||
* @summary Verify that an anonymous class cannot contain a static method.
|
||||
* @author maddox
|
||||
*
|
||||
* @run compile/fail AnonStaticMember_2.java
|
||||
* @run compile/fail/ref=AnonStaticMember_2.out -XDrawDiagnostics AnonStaticMember_2.java
|
||||
*/
|
||||
|
||||
class AnonStaticMember_2 {
|
||||
|
||||
2
langtools/test/tools/javac/AnonStaticMember_2.out
Normal file
2
langtools/test/tools/javac/AnonStaticMember_2.out
Normal file
@ -0,0 +1,2 @@
|
||||
AnonStaticMember_2.java:12:21: compiler.err.icls.cant.have.static.decl: compiler.misc.anonymous.class: AnonStaticMember_2$1
|
||||
1 error
|
||||
@ -100,7 +100,7 @@ testJavac() {
|
||||
expectedResult="$1"; shift
|
||||
cleanup
|
||||
echo $javac ${TESTTOOLVMOPTS} "$@"
|
||||
$javac ${TESTTOOLVMOPTS} "$@"
|
||||
"$javac" ${TESTTOOLVMOPTS} "$@"
|
||||
report $expectedResult $?
|
||||
}
|
||||
|
||||
|
||||
@ -85,15 +85,15 @@ for i in 1 2 3; do
|
||||
done
|
||||
|
||||
echo "Test 1"
|
||||
$javac ${TESTTOOLVMOPTS} -d . -extdirs ext1 "${TESTSRC}${FS}ExtDirTest_1.java"
|
||||
"$javac" ${TESTTOOLVMOPTS} -d . -extdirs ext1 "${TESTSRC}${FS}ExtDirTest_1.java"
|
||||
if [ $? -ne 0 ] ; then fail ; fi
|
||||
|
||||
echo "Test 2"
|
||||
$javac ${TESTTOOLVMOPTS} -d . -extdirs ext1${PS}ext2 "${TESTSRC}${FS}ExtDirTest_2.java"
|
||||
"$javac" ${TESTTOOLVMOPTS} -d . -extdirs ext1${PS}ext2 "${TESTSRC}${FS}ExtDirTest_2.java"
|
||||
if [ $? -ne 0 ] ; then fail ; fi
|
||||
|
||||
echo "Test 3"
|
||||
$javac ${TESTTOOLVMOPTS} -d . -extdirs ext3 "${TESTSRC}${FS}ExtDirTest_3.java"
|
||||
"$javac" ${TESTTOOLVMOPTS} -d . -extdirs ext3 "${TESTSRC}${FS}ExtDirTest_3.java"
|
||||
if [ $? -ne 0 ] ; then fail ; fi
|
||||
|
||||
echo PASS: all tests gave expected results
|
||||
|
||||
@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 4063740
|
||||
* @summary Interfaces may only be declared in top level classes.
|
||||
* @author turnidge
|
||||
*
|
||||
* @compile/fail InterfaceInInner.java
|
||||
* @compile/fail/ref=InterfaceInInner.out -XDrawDiagnostics InterfaceInInner.java
|
||||
*/
|
||||
class InterfaceInInner {
|
||||
InterfaceInInner() {
|
||||
|
||||
2
langtools/test/tools/javac/InterfaceInInner.out
Normal file
2
langtools/test/tools/javac/InterfaceInInner.out
Normal file
@ -0,0 +1,2 @@
|
||||
InterfaceInInner.java:12:13: compiler.err.intf.not.allowed.here
|
||||
1 error
|
||||
@ -40,8 +40,8 @@ set -u
|
||||
|
||||
DiagnosticsInEnglishPlease
|
||||
|
||||
HELP="`$javac ${TESTTOOLVMOPTS} -help 2>&1`"
|
||||
XHELP="`$javac ${TESTTOOLVMOPTS} -X 2>&1`"
|
||||
HELP="`\"$javac\" ${TESTTOOLVMOPTS} -help 2>&1`"
|
||||
XHELP="`\"$javac\" ${TESTTOOLVMOPTS} -X 2>&1`"
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# Standard options
|
||||
|
||||
@ -1,33 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 4406966
|
||||
* @summary null qualifying inner instance creation should be error.
|
||||
* @author gafter
|
||||
*
|
||||
* @compile/fail QualifiedNew.java
|
||||
* @compile/fail/ref=QualifiedNew.out -XDrawDiagnostics QualifiedNew.java
|
||||
*/
|
||||
|
||||
class QualifiedNew {
|
||||
|
||||
3
langtools/test/tools/javac/QualifiedNew.out
Normal file
3
langtools/test/tools/javac/QualifiedNew.out
Normal file
@ -0,0 +1,3 @@
|
||||
QualifiedNew.java:14:23: compiler.err.type.found.req: compiler.misc.type.null, (compiler.misc.type.req.ref)
|
||||
QualifiedNew.java:15:29: compiler.err.cant.resolve.location: kindname.class, Y, , , (compiler.misc.location: kindname.class, QualifiedNew.Y[], null)
|
||||
2 errors
|
||||
@ -1,2 +1,2 @@
|
||||
T6247324.java:18:6: compiler.err.cant.resolve.location: kindname.class, Seetharam, , , (compiler.misc.location: kindname.class, Pair, null)
|
||||
T6247324.java:18:6: compiler.err.cant.resolve.location: kindname.class, Seetharam, , , (compiler.misc.location: kindname.class, Pair<X,Y>, null)
|
||||
1 error
|
||||
|
||||
26
langtools/test/tools/javac/T6554097.java
Normal file
26
langtools/test/tools/javac/T6554097.java
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6554097
|
||||
* @summary "final" confuses at-SuppressWarnings
|
||||
* @compile T6554097.java
|
||||
* @compile/fail/ref=T6554097.out -XDrawDiagnostics -Werror -Xlint:serial T6554097.java
|
||||
*/
|
||||
|
||||
class T6554097 {
|
||||
@SuppressWarnings("serial") final Throwable[] v1 = { new Throwable() {} };
|
||||
@SuppressWarnings("serial") Throwable[] v2 = { new Throwable() {} };
|
||||
|
||||
public static void m1() throws Throwable {
|
||||
@SuppressWarnings("serial") final Throwable[] v3 = { new Throwable() {} };
|
||||
@SuppressWarnings("serial") Throwable[] v4 = { new Throwable() {} };
|
||||
}
|
||||
|
||||
final Throwable[] v5 = { new Throwable() {} };
|
||||
Throwable[] v6 = { new Throwable() {} };
|
||||
|
||||
public static void m2() throws Throwable {
|
||||
final Throwable[] v7 = { new Throwable() {} };
|
||||
Throwable[] v8 = { new Throwable() {} };
|
||||
}
|
||||
}
|
||||
|
||||
7
langtools/test/tools/javac/T6554097.out
Normal file
7
langtools/test/tools/javac/T6554097.out
Normal file
@ -0,0 +1,7 @@
|
||||
T6554097.java:18:46: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$5
|
||||
T6554097.java:19:46: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$6
|
||||
T6554097.java:22:50: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$7
|
||||
T6554097.java:23:54: compiler.warn.missing.SVUID: compiler.misc.anonymous.class: T6554097$8
|
||||
- compiler.err.warnings.and.werror
|
||||
1 error
|
||||
4 warnings
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -38,6 +38,7 @@ import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.file.RelativePath.RelativeFile;
|
||||
import com.sun.tools.javac.file.ZipFileIndex;
|
||||
import com.sun.tools.javac.file.ZipFileIndexArchive;
|
||||
import com.sun.tools.javac.file.ZipFileIndexCache;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
|
||||
public class T6725036 {
|
||||
@ -57,8 +58,8 @@ public class T6725036 {
|
||||
JarEntry je = j.getJarEntry(TEST_ENTRY_NAME.getPath());
|
||||
long jarEntryTime = je.getTime();
|
||||
|
||||
ZipFileIndex zfi =
|
||||
ZipFileIndex.getZipFileIndex(rt_jar, null, false, null, false);
|
||||
ZipFileIndexCache zfic = ZipFileIndexCache.getSharedInstance();
|
||||
ZipFileIndex zfi = zfic.getZipFileIndex(rt_jar, null, false, null, false);
|
||||
long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME);
|
||||
|
||||
check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime);
|
||||
|
||||
@ -4,13 +4,18 @@
|
||||
* @author Joseph D. Darcy
|
||||
* @summary Verify bad TWRs don't compile
|
||||
* @compile/fail -source 6 BadTwrSyntax.java
|
||||
* @compile/fail/ref=BadTwrSyntax.out -XDrawDiagnostics BadTwrSyntax.java
|
||||
* @compile/fail/ref=BadTwrSyntax.out -XDrawDiagnostics BadTwrSyntax.java
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
public class BadTwrSyntax implements AutoCloseable {
|
||||
public static void main(String... args) throws Exception {
|
||||
// illegal semicolon ending resources
|
||||
// illegal double semicolon ending resources
|
||||
try(BadTwr twrflow = new BadTwr();;) {
|
||||
System.out.println(twrflow.toString());
|
||||
}
|
||||
|
||||
// but one semicolon is fine
|
||||
try(BadTwr twrflow = new BadTwr();) {
|
||||
System.out.println(twrflow.toString());
|
||||
}
|
||||
|
||||
@ -1,2 +1,7 @@
|
||||
BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.expr
|
||||
1 error
|
||||
BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.type
|
||||
BadTwrSyntax.java:14:44: compiler.err.expected: =
|
||||
BadTwrSyntax.java:14:45: compiler.err.expected: ')'
|
||||
BadTwrSyntax.java:14:47: compiler.err.expected: '{'
|
||||
BadTwrSyntax.java:15:19: compiler.err.illegal.start.of.expr
|
||||
BadTwrSyntax.java:15:23: compiler.err.expected: ';'
|
||||
6 errors
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,9 +23,9 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6911256 6964740 6965277
|
||||
* @bug 6911256 6964740 6965277 7013420
|
||||
* @author Maurizio Cimadamore
|
||||
* @summary Check that lowered arm block does not end up creating resource twice
|
||||
* @summary Check that lowered try-with-resources block does not end up creating resource twice
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -45,7 +45,7 @@ public class DuplicateResource {
|
||||
static ArrayList<TestResource> resources = new ArrayList<TestResource>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
try(new TestResource()) {
|
||||
try(TestResource tr = new TestResource()) {
|
||||
//do something
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Shouldn't reach here", e);
|
||||
@ -59,7 +59,7 @@ public class DuplicateResource {
|
||||
}
|
||||
TestResource resource = resources.get(0);
|
||||
if (!resource.isClosed) {
|
||||
throw new AssertionError("Resource used in ARM block has not been automatically closed");
|
||||
throw new AssertionError("Resource used in try-with-resources block has not been automatically closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7013420
|
||||
* @author Joseph D. Darcy
|
||||
* @summary Test that resource variables are accepted as explicitly final.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ExplicitFinal implements AutoCloseable {
|
||||
public static void main(String... args) {
|
||||
try(final ExplicitFinal r2 = new ExplicitFinal()) {
|
||||
r2.toString();
|
||||
} catch (IOException ioe) {
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
|
||||
try(final @SuppressWarnings("unchecked") ExplicitFinal r3 = new ExplicitFinal()) {
|
||||
r3.toString();
|
||||
} catch (IOException ioe) {
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
|
||||
try(@SuppressWarnings("unchecked") ExplicitFinal r4 = new ExplicitFinal()) {
|
||||
r4.toString();
|
||||
} catch (IOException ioe) {
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
}
|
||||
public void close() throws IOException {
|
||||
System.out.println("Calling close on " + this);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6911256 6964740 6965277
|
||||
* @bug 6911256 6964740 6965277 7013420
|
||||
* @author Maurizio Cimadamore
|
||||
* @summary Test that resource variables are implicitly final
|
||||
* @compile/fail/ref=ImplicitFinal.out -XDrawDiagnostics ImplicitFinal.java
|
||||
@ -15,12 +15,25 @@ class ImplicitFinal implements AutoCloseable {
|
||||
} catch (IOException ioe) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
|
||||
try(@SuppressWarnings("unchecked") ImplicitFinal r1 = new ImplicitFinal()) {
|
||||
r1 = null; //disallowed
|
||||
} catch (IOException ioe) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
|
||||
try(final ImplicitFinal r2 = new ImplicitFinal()) {
|
||||
r2 = null; //disallowed
|
||||
} catch (IOException ioe) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
|
||||
try(final @SuppressWarnings("unchecked") ImplicitFinal r3 = new ImplicitFinal()) {
|
||||
r3 = null; //disallowed
|
||||
} catch (IOException ioe) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A close method, but the class is <em>not</em> Closeable or
|
||||
// AutoCloseable.
|
||||
|
||||
public void close() throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
@ -1,2 +1,5 @@
|
||||
ImplicitFinal.java:14:13: compiler.err.try.resource.may.not.be.assigned: r
|
||||
1 error
|
||||
ImplicitFinal.java:20:13: compiler.err.try.resource.may.not.be.assigned: r1
|
||||
ImplicitFinal.java:26:13: compiler.err.try.resource.may.not.be.assigned: r2
|
||||
ImplicitFinal.java:32:13: compiler.err.try.resource.may.not.be.assigned: r3
|
||||
4 errors
|
||||
|
||||
@ -1,26 +1,16 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6911256 6964740
|
||||
* @bug 6911256 6964740 7013420
|
||||
* @author Joseph D. Darcy
|
||||
* @summary Test exception analysis of ARM blocks
|
||||
* @summary Test exception analysis of try-with-resources blocks
|
||||
* @compile/fail/ref=TwrFlow.out -XDrawDiagnostics TwrFlow.java
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
public class TwrFlow implements AutoCloseable {
|
||||
public static void main(String... args) {
|
||||
try(TwrFlow armflow = new TwrFlow()) {
|
||||
System.out.println(armflow.toString());
|
||||
} catch (IOException ioe) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
// CustomCloseException should be caught or added to throws clause
|
||||
|
||||
// Also check behavior on a resource expression rather than a
|
||||
// declaration.
|
||||
TwrFlow armflowexpr = new TwrFlow();
|
||||
try(armflowexpr) {
|
||||
System.out.println(armflowexpr.toString());
|
||||
try(TwrFlow twrFlow = new TwrFlow()) {
|
||||
System.out.println(twrFlow.toString());
|
||||
} catch (IOException ioe) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", ioe);
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
TwrFlow.java:14:11: compiler.err.except.never.thrown.in.try: java.io.IOException
|
||||
TwrFlow.java:24:11: compiler.err.except.never.thrown.in.try: java.io.IOException
|
||||
TwrFlow.java:12:46: compiler.err.unreported.exception.need.to.catch.or.throw: CustomCloseException
|
||||
TwrFlow.java:22:26: compiler.err.unreported.exception.need.to.catch.or.throw: CustomCloseException
|
||||
4 errors
|
||||
2 errors
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6911256 6964740 6965277
|
||||
* @author Maurizio Cimadamore
|
||||
* @summary Check that resources of an intersection type forces union of exception types
|
||||
* to be caught outside twr block
|
||||
* @compile/fail/ref=TwrIntersection02.out -XDrawDiagnostics TwrIntersection02.java
|
||||
*/
|
||||
|
||||
class TwrIntersection02 {
|
||||
|
||||
static class Exception1 extends Exception {}
|
||||
static class Exception2 extends Exception {}
|
||||
|
||||
|
||||
interface MyResource1 extends AutoCloseable {
|
||||
void close() throws Exception1;
|
||||
}
|
||||
|
||||
interface MyResource2 extends AutoCloseable {
|
||||
void close() throws Exception2;
|
||||
}
|
||||
|
||||
public void test1() throws Exception1 {
|
||||
try(getX()) {
|
||||
//do something
|
||||
}
|
||||
}
|
||||
|
||||
public void test2() throws Exception2 {
|
||||
try(getX()) {
|
||||
//do something
|
||||
}
|
||||
}
|
||||
|
||||
<X extends MyResource1 & MyResource2> X getX() { return null; }
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
TwrIntersection02.java:25:21: compiler.err.unreported.exception.need.to.catch.or.throw: TwrIntersection02.Exception2
|
||||
TwrIntersection02.java:31:21: compiler.err.unreported.exception.need.to.catch.or.throw: TwrIntersection02.Exception1
|
||||
2 errors
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6911256 6964740
|
||||
* @bug 6911256 6964740 7013420
|
||||
* @author Joseph D. Darcy
|
||||
* @summary Test that TWR and multi-catch play well together
|
||||
* @compile TwrMultiCatch.java
|
||||
@ -48,9 +48,9 @@ public class TwrMultiCatch implements AutoCloseable {
|
||||
|
||||
private static void test(TwrMultiCatch twrMultiCatch,
|
||||
Class<? extends Exception> expected) {
|
||||
try(twrMultiCatch) {
|
||||
System.out.println(twrMultiCatch.toString());
|
||||
} catch (final CustomCloseException1 |
|
||||
try(TwrMultiCatch tmc = twrMultiCatch) {
|
||||
System.out.println(tmc.toString());
|
||||
} catch (CustomCloseException1 |
|
||||
CustomCloseException2 exception) {
|
||||
if (!exception.getClass().equals(expected) ) {
|
||||
throw new RuntimeException("Unexpected catch!");
|
||||
@ -68,7 +68,7 @@ public class TwrMultiCatch implements AutoCloseable {
|
||||
|
||||
try {
|
||||
throw t;
|
||||
} catch (final CustomCloseException1 |
|
||||
} catch (CustomCloseException1 |
|
||||
CustomCloseException2 exception) {
|
||||
throw exception;
|
||||
} catch (Throwable throwable) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6911256 6964740
|
||||
* @bug 6911256 6964740 7013420
|
||||
* @author Joseph D. Darcy
|
||||
* @summary Verify invalid TWR block is not accepted.
|
||||
* @compile/fail -source 6 TwrOnNonResource.java
|
||||
@ -18,18 +18,6 @@ class TwrOnNonResource {
|
||||
try(TwrOnNonResource aonr = new TwrOnNonResource()) {
|
||||
System.out.println(aonr.toString());
|
||||
} catch (Exception e) {;}
|
||||
|
||||
// Also check expression form
|
||||
TwrOnNonResource aonr = new TwrOnNonResource();
|
||||
try(aonr) {
|
||||
System.out.println(aonr.toString());
|
||||
}
|
||||
try(aonr) {
|
||||
System.out.println(aonr.toString());
|
||||
} finally {;}
|
||||
try(aonr) {
|
||||
System.out.println(aonr.toString());
|
||||
} catch (Exception e) {;}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
TwrOnNonResource.java:12:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
||||
TwrOnNonResource.java:15:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
||||
TwrOnNonResource.java:18:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
||||
TwrOnNonResource.java:24:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
||||
TwrOnNonResource.java:27:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
||||
TwrOnNonResource.java:30:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
||||
6 errors
|
||||
3 errors
|
||||
|
||||
346
langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java
Normal file
346
langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java
Normal file
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import javax.tools.*;
|
||||
|
||||
import com.sun.tools.javac.api.*;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
||||
import com.sun.tools.javac.api.Formattable.LocalizedString;
|
||||
import com.sun.tools.javac.code.Flags.Flag;
|
||||
import com.sun.tools.javac.code.Kinds.KindName;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.file.*;
|
||||
import com.sun.tools.javac.main.Main;
|
||||
import com.sun.tools.javac.parser.Token;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
|
||||
import javax.lang.model.SourceVersion;
|
||||
|
||||
/**
|
||||
* Compiler factory for instances of Example.Compiler that use custom
|
||||
* DiagnosticFormatter and Messages objects to track the types of args
|
||||
* when when localizing diagnostics.
|
||||
* The compiler objects only support "output" mode, not "check" mode.
|
||||
*/
|
||||
class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
||||
// Same code as Example.Compiler.DefaultFactory, but the names resolve differently
|
||||
public Example.Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
String first;
|
||||
String[] rest;
|
||||
if (opts == null || opts.isEmpty()) {
|
||||
first = null;
|
||||
rest = new String[0];
|
||||
} else {
|
||||
first = opts.get(0);
|
||||
rest = opts.subList(1, opts.size()).toArray(new String[opts.size() - 1]);
|
||||
}
|
||||
if (first == null || first.equals("jsr199"))
|
||||
return new Jsr199Compiler(verbose, rest);
|
||||
else if (first.equals("simple"))
|
||||
return new SimpleCompiler(verbose);
|
||||
else if (first.equals("backdoor"))
|
||||
return new BackdoorCompiler(verbose);
|
||||
else
|
||||
throw new IllegalArgumentException(first);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile using the JSR 199 API. The diagnostics generated are
|
||||
* scanned for resource keys. Not all diagnostic keys are generated
|
||||
* via the JSR 199 API -- for example, rich diagnostics are not directly
|
||||
* accessible, and some diagnostics generated by the file manager may
|
||||
* not be generated (for example, the JSR 199 file manager does not see
|
||||
* -Xlint:path).
|
||||
*/
|
||||
static class Jsr199Compiler extends Example.Compiler {
|
||||
List<String> fmOpts;
|
||||
|
||||
Jsr199Compiler(boolean verbose, String... args) {
|
||||
super(verbose);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (arg.equals("-filemanager") && (i + 1 < args.length)) {
|
||||
fmOpts = Arrays.asList(args[++i].split(","));
|
||||
} else
|
||||
throw new IllegalArgumentException(arg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
|
||||
assert out != null && keys == null;
|
||||
|
||||
if (verbose)
|
||||
System.err.println("run_jsr199: " + opts + " " + files);
|
||||
|
||||
JavacTool tool = JavacTool.create();
|
||||
|
||||
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
|
||||
if (fmOpts != null)
|
||||
fm = new FileManager(fm, fmOpts);
|
||||
|
||||
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
|
||||
|
||||
JavacTaskImpl t = (JavacTaskImpl) tool.getTask(out, fm, null, opts, null, fos);
|
||||
Context c = t.getContext();
|
||||
ArgTypeMessages.preRegister(c);
|
||||
Options options = Options.instance(c);
|
||||
Log.instance(c).setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
|
||||
Boolean ok = t.call();
|
||||
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the test using the standard simple entry point.
|
||||
*/
|
||||
static class SimpleCompiler extends Example.Compiler {
|
||||
SimpleCompiler(boolean verbose) {
|
||||
super(verbose);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
|
||||
assert out != null && keys == null;
|
||||
|
||||
if (verbose)
|
||||
System.err.println("run_simple: " + opts + " " + files);
|
||||
|
||||
List<String> args = new ArrayList<String>();
|
||||
|
||||
args.addAll(opts);
|
||||
for (File f: files)
|
||||
args.add(f.getPath());
|
||||
|
||||
Main main = new Main("javac", out);
|
||||
Context c = new Context() {
|
||||
@Override public void clear() {
|
||||
((JavacFileManager) get(JavaFileManager.class)).close();
|
||||
super.clear();
|
||||
}
|
||||
};
|
||||
JavacFileManager.preRegister(c); // can't create it until Log has been set up
|
||||
ArgTypeDiagnosticFormatter.preRegister(c);
|
||||
ArgTypeMessages.preRegister(c);
|
||||
int result = main.compile(args.toArray(new String[args.size()]), c);
|
||||
|
||||
return (result == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static class BackdoorCompiler extends Example.Compiler {
|
||||
BackdoorCompiler(boolean verbose) {
|
||||
super(verbose);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
|
||||
assert out != null && keys == null;
|
||||
|
||||
if (verbose)
|
||||
System.err.println("run_simple: " + opts + " " + files);
|
||||
|
||||
List<String> args = new ArrayList<String>(opts);
|
||||
for (File f: files)
|
||||
args.add(f.getPath());
|
||||
|
||||
Context c = new Context();
|
||||
JavacFileManager.preRegister(c); // can't create it until Log has been set up
|
||||
ArgTypeDiagnosticFormatter.preRegister(c);
|
||||
ArgTypeMessages.preRegister(c);
|
||||
com.sun.tools.javac.main.Main m = new com.sun.tools.javac.main.Main("javac", out);
|
||||
int rc = m.compile(args.toArray(new String[args.size()]), c);
|
||||
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Custom Javac components">
|
||||
|
||||
/**
|
||||
* Diagnostic formatter which reports formats a diag as a series of lines
|
||||
* containing a key, and a possibly empty set of descriptive strings for the
|
||||
* arg types.
|
||||
*/
|
||||
static class ArgTypeDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
||||
static void preRegister(final Context context) {
|
||||
context.put(Log.logKey, new Context.Factory<Log>() {
|
||||
public Log make() {
|
||||
Log log = new Log(context) { };
|
||||
Options options = Options.instance(context);
|
||||
log.setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
|
||||
return log;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
ArgTypeDiagnosticFormatter(Options options) {
|
||||
super(null, new SimpleConfiguration(options,
|
||||
EnumSet.of(DiagnosticPart.SUMMARY,
|
||||
DiagnosticPart.DETAILS,
|
||||
DiagnosticPart.SUBDIAGNOSTICS)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatDiagnostic(JCDiagnostic d, Locale locale) {
|
||||
return formatMessage(d, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatMessage(JCDiagnostic d, Locale l) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
formatMessage(d, buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private void formatMessage(JCDiagnostic d, StringBuilder buf) {
|
||||
String key = d.getCode();
|
||||
Object[] args = d.getArgs();
|
||||
// report the primary arg types, without recursing into diag fragments
|
||||
buf.append(getKeyArgsString(key, args));
|
||||
// report details for any diagnostic fragments
|
||||
for (Object arg: args) {
|
||||
if (arg instanceof JCDiagnostic) {
|
||||
buf.append("\n");
|
||||
formatMessage((JCDiagnostic) arg, buf);
|
||||
}
|
||||
}
|
||||
// report details for any subdiagnostics
|
||||
for (String s: formatSubdiagnostics(d, null)) {
|
||||
buf.append("\n");
|
||||
buf.append(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRaw() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagnostic formatter which "localizes" a message as a line
|
||||
* containing a key, and a possibly empty set of descriptive strings for the
|
||||
* arg types.
|
||||
*/
|
||||
static class ArgTypeMessages extends JavacMessages {
|
||||
static void preRegister(final Context c) {
|
||||
c.put(JavacMessages.messagesKey, new Context.Factory<JavacMessages>() {
|
||||
public JavacMessages make() {
|
||||
return new ArgTypeMessages(c) {
|
||||
@Override
|
||||
public String getLocalizedString(Locale l, String key, Object... args) {
|
||||
return getKeyArgsString(key, args);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ArgTypeMessages(Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to generate a string for key and args
|
||||
*/
|
||||
static String getKeyArgsString(String key, Object... args) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(key);
|
||||
String sep = ": ";
|
||||
for (Object o : args) {
|
||||
buf.append(sep);
|
||||
buf.append(getArgTypeOrStringValue(o));
|
||||
sep = ", ";
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
static boolean showStringValues = false;
|
||||
|
||||
static String getArgTypeOrStringValue(Object o) {
|
||||
if (showStringValues && o instanceof String)
|
||||
return "\"" + o + "\"";
|
||||
return getArgType(o);
|
||||
}
|
||||
|
||||
static String getArgType(Object o) {
|
||||
if (o == null)
|
||||
return "null";
|
||||
if (o instanceof Name)
|
||||
return "name";
|
||||
if (o instanceof Boolean)
|
||||
return "boolean";
|
||||
if (o instanceof Integer)
|
||||
return "number";
|
||||
if (o instanceof String)
|
||||
return "string";
|
||||
if (o instanceof Flag)
|
||||
return "modifier";
|
||||
if (o instanceof KindName)
|
||||
return "symbol kind";
|
||||
if (o instanceof Token)
|
||||
return "token";
|
||||
if (o instanceof Symbol)
|
||||
return "symbol";
|
||||
if (o instanceof Type)
|
||||
return "type";
|
||||
if (o instanceof List) {
|
||||
List<?> l = (List<?>) o;
|
||||
if (l.isEmpty())
|
||||
return "list";
|
||||
else
|
||||
return "list of " + getArgType(l.get(0));
|
||||
}
|
||||
if (o instanceof ListBuffer)
|
||||
return getArgType(((ListBuffer) o).toList());
|
||||
if (o instanceof Set) {
|
||||
Set<?> s = (Set<?>) o;
|
||||
if (s.isEmpty())
|
||||
return "set";
|
||||
else
|
||||
return "set of " + getArgType(s.iterator().next());
|
||||
}
|
||||
if (o instanceof SourceVersion)
|
||||
return "source version";
|
||||
if (o instanceof FileObject || o instanceof File)
|
||||
return "file name";
|
||||
if (o instanceof JCDiagnostic)
|
||||
return "message segment";
|
||||
if (o instanceof LocalizedString)
|
||||
return "message segment"; // only instance is "no arguments"
|
||||
String s = o.getClass().getSimpleName();
|
||||
return (s.isEmpty() ? o.getClass().getName() : s);
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -168,7 +168,7 @@ class Example implements Comparable<Example> {
|
||||
try {
|
||||
run(null, keys, true, verbose);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
@ -293,10 +293,15 @@ class Example implements Comparable<Example> {
|
||||
}
|
||||
|
||||
abstract static class Compiler {
|
||||
static Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
interface Factory {
|
||||
Compiler getCompiler(List<String> opts, boolean verbose);
|
||||
}
|
||||
|
||||
static class DefaultFactory implements Factory {
|
||||
public Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
String first;
|
||||
String[] rest;
|
||||
if (opts == null || opts.size() == 0) {
|
||||
if (opts == null || opts.isEmpty()) {
|
||||
first = null;
|
||||
rest = new String[0];
|
||||
} else {
|
||||
@ -311,6 +316,16 @@ class Example implements Comparable<Example> {
|
||||
return new BackdoorCompiler(verbose);
|
||||
else
|
||||
throw new IllegalArgumentException(first);
|
||||
}
|
||||
}
|
||||
|
||||
static Factory factory;
|
||||
|
||||
static Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
if (factory == null)
|
||||
factory = new DefaultFactory();
|
||||
|
||||
return factory.getCompiler(opts, verbose);
|
||||
}
|
||||
|
||||
protected Compiler(boolean verbose) {
|
||||
|
||||
463
langtools/test/tools/javac/diags/MessageFile.java
Normal file
463
langtools/test/tools/javac/diags/MessageFile.java
Normal file
@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Class to facilitate manipulating compiler.properties.
|
||||
*/
|
||||
class MessageFile {
|
||||
static final Pattern emptyOrCommentPattern = Pattern.compile("( *#.*)?");
|
||||
static final Pattern infoPattern = Pattern.compile("# ([0-9]+: [-A-Za-z ]+, )*[0-9]+: [-A-Za-z ]+");
|
||||
|
||||
/**
|
||||
* A line of text within the message file.
|
||||
* The lines form a doubly linked list for simple navigation.
|
||||
*/
|
||||
class Line {
|
||||
String text;
|
||||
Line prev;
|
||||
Line next;
|
||||
|
||||
Line(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
boolean isEmptyOrComment() {
|
||||
return emptyOrCommentPattern.matcher(text).matches();
|
||||
}
|
||||
|
||||
boolean isInfo() {
|
||||
return infoPattern.matcher(text).matches();
|
||||
}
|
||||
|
||||
boolean hasContinuation() {
|
||||
return (next != null) && text.endsWith("\\");
|
||||
}
|
||||
|
||||
Line insertAfter(String text) {
|
||||
Line l = new Line(text);
|
||||
insertAfter(l);
|
||||
return l;
|
||||
}
|
||||
|
||||
void insertAfter(Line l) {
|
||||
assert prev == null && next == null;
|
||||
l.prev = this;
|
||||
l.next = next;
|
||||
if (next == null)
|
||||
lastLine = l;
|
||||
else
|
||||
next.prev = l;
|
||||
next = l;
|
||||
}
|
||||
|
||||
Line insertBefore(String text) {
|
||||
Line l = new Line(text);
|
||||
insertBefore(l);
|
||||
return l;
|
||||
}
|
||||
|
||||
void insertBefore(Line l) {
|
||||
assert prev == null && next == null;
|
||||
l.prev = prev;
|
||||
l.next = this;
|
||||
if (prev == null)
|
||||
firstLine = l;
|
||||
else
|
||||
prev.next = l;
|
||||
prev = l;
|
||||
}
|
||||
|
||||
void remove() {
|
||||
if (prev == null)
|
||||
firstLine = next;
|
||||
else
|
||||
prev.next = next;
|
||||
if (next == null)
|
||||
lastLine = prev;
|
||||
else
|
||||
next.prev = prev;
|
||||
prev = null;
|
||||
next = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A message within the message file.
|
||||
* A message is a series of lines containing a "name=value" property,
|
||||
* optionally preceded by a comment describing the use of placeholders
|
||||
* such as {0}, {1}, etc within the property value.
|
||||
*/
|
||||
static final class Message {
|
||||
final Line firstLine;
|
||||
private Info info;
|
||||
|
||||
Message(Line l) {
|
||||
firstLine = l;
|
||||
}
|
||||
|
||||
boolean needInfo() {
|
||||
Line l = firstLine;
|
||||
while (true) {
|
||||
if (l.text.matches(".*\\{[0-9]+\\}.*"))
|
||||
return true;
|
||||
if (!l.hasContinuation())
|
||||
return false;
|
||||
l = l.next;
|
||||
}
|
||||
}
|
||||
|
||||
Set<Integer> getPlaceholders() {
|
||||
Pattern p = Pattern.compile("\\{([0-9]+)\\}");
|
||||
Set<Integer> results = new TreeSet<Integer>();
|
||||
Line l = firstLine;
|
||||
while (true) {
|
||||
Matcher m = p.matcher(l.text);
|
||||
while (m.find())
|
||||
results.add(Integer.parseInt(m.group(1)));
|
||||
if (!l.hasContinuation())
|
||||
return results;
|
||||
l = l.next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Info object for this message. It may be empty if there
|
||||
* if no comment preceding the property specification.
|
||||
*/
|
||||
Info getInfo() {
|
||||
if (info == null) {
|
||||
Line l = firstLine.prev;
|
||||
if (l != null && l.isInfo())
|
||||
info = new Info(l.text);
|
||||
else
|
||||
info = new Info();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Info for this message.
|
||||
* If there was an info comment preceding the property specification,
|
||||
* it will be updated; otherwise, one will be inserted.
|
||||
*/
|
||||
void setInfo(Info info) {
|
||||
this.info = info;
|
||||
Line l = firstLine.prev;
|
||||
if (l != null && l.isInfo())
|
||||
l.text = info.toComment();
|
||||
else
|
||||
firstLine.insertBefore(info.toComment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the lines pertaining to this message.
|
||||
*/
|
||||
List<Line> getLines(boolean includeAllPrecedingComments) {
|
||||
List<Line> lines = new ArrayList<Line>();
|
||||
Line l = firstLine;
|
||||
if (includeAllPrecedingComments) {
|
||||
// scan back to find end of prev message
|
||||
while (l.prev != null && l.prev.isEmptyOrComment())
|
||||
l = l.prev;
|
||||
// skip leading blank lines
|
||||
while (l.text.isEmpty())
|
||||
l = l.next;
|
||||
} else {
|
||||
if (l.prev != null && l.prev.isInfo())
|
||||
l = l.prev;
|
||||
}
|
||||
|
||||
// include any preceding lines
|
||||
for ( ; l != firstLine; l = l.next)
|
||||
lines.add(l);
|
||||
|
||||
// include message lines
|
||||
for (l = firstLine; l != null && l.hasContinuation(); l = l.next)
|
||||
lines.add(l);
|
||||
lines.add(l);
|
||||
|
||||
// include trailing blank line if present
|
||||
l = l.next;
|
||||
if (l != null && l.text.isEmpty())
|
||||
lines.add(l);
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An object to represent the comment that may precede the property
|
||||
* specification in a Message.
|
||||
* The comment is modelled as a list of fields, where the fields correspond
|
||||
* to the placeholder values (e.g. {0}, {1}, etc) within the message value.
|
||||
*/
|
||||
static final class Info {
|
||||
/**
|
||||
* An ordered set of descriptions for a placeholder value in a
|
||||
* message.
|
||||
*/
|
||||
static class Field {
|
||||
boolean unused;
|
||||
Set<String> values;
|
||||
boolean listOfAny = false;
|
||||
boolean setOfAny = false;
|
||||
Field(String s) {
|
||||
s = s.substring(s.indexOf(": ") + 2);
|
||||
values = new LinkedHashSet<String>(Arrays.asList(s.split(" or ")));
|
||||
for (String v: values) {
|
||||
if (v.startsWith("list of"))
|
||||
listOfAny = true;
|
||||
if (v.startsWith("set of"))
|
||||
setOfAny = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this field logically contains all the values of
|
||||
* another field.
|
||||
*/
|
||||
boolean contains(Field other) {
|
||||
if (unused != other.unused)
|
||||
return false;
|
||||
|
||||
for (String v: other.values) {
|
||||
if (values.contains(v))
|
||||
continue;
|
||||
if (v.equals("null") || v.equals("string"))
|
||||
continue;
|
||||
if (v.equals("list") && listOfAny)
|
||||
continue;
|
||||
if (v.equals("set") && setOfAny)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the values of another field into this field.
|
||||
*/
|
||||
void merge(Field other) {
|
||||
unused |= other.unused;
|
||||
values.addAll(other.values);
|
||||
|
||||
// cleanup unnecessary entries
|
||||
|
||||
if (values.contains("null") && values.size() > 1) {
|
||||
// "null" is superceded by anything else
|
||||
values.remove("null");
|
||||
}
|
||||
|
||||
if (values.contains("string") && values.size() > 1) {
|
||||
// "string" is superceded by anything else
|
||||
values.remove("string");
|
||||
}
|
||||
|
||||
if (values.contains("list")) {
|
||||
// list is superceded by "list of ..."
|
||||
for (String s: values) {
|
||||
if (s.startsWith("list of ")) {
|
||||
values.remove("list");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (values.contains("set")) {
|
||||
// set is superceded by "set of ..."
|
||||
for (String s: values) {
|
||||
if (s.startsWith("set of ")) {
|
||||
values.remove("set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (other.values.contains("unused")) {
|
||||
values.clear();
|
||||
values.add("unused");
|
||||
}
|
||||
}
|
||||
|
||||
void markUnused() {
|
||||
values = new LinkedHashSet<String>();
|
||||
values.add("unused");
|
||||
listOfAny = false;
|
||||
setOfAny = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return values.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/** The fields of the Info object. */
|
||||
List<Field> fields = new ArrayList<Field>();
|
||||
|
||||
Info() { }
|
||||
|
||||
Info(String text) throws IllegalArgumentException {
|
||||
if (!text.startsWith("# "))
|
||||
throw new IllegalArgumentException();
|
||||
String[] segs = text.substring(2).split(", ");
|
||||
fields = new ArrayList<Field>();
|
||||
for (String seg: segs) {
|
||||
fields.add(new Field(seg));
|
||||
}
|
||||
}
|
||||
|
||||
Info(Set<String> infos) throws IllegalArgumentException {
|
||||
for (String s: infos)
|
||||
merge(new Info(s));
|
||||
}
|
||||
|
||||
boolean isEmpty() {
|
||||
return fields.isEmpty();
|
||||
}
|
||||
|
||||
boolean contains(Info other) {
|
||||
if (other.isEmpty())
|
||||
return true;
|
||||
|
||||
if (fields.size() != other.fields.size())
|
||||
return false;
|
||||
|
||||
Iterator<Field> oIter = other.fields.iterator();
|
||||
for (Field values: fields) {
|
||||
if (!values.contains(oIter.next()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void merge(Info other) {
|
||||
if (fields.isEmpty()) {
|
||||
fields.addAll(other.fields);
|
||||
return;
|
||||
}
|
||||
|
||||
if (other.fields.size() != fields.size())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
Iterator<Field> oIter = other.fields.iterator();
|
||||
for (Field d: fields) {
|
||||
d.merge(oIter.next());
|
||||
}
|
||||
}
|
||||
|
||||
void markUnused(Set<Integer> used) {
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
if (!used.contains(i))
|
||||
fields.get(i).markUnused();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fields.toString();
|
||||
}
|
||||
|
||||
String toComment() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("# ");
|
||||
String sep = "";
|
||||
int i = 0;
|
||||
for (Field f: fields) {
|
||||
sb.append(sep);
|
||||
sb.append(i++);
|
||||
sb.append(": ");
|
||||
sep = "";
|
||||
for (String s: f.values) {
|
||||
sb.append(sep);
|
||||
sb.append(s);
|
||||
sep = " or ";
|
||||
}
|
||||
sep = ", ";
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Line firstLine;
|
||||
Line lastLine;
|
||||
Map<String, Message> messages = new TreeMap<String, Message>();
|
||||
|
||||
MessageFile(File file) throws IOException {
|
||||
Reader in = new FileReader(file);
|
||||
try {
|
||||
read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
MessageFile(Reader in) throws IOException {
|
||||
read(in);
|
||||
}
|
||||
|
||||
final void read(Reader in) throws IOException {
|
||||
BufferedReader br = (in instanceof BufferedReader)
|
||||
? (BufferedReader) in
|
||||
: new BufferedReader(in);
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
Line l;
|
||||
if (firstLine == null)
|
||||
l = firstLine = lastLine = new Line(line);
|
||||
else
|
||||
l = lastLine.insertAfter(line);
|
||||
if (line.startsWith("compiler.")) {
|
||||
int eq = line.indexOf("=");
|
||||
if (eq > 0)
|
||||
messages.put(line.substring(0, eq), new Message(l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write(File file) throws IOException {
|
||||
Writer out = new FileWriter(file);
|
||||
try {
|
||||
write(out);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
void write(Writer out) throws IOException {
|
||||
BufferedWriter bw = (out instanceof BufferedWriter)
|
||||
? (BufferedWriter) out
|
||||
: new BufferedWriter(out);
|
||||
for (Line l = firstLine; l != null; l = l.next) {
|
||||
bw.write(l.text);
|
||||
bw.write("\n"); // always use Unix line endings
|
||||
}
|
||||
bw.flush();
|
||||
}
|
||||
}
|
||||
410
langtools/test/tools/javac/diags/MessageInfo.java
Normal file
410
langtools/test/tools/javac/diags/MessageInfo.java
Normal file
@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 7013272
|
||||
* @summary Automatically generate info about how compiler resource keys are used
|
||||
* @build Example ArgTypeCompilerFactory MessageFile MessageInfo
|
||||
* @run main MessageInfo
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Utility to manipulate compiler.properties, and suggest info comments based
|
||||
* on information derived from running examples.
|
||||
*
|
||||
* Options:
|
||||
* -examples dir location of examples directory
|
||||
* -o file output file
|
||||
* -check just check message file
|
||||
* -ensureNewlines ensure newline after each entry
|
||||
* -fixIndent fix indentation of continuation lines
|
||||
* -sort sort messages
|
||||
* -verbose verbose output
|
||||
* -replace replace comments instead of merging comments
|
||||
* file javac compiler.properties file
|
||||
*
|
||||
*/
|
||||
public class MessageInfo {
|
||||
public static void main(String... args) throws Exception {
|
||||
jtreg = (System.getProperty("test.src") != null);
|
||||
File tmpDir;
|
||||
if (jtreg) {
|
||||
// use standard jtreg scratch directory: the current directory
|
||||
tmpDir = new File(System.getProperty("user.dir"));
|
||||
} else {
|
||||
tmpDir = new File(System.getProperty("java.io.tmpdir"),
|
||||
MessageInfo.class.getName()
|
||||
+ (new SimpleDateFormat("yyMMddHHmmss")).format(new Date()));
|
||||
}
|
||||
Example.setTempDir(tmpDir);
|
||||
Example.Compiler.factory = new ArgTypeCompilerFactory();
|
||||
|
||||
MessageInfo mi = new MessageInfo();
|
||||
|
||||
try {
|
||||
if (mi.run(args))
|
||||
return;
|
||||
} finally {
|
||||
/* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the
|
||||
* jtreg scratch directory, which is the current directory.
|
||||
* In case someone is faking jtreg mode, make sure to only
|
||||
* clean tmpDir when it is reasonable to do so.
|
||||
*/
|
||||
if (tmpDir.isDirectory() &&
|
||||
tmpDir.getName().startsWith(MessageInfo.class.getName())) {
|
||||
if (clean(tmpDir))
|
||||
tmpDir.delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (jtreg)
|
||||
throw new Exception(mi.errors + " errors occurred");
|
||||
else
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
void usage() {
|
||||
System.out.println("Usage:");
|
||||
System.out.println(" java MessageInfo [options] [file]");
|
||||
System.out.println("where options include");
|
||||
System.out.println(" -examples dir location of examples directory");
|
||||
System.out.println(" -o file output file");
|
||||
System.out.println(" -check just check message file");
|
||||
System.out.println(" -ensureNewlines ensure newline after each entry");
|
||||
System.out.println(" -fixIndent fix indentation of continuation lines");
|
||||
System.out.println(" -sort sort messages");
|
||||
System.out.println(" -verbose verbose output");
|
||||
System.out.println(" -replace replace comments instead of merging comments");
|
||||
System.out.println(" file javac compiler.properties file");
|
||||
}
|
||||
|
||||
boolean run(String... args) {
|
||||
File testSrc = new File(System.getProperty("test.src", "."));
|
||||
File examplesDir = new File(testSrc, "examples");
|
||||
File notYetFile = null;
|
||||
File msgFile = null;
|
||||
File outFile = null;
|
||||
boolean verbose = false;
|
||||
boolean ensureNewlines = false;
|
||||
boolean fixIndent = false;
|
||||
boolean sort = false;
|
||||
boolean replace = false;
|
||||
boolean check = jtreg; // default true in jtreg mode
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (arg.equals("-examples") && (i + 1) < args.length)
|
||||
examplesDir = new File(args[++i]);
|
||||
else if(arg.equals("-notyet") && (i + 1) < args.length)
|
||||
notYetFile = new File(args[++i]);
|
||||
else if (arg.equals("-ensureNewlines"))
|
||||
ensureNewlines = true;
|
||||
else if (arg.equals("-fixIndent"))
|
||||
fixIndent = true;
|
||||
else if (arg.equals("-sort"))
|
||||
sort = true;
|
||||
else if (arg.equals("-verbose"))
|
||||
verbose = true;
|
||||
else if (arg.equals("-replace"))
|
||||
replace = true;
|
||||
else if (arg.equals("-check"))
|
||||
check = true;
|
||||
else if (arg.equals("-o") && (i + 1) < args.length)
|
||||
outFile = new File(args[++i]);
|
||||
else if (arg.startsWith("-")) {
|
||||
error("unknown option: " + arg);
|
||||
return false;
|
||||
} else if (i == args.length - 1) {
|
||||
msgFile = new File(arg);
|
||||
} else {
|
||||
error("unknown arg: " + arg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check && outFile == null) {
|
||||
usage();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((ensureNewlines || fixIndent || sort) && outFile == null) {
|
||||
error("must set output file for these options");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (notYetFile == null) {
|
||||
notYetFile = new File(examplesDir.getParentFile(), "examples.not-yet.txt");
|
||||
}
|
||||
|
||||
if (msgFile == null) {
|
||||
for (File d = testSrc; d != null; d = d.getParentFile()) {
|
||||
if (new File(d, "TEST.ROOT").exists()) {
|
||||
d = d.getParentFile();
|
||||
File f = new File(d, "src/share/classes/com/sun/tools/javac/resources/compiler.properties");
|
||||
if (f.exists()) {
|
||||
msgFile = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (msgFile == null) {
|
||||
if (jtreg) {
|
||||
System.err.println("Warning: no message file available, test skipped");
|
||||
return true;
|
||||
}
|
||||
error("no message file available");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MessageFile mf;
|
||||
try {
|
||||
mf = new MessageFile(msgFile);
|
||||
} catch (IOException e) {
|
||||
error("problem reading message file: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<String, Set<String>> msgInfo = runExamples(examplesDir, verbose);
|
||||
|
||||
if (ensureNewlines)
|
||||
ensureNewlines(mf);
|
||||
|
||||
if (fixIndent)
|
||||
fixIndent(mf);
|
||||
|
||||
if (sort)
|
||||
sort(mf, true);
|
||||
|
||||
for (Map.Entry<String, Set<String>> e: msgInfo.entrySet()) {
|
||||
String k = e.getKey();
|
||||
Set<String> suggestions = e.getValue();
|
||||
MessageFile.Message m = mf.messages.get(k);
|
||||
if (m == null) {
|
||||
error("Can't find message for " + k + " in message file");
|
||||
continue;
|
||||
}
|
||||
|
||||
MessageFile.Info info = m.getInfo();
|
||||
Set<Integer> placeholders = m.getPlaceholders();
|
||||
MessageFile.Info suggestedInfo = new MessageFile.Info(suggestions);
|
||||
suggestedInfo.markUnused(placeholders);
|
||||
|
||||
if (!info.isEmpty()) {
|
||||
if (info.contains(suggestedInfo))
|
||||
continue;
|
||||
if (!replace) {
|
||||
if (info.fields.size() != suggestedInfo.fields.size())
|
||||
error("Cannot merge info for " + k);
|
||||
else
|
||||
suggestedInfo.merge(info);
|
||||
}
|
||||
}
|
||||
|
||||
if (outFile == null) {
|
||||
System.err.println("suggest for " + k);
|
||||
System.err.println(suggestedInfo.toComment());
|
||||
} else
|
||||
m.setInfo(suggestedInfo);
|
||||
}
|
||||
|
||||
if (check)
|
||||
check(mf, notYetFile);
|
||||
|
||||
try {
|
||||
if (outFile != null)
|
||||
mf.write(outFile);
|
||||
} catch (IOException e) {
|
||||
error("problem writing file: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return (errors == 0);
|
||||
}
|
||||
|
||||
void check(MessageFile mf, File notYetFile) {
|
||||
Set<String> notYetList = null;
|
||||
for (Map.Entry<String, MessageFile.Message> e: mf.messages.entrySet()) {
|
||||
String key = e.getKey();
|
||||
MessageFile.Message m = e.getValue();
|
||||
if (m.needInfo() && m.getInfo().isEmpty()) {
|
||||
if (notYetList == null)
|
||||
notYetList = getNotYetList(notYetFile);
|
||||
if (notYetList.contains(key))
|
||||
System.err.println("Warning: no info for " + key);
|
||||
else
|
||||
error("no info for " + key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ensureNewlines(MessageFile mf) {
|
||||
for (MessageFile.Message m: mf.messages.values()) {
|
||||
MessageFile.Line l = m.firstLine;
|
||||
while (l.text.endsWith("\\"))
|
||||
l = l.next;
|
||||
if (l.next != null && !l.next.text.isEmpty())
|
||||
l.insertAfter("");
|
||||
}
|
||||
}
|
||||
|
||||
void fixIndent(MessageFile mf) {
|
||||
for (MessageFile.Message m: mf.messages.values()) {
|
||||
MessageFile.Line l = m.firstLine;
|
||||
while (l.text.endsWith("\\") && l.next != null) {
|
||||
if (!l.next.text.matches("^ \\S.*"))
|
||||
l.next.text = " " + l.next.text.trim();
|
||||
l = l.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sort(MessageFile mf, boolean includePrecedingNewlines) {
|
||||
for (MessageFile.Message m: mf.messages.values()) {
|
||||
for (MessageFile.Line l: m.getLines(includePrecedingNewlines)) {
|
||||
l.remove();
|
||||
mf.lastLine.insertAfter(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Set<String>> runExamples(File examplesDir, boolean verbose) {
|
||||
Map<String, Set<String>> map = new TreeMap<String, Set<String>>();
|
||||
for (Example e: getExamples(examplesDir)) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.run(pw, true, verbose);
|
||||
pw.close();
|
||||
String[] lines = sw.toString().split("\n");
|
||||
for (String line: lines) {
|
||||
if (!line.startsWith("compiler."))
|
||||
continue;
|
||||
int colon = line.indexOf(":");
|
||||
if (colon == -1)
|
||||
continue;
|
||||
String key = line.substring(0, colon);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("# ");
|
||||
int i = 0;
|
||||
String[] descs = line.substring(colon + 1).split(", *");
|
||||
for (String desc: descs) {
|
||||
if (i > 0) sb.append(", ");
|
||||
sb.append(i++);
|
||||
sb.append(": ");
|
||||
sb.append(desc.trim());
|
||||
}
|
||||
Set<String> set = map.get(key);
|
||||
if (set == null)
|
||||
map.put(key, set = new TreeSet<String>());
|
||||
set.add(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the complete set of examples to be checked.
|
||||
*/
|
||||
Set<Example> getExamples(File examplesDir) {
|
||||
Set<Example> results = new TreeSet<Example>();
|
||||
for (File f: examplesDir.listFiles()) {
|
||||
if (isValidExample(f))
|
||||
results.add(new Example(f));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
boolean isValidExample(File f) {
|
||||
return (f.isDirectory() && (!jtreg || f.list().length > 0)) ||
|
||||
(f.isFile() && f.getName().endsWith(".java"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of the "not-yet" list.
|
||||
*/
|
||||
Set<String> getNotYetList(File file) {
|
||||
Set<String> results = new TreeSet<String>();
|
||||
try {
|
||||
String[] lines = read(file).split("[\r\n]");
|
||||
for (String line: lines) {
|
||||
int hash = line.indexOf("#");
|
||||
if (hash != -1)
|
||||
line = line.substring(0, hash).trim();
|
||||
if (line.matches("[A-Za-z0-9-_.]+"))
|
||||
results.add(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the contents of a file.
|
||||
*/
|
||||
String read(File f) throws IOException {
|
||||
byte[] bytes = new byte[(int) f.length()];
|
||||
DataInputStream in = new DataInputStream(new FileInputStream(f));
|
||||
try {
|
||||
in.readFully(bytes);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an error.
|
||||
*/
|
||||
void error(String msg) {
|
||||
System.err.println("Error: " + msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
static boolean jtreg;
|
||||
|
||||
int errors;
|
||||
|
||||
/**
|
||||
* Clean the contents of a directory.
|
||||
*/
|
||||
static boolean clean(File dir) {
|
||||
boolean ok = true;
|
||||
for (File f: dir.listFiles()) {
|
||||
if (f.isDirectory())
|
||||
ok &= clean(f);
|
||||
ok &= f.delete();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,7 @@
|
||||
* @test
|
||||
* @bug 6968063
|
||||
* @summary provide examples of code that generate diagnostics
|
||||
* @build Example HTMLWriter RunExamples
|
||||
* @build ArgTypeCompilerFactory Example HTMLWriter RunExamples
|
||||
* @run main RunExamples
|
||||
*/
|
||||
|
||||
@ -97,6 +97,7 @@ public class RunExamples {
|
||||
boolean raw = false;
|
||||
boolean showFiles = false;
|
||||
boolean verbose = false;
|
||||
boolean argTypes = false;
|
||||
String title = null;
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
@ -115,6 +116,8 @@ public class RunExamples {
|
||||
outFile = new File(args[++i]);
|
||||
else if (arg.equals("-title") && (i + 1) < args.length)
|
||||
title = args[++i];
|
||||
else if (arg.equals("-argtypes"))
|
||||
argTypes = true;
|
||||
else if (arg.startsWith("-")) {
|
||||
error("unknown option: " + arg);
|
||||
return false;
|
||||
@ -127,6 +130,11 @@ public class RunExamples {
|
||||
}
|
||||
}
|
||||
|
||||
// special mode to show message keys and the types of the args that
|
||||
// are used.
|
||||
if (argTypes)
|
||||
Example.Compiler.factory = new ArgTypeCompilerFactory();
|
||||
|
||||
if (selectedKeys.size() > 0) {
|
||||
Set<Example> examples = getExamples(examplesDir);
|
||||
nextKey:
|
||||
@ -138,7 +146,7 @@ public class RunExamples {
|
||||
error("Key " + k + ": no examples found");
|
||||
}
|
||||
} else {
|
||||
if (selectedExamples.size() == 0)
|
||||
if (selectedExamples.isEmpty())
|
||||
selectedExamples = getExamples(examplesDir);
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +63,6 @@ compiler.misc.fatal.err.cant.locate.meth # Resolve, from Lower
|
||||
compiler.misc.fatal.err.cant.close.loader # JavacProcessingEnvironment
|
||||
compiler.misc.file.does.not.contain.package
|
||||
compiler.misc.illegal.start.of.class.file
|
||||
compiler.misc.inferred.do.not.conform.to.params # UNUSED (hard to see if very complex inference scenario might require this though, so leaving it in, as per JLS3)
|
||||
compiler.misc.kindname.annotation
|
||||
compiler.misc.kindname.enum
|
||||
compiler.misc.kindname.package
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.misc.inaccessible.varargs.type
|
||||
// key: compiler.err.cant.apply.symbol.1
|
||||
|
||||
import p1.B;
|
||||
|
||||
class InaccessibleVarargsType {
|
||||
{ new B().foo(new B(), new B()); }
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
class A {
|
||||
A() { }
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
public class B extends A {
|
||||
public B() {}
|
||||
public void foo(A... args) { }
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,27 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6911256 6964740 6965277
|
||||
* @author Maurizio Cimadamore
|
||||
* @summary Resource of an intersection type crashes Flow
|
||||
* @compile TwrIntersection.java
|
||||
*/
|
||||
// key: compiler.err.name.clash.same.erasure.no.hide
|
||||
|
||||
interface MyCloseable extends AutoCloseable {
|
||||
void close() throws java.io.IOException;
|
||||
}
|
||||
|
||||
class ResourceTypeVar {
|
||||
|
||||
public void test() {
|
||||
try(getX()) {
|
||||
//do something
|
||||
} catch (java.io.IOException e) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", e);
|
||||
}
|
||||
public class NameClashSameErasureNoHide<X> {
|
||||
static class A {
|
||||
static void m(NameClashSameErasureNoHide<String> l) {}
|
||||
}
|
||||
|
||||
<X extends Number & MyCloseable> X getX() { return null; }
|
||||
static class B extends A {
|
||||
static void m(NameClashSameErasureNoHide<Integer> l) {}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,10 +25,10 @@
|
||||
|
||||
public class NameClashSameErasureNoOverride<X> {
|
||||
static class A {
|
||||
static void m(NameClashSameErasureNoOverride<String> l) {}
|
||||
void m(NameClashSameErasureNoOverride<String> l) {}
|
||||
}
|
||||
|
||||
static class B extends A {
|
||||
static void m(NameClashSameErasureNoOverride<Integer> l) {}
|
||||
void m(NameClashSameErasureNoOverride<Integer> l) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,23 +21,19 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6911256 6964740 6965277
|
||||
* @author Maurizio Cimadamore
|
||||
* @summary Verify that method type-inference works as expected in TWR context
|
||||
* @compile TwrInference.java
|
||||
*/
|
||||
// key: compiler.err.name.clash.same.erasure.no.override.1
|
||||
|
||||
class TwrInference {
|
||||
public class NameClashSameErasureNoOverride1 {
|
||||
|
||||
public void test() {
|
||||
try(getX()) {
|
||||
//do something
|
||||
} catch (Exception e) { // Not reachable
|
||||
throw new AssertionError("Shouldn't reach here", e);
|
||||
}
|
||||
interface I<X> {
|
||||
void m(X l);
|
||||
}
|
||||
|
||||
<X> X getX() { return null; }
|
||||
class A {
|
||||
void m(Object l) {}
|
||||
}
|
||||
|
||||
class B extends A implements I<Integer> {
|
||||
public void m(Integer l) {}
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,2 @@
|
||||
T5009937.java:16:21: compiler.err.name.clash.same.erasure.no.override: m(T5009937<java.lang.Integer>), T5009937.B, m(T5009937<java.lang.String>), T5009937.A
|
||||
T5009937.java:16:21: compiler.err.name.clash.same.erasure.no.hide: m(T5009937<java.lang.Integer>), T5009937.B, m(T5009937<java.lang.String>), T5009937.A
|
||||
1 error
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6182950b.java:15:16: compiler.err.name.clash.same.erasure.no.override: m(java.util.List<java.lang.Integer>), T6182950b.B, m(java.util.List<java.lang.String>), T6182950b.A
|
||||
T6182950b.java:15:16: compiler.err.name.clash.same.erasure.no.override: m(java.util.List<java.lang.Integer>), T6182950b.B, m(java.util.List<java.lang.String>), T6182950b.A, m(java.util.List<java.lang.Integer>), T6182950b.B
|
||||
1 error
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6476118a.java:14:20: compiler.err.name.clash.same.erasure.no.override: compareTo(T), java.lang.Comparable, compareTo(java.lang.Object), T6476118a.A
|
||||
T6476118a.java:14:20: compiler.err.name.clash.same.erasure.no.override.1: compareTo(T6476118a.B), T6476118a.B, compareTo(java.lang.Object), T6476118a.A, compareTo(T), java.lang.Comparable
|
||||
1 error
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6476118b.java:12:20: compiler.err.name.clash.same.erasure.no.override: compareTo(T), java.lang.Comparable, compareTo(java.lang.Object), T6476118b
|
||||
T6476118b.java:12:20: compiler.err.name.clash.same.erasure.no.override.1: compareTo(T6476118b.B), T6476118b.B, compareTo(java.lang.Object), T6476118b, compareTo(T), java.lang.Comparable
|
||||
1 error
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* @compile/fail/ref=T6476118c.out -XDrawDiagnostics T6476118c.java
|
||||
*/
|
||||
|
||||
class T6476118b {
|
||||
class T6476118c {
|
||||
static class A<T> {
|
||||
public void foo(T t) { }
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
T6476118c.java:18:21: compiler.err.name.clash.same.erasure.no.override: foo(java.lang.Object), T6476118b.C, foo(T), T6476118b.A
|
||||
T6476118c.java:19:21: compiler.err.name.clash.same.erasure.no.override: foo(java.lang.Number), T6476118b.C, foo(T), T6476118b.B
|
||||
T6476118c.java:18:21: compiler.err.name.clash.same.erasure.no.override: foo(java.lang.Object), T6476118c.C, foo(T), T6476118c.A, foo(java.lang.Object), T6476118c.C
|
||||
T6476118c.java:19:21: compiler.err.name.clash.same.erasure.no.override: foo(java.lang.Number), T6476118c.C, foo(T), T6476118c.B, foo(java.lang.Number), T6476118c.C
|
||||
2 errors
|
||||
|
||||
16
langtools/test/tools/javac/generics/6910550/T6910550a.java
Normal file
16
langtools/test/tools/javac/generics/6910550/T6910550a.java
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6910550
|
||||
*
|
||||
* @summary javac 1.5.0_17 fails with incorrect error message
|
||||
* @compile/fail/ref=T6910550a.out -XDrawDiagnostics T6910550a.java
|
||||
*
|
||||
*/
|
||||
import java.util.*;
|
||||
|
||||
class T6910550a {
|
||||
void m(List<String> ls) {}
|
||||
void m(List<Integer> li) {}
|
||||
|
||||
{ m(Arrays.asList(12)); }
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
T6910550a.java:13:10: compiler.err.name.clash.same.erasure: m(java.util.List<java.lang.Integer>), m(java.util.List<java.lang.String>)
|
||||
1 error
|
||||
16
langtools/test/tools/javac/generics/6910550/T6910550b.java
Normal file
16
langtools/test/tools/javac/generics/6910550/T6910550b.java
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 6910550
|
||||
*
|
||||
* @summary javac 1.5.0_17 fails with incorrect error message
|
||||
* @compile/fail/ref=T6910550b.out -XDrawDiagnostics T6910550b.java
|
||||
*
|
||||
*/
|
||||
|
||||
class T6910550b<X, Y, Z> {
|
||||
void m(X x) {}
|
||||
void m(Y y) {}
|
||||
void m(Z y) {}
|
||||
|
||||
{ m(null); }
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
T6910550b.java:12:10: compiler.err.name.clash.same.erasure: m(Y), m(X)
|
||||
T6910550b.java:13:10: compiler.err.name.clash.same.erasure: m(Z), m(X)
|
||||
2 errors
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user