Merge
This commit is contained in:
commit
cdc3810c17
@ -37,6 +37,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -51,6 +52,7 @@ import com.sun.source.util.TaskEvent;
|
|||||||
import com.sun.source.util.TaskListener;
|
import com.sun.source.util.TaskListener;
|
||||||
import com.sun.tools.javac.util.ClientCodeException;
|
import com.sun.tools.javac.util.ClientCodeException;
|
||||||
import com.sun.tools.javac.util.Context;
|
import com.sun.tools.javac.util.Context;
|
||||||
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@ -146,7 +148,7 @@ public class ClientCodeWrapper {
|
|||||||
return fo;
|
return fo;
|
||||||
}
|
}
|
||||||
|
|
||||||
<T> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
|
<T /*super JavaFileOject*/> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
|
||||||
if (isTrusted(dl))
|
if (isTrusted(dl))
|
||||||
return dl;
|
return dl;
|
||||||
return new WrappedDiagnosticListener<T>(dl);
|
return new WrappedDiagnosticListener<T>(dl);
|
||||||
@ -158,6 +160,16 @@ public class ClientCodeWrapper {
|
|||||||
return new WrappedTaskListener(tl);
|
return new WrappedTaskListener(tl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> Diagnostic<T> unwrap(final Diagnostic<T> diagnostic) {
|
||||||
|
if (diagnostic instanceof JCDiagnostic) {
|
||||||
|
JCDiagnostic d = (JCDiagnostic) diagnostic;
|
||||||
|
return (Diagnostic<T>) new DiagnosticSourceUnwrapper(d);
|
||||||
|
} else {
|
||||||
|
return diagnostic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isTrusted(Object o) {
|
protected boolean isTrusted(Object o) {
|
||||||
Class<?> c = o.getClass();
|
Class<?> c = o.getClass();
|
||||||
Boolean trusted = trustedClasses.get(c);
|
Boolean trusted = trustedClasses.get(c);
|
||||||
@ -534,7 +546,7 @@ public class ClientCodeWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class WrappedDiagnosticListener<T> implements DiagnosticListener<T> {
|
protected class WrappedDiagnosticListener<T /*super JavaFileObject*/> implements DiagnosticListener<T> {
|
||||||
protected DiagnosticListener<T> clientDiagnosticListener;
|
protected DiagnosticListener<T> clientDiagnosticListener;
|
||||||
WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
|
WrappedDiagnosticListener(DiagnosticListener<T> clientDiagnosticListener) {
|
||||||
clientDiagnosticListener.getClass(); // null check
|
clientDiagnosticListener.getClass(); // null check
|
||||||
@ -544,7 +556,7 @@ public class ClientCodeWrapper {
|
|||||||
@Override
|
@Override
|
||||||
public void report(Diagnostic<? extends T> diagnostic) {
|
public void report(Diagnostic<? extends T> diagnostic) {
|
||||||
try {
|
try {
|
||||||
clientDiagnosticListener.report(diagnostic);
|
clientDiagnosticListener.report(unwrap(diagnostic));
|
||||||
} catch (ClientCodeException e) {
|
} catch (ClientCodeException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
@ -555,6 +567,54 @@ public class ClientCodeWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DiagnosticSourceUnwrapper implements Diagnostic<JavaFileObject> {
|
||||||
|
public final JCDiagnostic d;
|
||||||
|
|
||||||
|
DiagnosticSourceUnwrapper(JCDiagnostic d) {
|
||||||
|
this.d = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Diagnostic.Kind getKind() {
|
||||||
|
return d.getKind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JavaFileObject getSource() {
|
||||||
|
return unwrap(d.getSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPosition() {
|
||||||
|
return d.getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getStartPosition() {
|
||||||
|
return d.getStartPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getEndPosition() {
|
||||||
|
return d.getEndPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLineNumber() {
|
||||||
|
return d.getLineNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getColumnNumber() {
|
||||||
|
return d.getColumnNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return d.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage(Locale locale) {
|
||||||
|
return d.getMessage(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return d.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class WrappedTaskListener implements TaskListener {
|
protected class WrappedTaskListener implements TaskListener {
|
||||||
protected TaskListener clientTaskListener;
|
protected TaskListener clientTaskListener;
|
||||||
WrappedTaskListener(TaskListener clientTaskListener) {
|
WrappedTaskListener(TaskListener clientTaskListener) {
|
||||||
|
@ -269,10 +269,12 @@ public class Types {
|
|||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="isConvertible">
|
// <editor-fold defaultstate="collapsed" desc="isConvertible">
|
||||||
/**
|
/**
|
||||||
* Is t a subtype of or convertiable via boxing/unboxing
|
* Is t a subtype of or convertible via boxing/unboxing
|
||||||
* convertions to s?
|
* conversion to s?
|
||||||
*/
|
*/
|
||||||
public boolean isConvertible(Type t, Type s, Warner warn) {
|
public boolean isConvertible(Type t, Type s, Warner warn) {
|
||||||
|
if (t.tag == ERROR)
|
||||||
|
return true;
|
||||||
boolean tPrimitive = t.isPrimitive();
|
boolean tPrimitive = t.isPrimitive();
|
||||||
boolean sPrimitive = s.isPrimitive();
|
boolean sPrimitive = s.isPrimitive();
|
||||||
if (tPrimitive == sPrimitive) {
|
if (tPrimitive == sPrimitive) {
|
||||||
@ -2117,6 +2119,8 @@ public class Types {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<TypeSymbol> seenTypes = List.nil();
|
||||||
|
|
||||||
/** members closure visitor methods **/
|
/** members closure visitor methods **/
|
||||||
|
|
||||||
public CompoundScope visitType(Type t, Boolean skipInterface) {
|
public CompoundScope visitType(Type t, Boolean skipInterface) {
|
||||||
@ -2125,21 +2129,33 @@ public class Types {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundScope visitClassType(ClassType t, Boolean skipInterface) {
|
public CompoundScope visitClassType(ClassType t, Boolean skipInterface) {
|
||||||
ClassSymbol csym = (ClassSymbol)t.tsym;
|
if (seenTypes.contains(t.tsym)) {
|
||||||
Entry e = _map.get(csym);
|
//this is possible when an interface is implemented in multiple
|
||||||
if (e == null || !e.matches(skipInterface)) {
|
//superclasses, or when a classs hierarchy is circular - in such
|
||||||
CompoundScope membersClosure = new CompoundScope(csym);
|
//cases we don't need to recurse (empty scope is returned)
|
||||||
if (!skipInterface) {
|
return new CompoundScope(t.tsym);
|
||||||
for (Type i : interfaces(t)) {
|
}
|
||||||
membersClosure.addSubScope(visit(i, skipInterface));
|
try {
|
||||||
}
|
seenTypes = seenTypes.prepend(t.tsym);
|
||||||
}
|
ClassSymbol csym = (ClassSymbol)t.tsym;
|
||||||
membersClosure.addSubScope(visit(supertype(t), skipInterface));
|
Entry e = _map.get(csym);
|
||||||
membersClosure.addSubScope(csym.members());
|
if (e == null || !e.matches(skipInterface)) {
|
||||||
e = new Entry(skipInterface, membersClosure);
|
CompoundScope membersClosure = new CompoundScope(csym);
|
||||||
_map.put(csym, e);
|
if (!skipInterface) {
|
||||||
|
for (Type i : interfaces(t)) {
|
||||||
|
membersClosure.addSubScope(visit(i, skipInterface));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
membersClosure.addSubScope(visit(supertype(t), skipInterface));
|
||||||
|
membersClosure.addSubScope(csym.members());
|
||||||
|
e = new Entry(skipInterface, membersClosure);
|
||||||
|
_map.put(csym, e);
|
||||||
|
}
|
||||||
|
return e.compoundScope;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
seenTypes = seenTypes.tail;
|
||||||
}
|
}
|
||||||
return e.compoundScope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -594,7 +594,15 @@ public class Attr extends JCTree.Visitor {
|
|||||||
lintEnv = lintEnv.next;
|
lintEnv = lintEnv.next;
|
||||||
|
|
||||||
// Having found the enclosing lint value, we can initialize the lint value for this class
|
// 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());
|
// ... but ...
|
||||||
|
// There's a problem with evaluating annotations in the right order, such that
|
||||||
|
// env.info.enclVar.attributes_field might not yet have been evaluated, and so might be
|
||||||
|
// null. In that case, calling augment will throw an NPE. To avoid this, for now we
|
||||||
|
// revert to the jdk 6 behavior and ignore the (unevaluated) attributes.
|
||||||
|
if (env.info.enclVar.attributes_field == null)
|
||||||
|
env.info.lint = lintEnv.info.lint;
|
||||||
|
else
|
||||||
|
env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags());
|
||||||
|
|
||||||
Lint prevLint = chk.setLint(env.info.lint);
|
Lint prevLint = chk.setLint(env.info.lint);
|
||||||
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -98,6 +98,7 @@ class RegularFileObject extends BaseFileObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream openOutputStream() throws IOException {
|
public OutputStream openOutputStream() throws IOException {
|
||||||
|
fileManager.flushCache(this);
|
||||||
ensureParentDirectoriesExist();
|
ensureParentDirectoriesExist();
|
||||||
return new FileOutputStream(file);
|
return new FileOutputStream(file);
|
||||||
}
|
}
|
||||||
@ -128,6 +129,7 @@ class RegularFileObject extends BaseFileObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Writer openWriter() throws IOException {
|
public Writer openWriter() throws IOException {
|
||||||
|
fileManager.flushCache(this);
|
||||||
ensureParentDirectoriesExist();
|
ensureParentDirectoriesExist();
|
||||||
return new OutputStreamWriter(new FileOutputStream(file), fileManager.getEncodingName());
|
return new OutputStreamWriter(new FileOutputStream(file), fileManager.getEncodingName());
|
||||||
}
|
}
|
||||||
|
@ -1689,6 +1689,8 @@ public class Gen extends JCTree.Visitor {
|
|||||||
// outer instance of a super(...) call appears as first parameter).
|
// outer instance of a super(...) call appears as first parameter).
|
||||||
genArgs(tree.args,
|
genArgs(tree.args,
|
||||||
TreeInfo.symbol(tree.meth).externalType(types).getParameterTypes());
|
TreeInfo.symbol(tree.meth).externalType(types).getParameterTypes());
|
||||||
|
code.statBegin(tree.pos);
|
||||||
|
code.markStatBegin();
|
||||||
result = m.invoke();
|
result = m.invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +205,7 @@ abstract class PathFileObject implements JavaFileObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OutputStream openOutputStream() throws IOException {
|
public OutputStream openOutputStream() throws IOException {
|
||||||
|
fileManager.flushCache(this);
|
||||||
ensureParentDirectoriesExist();
|
ensureParentDirectoriesExist();
|
||||||
return Files.newOutputStream(path);
|
return Files.newOutputStream(path);
|
||||||
}
|
}
|
||||||
@ -241,6 +242,7 @@ abstract class PathFileObject implements JavaFileObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Writer openWriter() throws IOException {
|
public Writer openWriter() throws IOException {
|
||||||
|
fileManager.flushCache(this);
|
||||||
ensureParentDirectoriesExist();
|
ensureParentDirectoriesExist();
|
||||||
return new OutputStreamWriter(Files.newOutputStream(path), fileManager.getEncodingName());
|
return new OutputStreamWriter(Files.newOutputStream(path), fileManager.getEncodingName());
|
||||||
}
|
}
|
||||||
|
@ -27,15 +27,15 @@ package com.sun.tools.javac.parser;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import com.sun.tools.javac.tree.*;
|
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
|
import com.sun.tools.javac.tree.*;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.*;
|
||||||
import com.sun.tools.javac.util.*;
|
import com.sun.tools.javac.util.*;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
|
||||||
|
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
|
|
||||||
import static com.sun.tools.javac.util.ListBuffer.lb;
|
import static com.sun.tools.javac.util.ListBuffer.lb;
|
||||||
|
|
||||||
import com.sun.tools.javac.tree.JCTree.*;
|
|
||||||
|
|
||||||
import static com.sun.tools.javac.parser.Token.*;
|
import static com.sun.tools.javac.parser.Token.*;
|
||||||
|
|
||||||
/** The parser maps a token sequence into an abstract syntax
|
/** The parser maps a token sequence into an abstract syntax
|
||||||
@ -254,26 +254,44 @@ public class JavacParser implements Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JCErroneous syntaxError(int pos, String key, Token... args) {
|
private JCErroneous syntaxError(int pos, String key, Token... args) {
|
||||||
return syntaxError(pos, null, key, args);
|
return syntaxError(pos, List.<JCTree>nil(), key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
|
private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
|
||||||
setErrorEndPos(pos);
|
setErrorEndPos(pos);
|
||||||
reportSyntaxError(pos, key, (Object[])args);
|
JCErroneous err = F.at(pos).Erroneous(errs);
|
||||||
return toP(F.at(pos).Erroneous(errs));
|
reportSyntaxError(err, key, (Object[])args);
|
||||||
|
if (errs != null) {
|
||||||
|
JCTree last = errs.last();
|
||||||
|
if (last != null)
|
||||||
|
storeEnd(last, pos);
|
||||||
|
}
|
||||||
|
return toP(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int errorPos = Position.NOPOS;
|
private int errorPos = Position.NOPOS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report a syntax error at given position using the given
|
* Report a syntax using the given the position parameter and arguments,
|
||||||
* argument unless one was already reported at the same position.
|
* unless one was already reported at the same position.
|
||||||
*/
|
*/
|
||||||
private void reportSyntaxError(int pos, String key, Object... args) {
|
private void reportSyntaxError(int pos, String key, Object... args) {
|
||||||
|
JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos);
|
||||||
|
reportSyntaxError(diag, key, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report a syntax error using the given DiagnosticPosition object and
|
||||||
|
* arguments, unless one was already reported at the same position.
|
||||||
|
*/
|
||||||
|
private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
|
||||||
|
int pos = diagPos.getPreferredPosition();
|
||||||
if (pos > S.errPos() || pos == Position.NOPOS) {
|
if (pos > S.errPos() || pos == Position.NOPOS) {
|
||||||
if (S.token() == EOF)
|
if (S.token() == EOF) {
|
||||||
error(pos, "premature.eof");
|
error(diagPos, "premature.eof");
|
||||||
else
|
} else {
|
||||||
error(pos, key, args);
|
error(diagPos, key, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
S.errPos(pos);
|
S.errPos(pos);
|
||||||
if (S.pos() == errorPos)
|
if (S.pos() == errorPos)
|
||||||
@ -311,7 +329,7 @@ public class JavacParser implements Parser {
|
|||||||
/** Report an illegal start of expression/type error at given position.
|
/** Report an illegal start of expression/type error at given position.
|
||||||
*/
|
*/
|
||||||
JCExpression illegal(int pos) {
|
JCExpression illegal(int pos) {
|
||||||
setErrorEndPos(S.pos());
|
setErrorEndPos(pos);
|
||||||
if ((mode & EXPR) != 0)
|
if ((mode & EXPR) != 0)
|
||||||
return syntaxError(pos, "illegal.start.of.expr");
|
return syntaxError(pos, "illegal.start.of.expr");
|
||||||
else
|
else
|
||||||
@ -340,7 +358,7 @@ public class JavacParser implements Parser {
|
|||||||
* indexed by the tree nodes they refer to.
|
* indexed by the tree nodes they refer to.
|
||||||
* defined only if option flag keepDocComment is set.
|
* defined only if option flag keepDocComment is set.
|
||||||
*/
|
*/
|
||||||
Map<JCTree, String> docComments;
|
private final Map<JCTree, String> docComments;
|
||||||
|
|
||||||
/** Make an entry into docComments hashtable,
|
/** Make an entry into docComments hashtable,
|
||||||
* provided flag keepDocComments is set and given doc comment is non-null.
|
* provided flag keepDocComments is set and given doc comment is non-null.
|
||||||
@ -462,6 +480,10 @@ public class JavacParser implements Parser {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JCExpression literal(Name prefix) {
|
||||||
|
return literal(prefix, S.pos());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Literal =
|
* Literal =
|
||||||
* INTLITERAL
|
* INTLITERAL
|
||||||
@ -474,8 +496,7 @@ public class JavacParser implements Parser {
|
|||||||
* | FALSE
|
* | FALSE
|
||||||
* | NULL
|
* | NULL
|
||||||
*/
|
*/
|
||||||
JCExpression literal(Name prefix) {
|
JCExpression literal(Name prefix, int pos) {
|
||||||
int pos = S.pos();
|
|
||||||
JCExpression t = errorTree;
|
JCExpression t = errorTree;
|
||||||
switch (S.token()) {
|
switch (S.token()) {
|
||||||
case INTLITERAL:
|
case INTLITERAL:
|
||||||
@ -869,7 +890,7 @@ public class JavacParser implements Parser {
|
|||||||
(S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
|
(S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
|
||||||
S.radix() == 10) {
|
S.radix() == 10) {
|
||||||
mode = EXPR;
|
mode = EXPR;
|
||||||
t = literal(names.hyphen);
|
t = literal(names.hyphen, pos);
|
||||||
} else {
|
} else {
|
||||||
t = term3();
|
t = term3();
|
||||||
return F.at(pos).Unary(unoptag(token), t);
|
return F.at(pos).Unary(unoptag(token), t);
|
||||||
@ -1267,15 +1288,17 @@ public class JavacParser implements Parser {
|
|||||||
case GTGT:
|
case GTGT:
|
||||||
S.token(GT);
|
S.token(GT);
|
||||||
break;
|
break;
|
||||||
|
case GT:
|
||||||
|
S.nextToken();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
accept(GT);
|
args.append(syntaxError(S.pos(), "expected", GT));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return args.toList();
|
return args.toList();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
syntaxError(S.pos(), "expected", LT);
|
return List.<JCExpression>of(syntaxError(S.pos(), "expected", LT));
|
||||||
return List.nil();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1300,12 +1323,12 @@ public class JavacParser implements Parser {
|
|||||||
return F.at(pos).Wildcard(t, bound);
|
return F.at(pos).Wildcard(t, bound);
|
||||||
} else if (S.token() == IDENTIFIER) {
|
} else if (S.token() == IDENTIFIER) {
|
||||||
//error recovery
|
//error recovery
|
||||||
reportSyntaxError(S.prevEndPos(), "expected3",
|
|
||||||
GT, EXTENDS, SUPER);
|
|
||||||
TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
|
TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
|
||||||
JCExpression wc = toP(F.at(pos).Wildcard(t, null));
|
JCExpression wc = toP(F.at(pos).Wildcard(t, null));
|
||||||
JCIdent id = toP(F.at(S.pos()).Ident(ident()));
|
JCIdent id = toP(F.at(S.pos()).Ident(ident()));
|
||||||
return F.at(pos).Erroneous(List.<JCTree>of(wc, id));
|
JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
|
||||||
|
reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER);
|
||||||
|
return err;
|
||||||
} else {
|
} else {
|
||||||
TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
|
TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
|
||||||
return toP(F.at(pos).Wildcard(t, null));
|
return toP(F.at(pos).Wildcard(t, null));
|
||||||
@ -1391,7 +1414,7 @@ public class JavacParser implements Parser {
|
|||||||
while (S.token() == DOT) {
|
while (S.token() == DOT) {
|
||||||
if (diamondFound) {
|
if (diamondFound) {
|
||||||
//cannot select after a diamond
|
//cannot select after a diamond
|
||||||
illegal(S.pos());
|
illegal();
|
||||||
}
|
}
|
||||||
int pos = S.pos();
|
int pos = S.pos();
|
||||||
S.nextToken();
|
S.nextToken();
|
||||||
@ -1419,15 +1442,16 @@ public class JavacParser implements Parser {
|
|||||||
pos = typeArgs.head.pos;
|
pos = typeArgs.head.pos;
|
||||||
}
|
}
|
||||||
setErrorEndPos(S.prevEndPos());
|
setErrorEndPos(S.prevEndPos());
|
||||||
reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
|
JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
|
||||||
return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
|
reportSyntaxError(err, "cannot.create.array.with.type.arguments");
|
||||||
|
return toP(err);
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
} else if (S.token() == LPAREN) {
|
} else if (S.token() == LPAREN) {
|
||||||
return classCreatorRest(newpos, null, typeArgs, t);
|
return classCreatorRest(newpos, null, typeArgs, t);
|
||||||
} else {
|
} else {
|
||||||
reportSyntaxError(S.pos(), "expected2",
|
setErrorEndPos(S.pos());
|
||||||
LPAREN, LBRACKET);
|
reportSyntaxError(S.pos(), "expected2", LPAREN, LBRACKET);
|
||||||
t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
|
t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
|
||||||
return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
|
return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
|
||||||
}
|
}
|
||||||
@ -1457,7 +1481,8 @@ public class JavacParser implements Parser {
|
|||||||
if (S.token() == LBRACE) {
|
if (S.token() == LBRACE) {
|
||||||
return arrayInitializer(newpos, elemtype);
|
return arrayInitializer(newpos, elemtype);
|
||||||
} else {
|
} else {
|
||||||
return syntaxError(S.pos(), "array.dimension.missing");
|
JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
|
||||||
|
return syntaxError(S.pos(), List.<JCTree>of(t), "array.dimension.missing");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
|
ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
|
||||||
@ -1843,7 +1868,7 @@ public class JavacParser implements Parser {
|
|||||||
|
|
||||||
/** CatchClause = CATCH "(" FormalParameter ")" Block
|
/** CatchClause = CATCH "(" FormalParameter ")" Block
|
||||||
*/
|
*/
|
||||||
JCCatch catchClause() {
|
protected JCCatch catchClause() {
|
||||||
int pos = S.pos();
|
int pos = S.pos();
|
||||||
accept(CATCH);
|
accept(CATCH);
|
||||||
accept(LPAREN);
|
accept(LPAREN);
|
||||||
@ -1973,7 +1998,7 @@ public class JavacParser implements Parser {
|
|||||||
JCModifiers modifiersOpt() {
|
JCModifiers modifiersOpt() {
|
||||||
return modifiersOpt(null);
|
return modifiersOpt(null);
|
||||||
}
|
}
|
||||||
JCModifiers modifiersOpt(JCModifiers partial) {
|
protected JCModifiers modifiersOpt(JCModifiers partial) {
|
||||||
long flags;
|
long flags;
|
||||||
ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
|
ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
|
||||||
int pos;
|
int pos;
|
||||||
@ -2006,6 +2031,7 @@ public class JavacParser implements Parser {
|
|||||||
case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
|
case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
|
||||||
case STRICTFP : flag = Flags.STRICTFP; break;
|
case STRICTFP : flag = Flags.STRICTFP; break;
|
||||||
case MONKEYS_AT : flag = Flags.ANNOTATION; break;
|
case MONKEYS_AT : flag = Flags.ANNOTATION; break;
|
||||||
|
case ERROR : flag = 0; S.nextToken(); break;
|
||||||
default: break loop;
|
default: break loop;
|
||||||
}
|
}
|
||||||
if ((flags & flag) != 0) error(S.pos(), "repeated.modifier");
|
if ((flags & flag) != 0) error(S.pos(), "repeated.modifier");
|
||||||
@ -2219,9 +2245,12 @@ public class JavacParser implements Parser {
|
|||||||
|
|
||||||
/** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
|
/** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
|
||||||
*/
|
*/
|
||||||
JCTree resource() {
|
protected JCTree resource() {
|
||||||
return variableDeclaratorRest(S.pos(), optFinal(Flags.FINAL),
|
JCModifiers optFinal = optFinal(Flags.FINAL);
|
||||||
parseType(), ident(), true, null);
|
JCExpression type = parseType();
|
||||||
|
int pos = S.pos();
|
||||||
|
Name ident = ident();
|
||||||
|
return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
|
/** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
|
||||||
@ -2568,7 +2597,7 @@ public class JavacParser implements Parser {
|
|||||||
* | ModifiersOpt Type Ident
|
* | ModifiersOpt Type Ident
|
||||||
* ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
|
* ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
|
||||||
*/
|
*/
|
||||||
List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
|
protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
|
||||||
if (S.token() == SEMI) {
|
if (S.token() == SEMI) {
|
||||||
S.nextToken();
|
S.nextToken();
|
||||||
return List.<JCTree>nil();
|
return List.<JCTree>nil();
|
||||||
@ -2770,7 +2799,7 @@ public class JavacParser implements Parser {
|
|||||||
/** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
|
/** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
|
||||||
* LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
|
* LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
|
||||||
*/
|
*/
|
||||||
JCVariableDecl formalParameter() {
|
protected JCVariableDecl formalParameter() {
|
||||||
JCModifiers mods = optFinal(Flags.PARAMETER);
|
JCModifiers mods = optFinal(Flags.PARAMETER);
|
||||||
JCExpression type = parseType();
|
JCExpression type = parseType();
|
||||||
if (S.token() == ELLIPSIS) {
|
if (S.token() == ELLIPSIS) {
|
||||||
@ -2788,6 +2817,10 @@ public class JavacParser implements Parser {
|
|||||||
log.error(DiagnosticFlag.SYNTAX, pos, key, args);
|
log.error(DiagnosticFlag.SYNTAX, pos, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void error(DiagnosticPosition pos, String key, Object ... args) {
|
||||||
|
log.error(DiagnosticFlag.SYNTAX, pos, key, args);
|
||||||
|
}
|
||||||
|
|
||||||
void warning(int pos, String key, Object ... args) {
|
void warning(int pos, String key, Object ... args) {
|
||||||
log.warning(pos, key, args);
|
log.warning(pos, key, args);
|
||||||
}
|
}
|
||||||
@ -2807,8 +2840,9 @@ public class JavacParser implements Parser {
|
|||||||
case JCTree.ERRONEOUS:
|
case JCTree.ERRONEOUS:
|
||||||
return t;
|
return t;
|
||||||
default:
|
default:
|
||||||
error(t.pos, "not.stmt");
|
JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
|
||||||
return F.at(t.pos).Erroneous(List.<JCTree>of(t));
|
error(ret, "not.stmt");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,8 +982,16 @@ public class Scanner implements Lexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the current token.
|
/** Sets the current token.
|
||||||
|
* This method is primarily used to update the token stream when the
|
||||||
|
* parser is handling the end of nested type arguments such as
|
||||||
|
* {@code List<List<String>>} and needs to disambiguate between
|
||||||
|
* repeated use of ">" and relation operators such as ">>" and ">>>". Noting
|
||||||
|
* that this does not handle arbitrary tokens containing Unicode escape
|
||||||
|
* sequences.
|
||||||
*/
|
*/
|
||||||
public void token(Token token) {
|
public void token(Token token) {
|
||||||
|
pos += this.token.name.length() - token.name.length();
|
||||||
|
prevEndPos = pos;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -94,6 +94,19 @@ public abstract class AbstractLog {
|
|||||||
report(diags.error(source, pos, key, args));
|
report(diags.error(source, pos, key, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Report an error, unless another error was already reported at same
|
||||||
|
* source position.
|
||||||
|
* @param flag A flag to set on the diagnostic
|
||||||
|
* @param pos The source position at which to report the error.
|
||||||
|
* @param key The key for the localized error message.
|
||||||
|
* @param args Fields of the error message.
|
||||||
|
*/
|
||||||
|
public void error(DiagnosticFlag flag, DiagnosticPosition pos, String key, Object ... args) {
|
||||||
|
JCDiagnostic d = diags.error(source, pos, key, args);
|
||||||
|
d.setFlag(flag);
|
||||||
|
report(d);
|
||||||
|
}
|
||||||
|
|
||||||
/** Report an error, unless another error was already reported at same
|
/** Report an error, unless another error was already reported at same
|
||||||
* source position.
|
* source position.
|
||||||
* @param pos The source position at which to report the error.
|
* @param pos The source position at which to report the error.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -322,16 +322,46 @@ public abstract class BaseFileManager {
|
|||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="Content cache">
|
// <editor-fold defaultstate="collapsed" desc="Content cache">
|
||||||
public CharBuffer getCachedContent(JavaFileObject file) {
|
public CharBuffer getCachedContent(JavaFileObject file) {
|
||||||
SoftReference<CharBuffer> r = contentCache.get(file);
|
ContentCacheEntry e = contentCache.get(file);
|
||||||
return (r == null ? null : r.get());
|
if (e == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!e.isValid(file)) {
|
||||||
|
contentCache.remove(file);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cache(JavaFileObject file, CharBuffer cb) {
|
public void cache(JavaFileObject file, CharBuffer cb) {
|
||||||
contentCache.put(file, new SoftReference<CharBuffer>(cb));
|
contentCache.put(file, new ContentCacheEntry(file, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final Map<JavaFileObject, SoftReference<CharBuffer>> contentCache
|
public void flushCache(JavaFileObject file) {
|
||||||
= new HashMap<JavaFileObject, SoftReference<CharBuffer>>();
|
contentCache.remove(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final Map<JavaFileObject, ContentCacheEntry> contentCache
|
||||||
|
= new HashMap<JavaFileObject, ContentCacheEntry>();
|
||||||
|
|
||||||
|
protected static class ContentCacheEntry {
|
||||||
|
final long timestamp;
|
||||||
|
final SoftReference<CharBuffer> ref;
|
||||||
|
|
||||||
|
ContentCacheEntry(JavaFileObject file, CharBuffer cb) {
|
||||||
|
this.timestamp = file.getLastModified();
|
||||||
|
this.ref = new SoftReference<CharBuffer>(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isValid(JavaFileObject file) {
|
||||||
|
return timestamp == file.getLastModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
CharBuffer getValue() {
|
||||||
|
return ref.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
|
|
||||||
public static Kind getKind(String name) {
|
public static Kind getKind(String name) {
|
||||||
|
@ -26,10 +26,8 @@
|
|||||||
package javax.tools;
|
package javax.tools;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import javax.annotation.processing.Processor;
|
import javax.annotation.processing.Processor;
|
||||||
|
168
langtools/test/tools/javac/7079713/TestCircularClassfile.java
Normal file
168
langtools/test/tools/javac/7079713/TestCircularClassfile.java
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* 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 7079713
|
||||||
|
* @summary javac hangs when compiling a class that references a cyclically inherited class
|
||||||
|
* @run main TestCircularClassfile
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
import javax.tools.StandardJavaFileManager;
|
||||||
|
import javax.tools.StandardLocation;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
|
||||||
|
public class TestCircularClassfile {
|
||||||
|
|
||||||
|
enum SourceKind {
|
||||||
|
A_EXTENDS_B("class B {} class A extends B { void m() {} }"),
|
||||||
|
B_EXTENDS_A("class A { void m() {} } class B extends A {}");
|
||||||
|
|
||||||
|
String sourceStr;
|
||||||
|
|
||||||
|
private SourceKind(String sourceStr) {
|
||||||
|
this.sourceStr = sourceStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleJavaFileObject getSource() {
|
||||||
|
return new SimpleJavaFileObject(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE) {
|
||||||
|
@Override
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||||
|
return sourceStr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TestKind {
|
||||||
|
REPLACE_A("A.class"),
|
||||||
|
REPLACE_B("B.class");
|
||||||
|
|
||||||
|
String targetClass;
|
||||||
|
|
||||||
|
private TestKind(String targetClass) {
|
||||||
|
this.targetClass = targetClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ClientKind {
|
||||||
|
METHOD_CALL1("A a = null; a.m();"),
|
||||||
|
METHOD_CALL2("B b = null; b.m();"),
|
||||||
|
CONSTR_CALL1("new A();"),
|
||||||
|
CONSTR_CALL2("new B();"),
|
||||||
|
ASSIGN1("A a = null; B b = a;"),
|
||||||
|
ASSIGN2("B b = null; A a = b;");
|
||||||
|
|
||||||
|
String mainMethod;
|
||||||
|
|
||||||
|
private ClientKind(String mainMethod) {
|
||||||
|
this.mainMethod = mainMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleJavaFileObject getSource() {
|
||||||
|
return new SimpleJavaFileObject(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE) {
|
||||||
|
@Override
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||||
|
return "class Test { public static void main(String[] args) { #M } }"
|
||||||
|
.replace("#M", mainMethod);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
|
||||||
|
StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
|
||||||
|
int count = 0;
|
||||||
|
for (SourceKind sk1 : SourceKind.values()) {
|
||||||
|
for (SourceKind sk2 : SourceKind.values()) {
|
||||||
|
for (TestKind tk : TestKind.values()) {
|
||||||
|
for (ClientKind ck : ClientKind.values()) {
|
||||||
|
new TestCircularClassfile("sub_"+count++, sk1, sk2, tk, ck).check(comp, fm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static String workDir = System.getProperty("user.dir");
|
||||||
|
|
||||||
|
String destPath;
|
||||||
|
SourceKind sk1;
|
||||||
|
SourceKind sk2;
|
||||||
|
TestKind tk;
|
||||||
|
ClientKind ck;
|
||||||
|
|
||||||
|
TestCircularClassfile(String destPath, SourceKind sk1, SourceKind sk2, TestKind tk, ClientKind ck) {
|
||||||
|
this.destPath = destPath;
|
||||||
|
this.sk1 = sk1;
|
||||||
|
this.sk2 = sk2;
|
||||||
|
this.tk = tk;
|
||||||
|
this.ck = ck;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check(JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
|
||||||
|
//step 1: compile first source code in the test subfolder
|
||||||
|
File destDir = new File(workDir, destPath); destDir.mkdir();
|
||||||
|
//output dir must be set explicitly as we are sharing the fm (see bug 7026941)
|
||||||
|
fm.setLocation(javax.tools.StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
|
||||||
|
JavacTask ct = (JavacTask)comp.getTask(null, fm, null,
|
||||||
|
null, null, Arrays.asList(sk1.getSource()));
|
||||||
|
ct.generate();
|
||||||
|
|
||||||
|
//step 2: compile second source code in a temp folder
|
||||||
|
File tmpDir = new File(destDir, "tmp"); tmpDir.mkdir();
|
||||||
|
//output dir must be set explicitly as we are sharing the fm (see bug 7026941)
|
||||||
|
fm.setLocation(javax.tools.StandardLocation.CLASS_OUTPUT, Arrays.asList(tmpDir));
|
||||||
|
ct = (JavacTask)comp.getTask(null, fm, null,
|
||||||
|
null, null, Arrays.asList(sk2.getSource()));
|
||||||
|
ct.generate();
|
||||||
|
|
||||||
|
//step 3: move a classfile from the temp folder to the test subfolder
|
||||||
|
File fileToMove = new File(tmpDir, tk.targetClass);
|
||||||
|
File target = new File(destDir, tk.targetClass);
|
||||||
|
target.delete();
|
||||||
|
boolean success = fileToMove.renameTo(target);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
throw new AssertionError("error when moving file " + tk.targetClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
//step 4: compile the client class against the classes in the test subfolder
|
||||||
|
//input/output dir must be set explicitly as we are sharing the fm (see bug 7026941)
|
||||||
|
fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
|
||||||
|
fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(destDir));
|
||||||
|
ct = (JavacTask)comp.getTask(null, fm, null,
|
||||||
|
null, null, Arrays.asList(ck.getSource()));
|
||||||
|
|
||||||
|
ct.generate();
|
||||||
|
}
|
||||||
|
}
|
12
langtools/test/tools/javac/7085024/T7085024.java
Normal file
12
langtools/test/tools/javac/7085024/T7085024.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* @test /nodynamiccopyright/
|
||||||
|
* @bug 7085024
|
||||||
|
* @summary internal error; cannot instantiate Foo
|
||||||
|
* @compile/fail/ref=T7085024.out -XDrawDiagnostics T7085024.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
class T7085024 {
|
||||||
|
T7085024 (boolean ret) { } //internal error goes away if constructor accepts a reference type
|
||||||
|
|
||||||
|
T7085024 f = new T7085024((NonExistentClass) null );
|
||||||
|
}
|
2
langtools/test/tools/javac/7085024/T7085024.out
Normal file
2
langtools/test/tools/javac/7085024/T7085024.out
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
T7085024.java:11:32: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, T7085024, null)
|
||||||
|
1 error
|
@ -1,5 +1,5 @@
|
|||||||
BadTwr.java:13:39: compiler.err.already.defined: r1, main(java.lang.String...)
|
BadTwr.java:13:46: compiler.err.already.defined: r1, main(java.lang.String...)
|
||||||
BadTwr.java:18:13: compiler.err.already.defined: args, main(java.lang.String...)
|
BadTwr.java:18:20: compiler.err.already.defined: args, main(java.lang.String...)
|
||||||
BadTwr.java:21:13: compiler.err.cant.assign.val.to.final.var: thatsIt
|
BadTwr.java:21:13: compiler.err.cant.assign.val.to.final.var: thatsIt
|
||||||
BadTwr.java:26:17: compiler.err.already.defined: name, main(java.lang.String...)
|
BadTwr.java:26:24: compiler.err.already.defined: name, main(java.lang.String...)
|
||||||
4 errors
|
4 errors
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
DuplicateResourceDecl.java:12:45: compiler.err.already.defined: c, main(java.lang.String[])
|
DuplicateResourceDecl.java:12:56: compiler.err.already.defined: c, main(java.lang.String[])
|
||||||
1 error
|
1 error
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
ResourceInterface.java:38:13: compiler.err.unreported.exception.implicit.close: ResourceInterface.E1, r2
|
ResourceInterface.java:38:23: compiler.err.unreported.exception.implicit.close: ResourceInterface.E1, r2
|
||||||
1 error
|
1 error
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TwrFlow.java:14:11: compiler.err.except.never.thrown.in.try: java.io.IOException
|
TwrFlow.java:14:11: compiler.err.except.never.thrown.in.try: java.io.IOException
|
||||||
TwrFlow.java:12:13: compiler.err.unreported.exception.implicit.close: CustomCloseException, twrFlow
|
TwrFlow.java:12:21: compiler.err.unreported.exception.implicit.close: CustomCloseException, twrFlow
|
||||||
2 errors
|
2 errors
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TwrLint.java:14:15: compiler.warn.try.explicit.close.call
|
TwrLint.java:14:15: compiler.warn.try.explicit.close.call
|
||||||
TwrLint.java:13:13: compiler.warn.try.resource.not.referenced: r3
|
TwrLint.java:13:21: compiler.warn.try.resource.not.referenced: r3
|
||||||
2 warnings
|
2 warnings
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
TwrOnNonResource.java:12:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
TwrOnNonResource.java:12:30: 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:15:30: 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:18:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
|
||||||
3 errors
|
3 errors
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
import com.sun.source.util.JavacTask;
|
||||||
|
import com.sun.tools.javac.api.ClientCodeWrapper;
|
||||||
import com.sun.tools.javac.api.JavacTool;
|
import com.sun.tools.javac.api.JavacTool;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic;
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -236,7 +237,7 @@ public class UnusedResourcesTest {
|
|||||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
if (diagnostic.getKind() == Diagnostic.Kind.WARNING &&
|
if (diagnostic.getKind() == Diagnostic.Kind.WARNING &&
|
||||||
diagnostic.getCode().contains("try.resource.not.referenced")) {
|
diagnostic.getCode().contains("try.resource.not.referenced")) {
|
||||||
String varName = ((JCDiagnostic)diagnostic).getArgs()[0].toString();
|
String varName = unwrap(diagnostic).getArgs()[0].toString();
|
||||||
if (varName.equals(TwrStmt.TWR1.resourceName)) {
|
if (varName.equals(TwrStmt.TWR1.resourceName)) {
|
||||||
unused_r1 = true;
|
unused_r1 = true;
|
||||||
} else if (varName.equals(TwrStmt.TWR2.resourceName)) {
|
} else if (varName.equals(TwrStmt.TWR2.resourceName)) {
|
||||||
@ -246,5 +247,13 @@ public class UnusedResourcesTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JCDiagnostic unwrap(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
if (diagnostic instanceof JCDiagnostic)
|
||||||
|
return (JCDiagnostic) diagnostic;
|
||||||
|
if (diagnostic instanceof ClientCodeWrapper.DiagnosticSourceUnwrapper)
|
||||||
|
return ((ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic).d;
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
langtools/test/tools/javac/annotations/T7043371.java
Normal file
43
langtools/test/tools/javac/annotations/T7043371.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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 7043371
|
||||||
|
* @summary javac7 fails with NPE during compilation
|
||||||
|
* @compile T7043371.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
@interface Anno {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
@Anno(value=A.a)
|
||||||
|
public static final int b = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
@Deprecated
|
||||||
|
public static final String a = "a";
|
||||||
|
}
|
39
langtools/test/tools/javac/annotations/T7073477.java
Normal file
39
langtools/test/tools/javac/annotations/T7073477.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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 7073477
|
||||||
|
* @summary NPE in com.sun.tools.javac.code.Symbol$VarSymbol.getConstValue
|
||||||
|
* @compile T7073477.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
@SuppressWarnings(T7073477A.S)
|
||||||
|
class T7073477 {
|
||||||
|
}
|
||||||
|
|
||||||
|
class T7073477A {
|
||||||
|
@SuppressWarnings("")
|
||||||
|
static final String S = "";
|
||||||
|
}
|
||||||
|
|
78
langtools/test/tools/javac/api/7086261/T7086261.java
Normal file
78
langtools/test/tools/javac/api/7086261/T7086261.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 20011, 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 7086261
|
||||||
|
* @summary javac doesn't report error as expected, it only reports ClientCodeWrapper$DiagnosticSourceUnwrapper
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.tools.*;
|
||||||
|
|
||||||
|
import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper;
|
||||||
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static javax.tools.StandardLocation.*;
|
||||||
|
import static javax.tools.JavaFileObject.Kind.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class T7086261 {
|
||||||
|
|
||||||
|
static class ErroneousSource extends SimpleJavaFileObject {
|
||||||
|
public ErroneousSource() {
|
||||||
|
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
||||||
|
}
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||||
|
return "class Test { NonexistentClass c = null; }";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DiagnosticChecker implements DiagnosticListener<javax.tools.JavaFileObject> {
|
||||||
|
public void report(Diagnostic message) {
|
||||||
|
if (!(message instanceof DiagnosticSourceUnwrapper)) {
|
||||||
|
throw new AssertionError("Wrapped diagnostic expected!");
|
||||||
|
}
|
||||||
|
String actual = message.toString();
|
||||||
|
JCDiagnostic jd = (JCDiagnostic)((DiagnosticSourceUnwrapper)message).d;
|
||||||
|
String expected = jd.toString();
|
||||||
|
if (!actual.equals(expected)) {
|
||||||
|
throw new AssertionError("expected = " + expected + "\nfound = " + actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void test() throws Throwable {
|
||||||
|
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||||
|
JavaFileManager jfm = javac.getStandardFileManager(null, null, null);
|
||||||
|
JavaCompiler.CompilationTask task =
|
||||||
|
javac.getTask(null, jfm, new DiagnosticChecker(), null, null, Arrays.asList(new ErroneousSource()));
|
||||||
|
task.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
new T7086261().test();
|
||||||
|
}
|
||||||
|
}
|
@ -21,10 +21,12 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.tools.javac.file.JavacFileManager;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.*;
|
import java.util.regex.*;
|
||||||
|
import javax.annotation.processing.Processor;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.DiagnosticCollector;
|
import javax.tools.DiagnosticCollector;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
@ -37,12 +39,11 @@ import javax.tools.ToolProvider;
|
|||||||
// import com.sun.tools.javac.Main
|
// import com.sun.tools.javac.Main
|
||||||
// import com.sun.tools.javac.main.Main
|
// import com.sun.tools.javac.main.Main
|
||||||
|
|
||||||
|
import com.sun.tools.javac.api.ClientCodeWrapper;
|
||||||
|
import com.sun.tools.javac.file.JavacFileManager;
|
||||||
import com.sun.tools.javac.util.Context;
|
import com.sun.tools.javac.util.Context;
|
||||||
import com.sun.tools.javac.util.JavacMessages;
|
import com.sun.tools.javac.util.JavacMessages;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic;
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import javax.annotation.processing.Processor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to handle example code designed to illustrate javac diagnostic messages.
|
* Class to handle example code designed to illustrate javac diagnostic messages.
|
||||||
@ -397,7 +398,7 @@ class Example implements Comparable<Example> {
|
|||||||
|
|
||||||
if (keys != null) {
|
if (keys != null) {
|
||||||
for (Diagnostic<? extends JavaFileObject> d: dc.getDiagnostics()) {
|
for (Diagnostic<? extends JavaFileObject> d: dc.getDiagnostics()) {
|
||||||
scanForKeys((JCDiagnostic) d, keys);
|
scanForKeys(unwrap(d), keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,6 +419,14 @@ class Example implements Comparable<Example> {
|
|||||||
for (JCDiagnostic sd: d.getSubdiagnostics())
|
for (JCDiagnostic sd: d.getSubdiagnostics())
|
||||||
scanForKeys(sd, keys);
|
scanForKeys(sd, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JCDiagnostic unwrap(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
if (diagnostic instanceof JCDiagnostic)
|
||||||
|
return (JCDiagnostic) diagnostic;
|
||||||
|
if (diagnostic instanceof ClientCodeWrapper.DiagnosticSourceUnwrapper)
|
||||||
|
return ((ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic).d;
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
// key: compiler.err.empty.char.lit
|
// key: compiler.err.empty.char.lit
|
||||||
// key: compiler.err.unclosed.char.lit
|
// key: compiler.err.unclosed.char.lit
|
||||||
// key: compiler.err.expected
|
|
||||||
// key: compiler.err.premature.eof
|
// key: compiler.err.premature.eof
|
||||||
|
|
||||||
class X {
|
class X {
|
||||||
|
168
langtools/test/tools/javac/file/T7068451.java
Normal file
168
langtools/test/tools/javac/file/T7068451.java
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* 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 7068451
|
||||||
|
* @summary Regression: javac compiles fixed sources against previous,
|
||||||
|
* not current, version of generated sources
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.annotation.processing.AbstractProcessor;
|
||||||
|
import javax.annotation.processing.Filer;
|
||||||
|
import javax.annotation.processing.Messager;
|
||||||
|
import javax.annotation.processing.RoundEnvironment;
|
||||||
|
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.JavaCompiler.CompilationTask;
|
||||||
|
import javax.tools.StandardLocation;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
public class T7068451 {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
new T7068451().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() throws Exception {
|
||||||
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
|
System.err.println("using " + compiler.getClass() + " from " + compiler.getClass().getProtectionDomain().getCodeSource());
|
||||||
|
|
||||||
|
File tmp = new File("tmp");
|
||||||
|
tmp.mkdir();
|
||||||
|
for (File f: tmp.listFiles())
|
||||||
|
f.delete();
|
||||||
|
|
||||||
|
File input = writeFile(tmp, "X.java", "package p; class X { { p.C.first(); } }");
|
||||||
|
|
||||||
|
List<String> opts = Arrays.asList(
|
||||||
|
"-s", tmp.getPath(),
|
||||||
|
"-d", tmp.getPath(),
|
||||||
|
"-XprintRounds");
|
||||||
|
|
||||||
|
System.err.println();
|
||||||
|
System.err.println("FIRST compilation");
|
||||||
|
System.err.println();
|
||||||
|
|
||||||
|
CompilationTask task = compiler.getTask(null, null, null, opts, null,
|
||||||
|
compiler.getStandardFileManager(null, null, null).getJavaFileObjects(input));
|
||||||
|
task.setProcessors(Collections.singleton(new Proc("first")));
|
||||||
|
check("compilation", task.call());
|
||||||
|
|
||||||
|
writeFile(tmp, "X.java", "package p; class X { { p.C.second(); } }");
|
||||||
|
|
||||||
|
//Thread.sleep(2000);
|
||||||
|
|
||||||
|
System.err.println();
|
||||||
|
System.err.println("SECOND compilation");
|
||||||
|
System.err.println();
|
||||||
|
|
||||||
|
task = compiler.getTask(null, null, null, opts, null,
|
||||||
|
compiler.getStandardFileManager(null, null, null).getJavaFileObjects(input));
|
||||||
|
task.setProcessors(Collections.singleton(new Proc("second")));
|
||||||
|
check("compilation", task.call());
|
||||||
|
|
||||||
|
//Thread.sleep(2000);
|
||||||
|
|
||||||
|
System.err.println();
|
||||||
|
System.err.println("SECOND compilation, REPEATED");
|
||||||
|
System.err.println();
|
||||||
|
|
||||||
|
task = compiler.getTask(null, null, null, opts, null,
|
||||||
|
compiler.getStandardFileManager(null, null, null).getJavaFileObjects(input));
|
||||||
|
task.setProcessors(Collections.singleton(new Proc("second")));
|
||||||
|
check("compilation", task.call());
|
||||||
|
}
|
||||||
|
|
||||||
|
void check(String msg, boolean ok) {
|
||||||
|
System.err.println(msg + ": " + (ok ? "ok" : "failed"));
|
||||||
|
if (!ok)
|
||||||
|
throw new AssertionError(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static File writeFile(File base, String path, String body) throws IOException {
|
||||||
|
File f = new File(base, path);
|
||||||
|
FileWriter out = new FileWriter(f);
|
||||||
|
out.write(body);
|
||||||
|
out.close();
|
||||||
|
System.err.println("wrote " + path + ": " + body);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SupportedAnnotationTypes("*")
|
||||||
|
private static class Proc extends AbstractProcessor {
|
||||||
|
final String m;
|
||||||
|
Proc(String m) {
|
||||||
|
this.m = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count;
|
||||||
|
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
|
if (roundEnv.processingOver() || count++ > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Filer filer = processingEnv.getFiler();
|
||||||
|
Messager messager = processingEnv.getMessager();
|
||||||
|
|
||||||
|
System.err.println("running Proc");
|
||||||
|
try {
|
||||||
|
int len = filer.getResource(StandardLocation.SOURCE_OUTPUT, "p", "C.java").getCharContent(false).length();
|
||||||
|
messager.printMessage(Kind.NOTE, "C.java: found previous content of length " + len);
|
||||||
|
} catch (FileNotFoundException x) {
|
||||||
|
messager.printMessage(Kind.NOTE, "C.java: not previously there");
|
||||||
|
} catch (IOException x) {
|
||||||
|
messager.printMessage(Kind.ERROR, "while reading: " + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String body = "package p; public class C { public static void " + m + "() {} }";
|
||||||
|
Writer w = filer.createSourceFile("p.C").openWriter();
|
||||||
|
w.write(body);
|
||||||
|
w.close();
|
||||||
|
messager.printMessage(Kind.NOTE, "C.java: wrote new content: " + body);
|
||||||
|
} catch (IOException x) {
|
||||||
|
messager.printMessage(Kind.ERROR, "while writing: " + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
31
langtools/test/tools/javac/jvm/T7024096.java
Normal file
31
langtools/test/tools/javac/jvm/T7024096.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* @test /nodynamiccopyright/
|
||||||
|
* @bug 7024096
|
||||||
|
* @summary Stack trace has invalid line numbers
|
||||||
|
* @author Bruce Chapman
|
||||||
|
* @compile T7024096.java
|
||||||
|
* @run main T7024096
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class T7024096 {
|
||||||
|
private static final int START = 14; // starting line number for the test
|
||||||
|
public static void main(String[] args) {
|
||||||
|
T7024096 m = new T7024096();
|
||||||
|
m.nest(START);
|
||||||
|
m.nest(START + 1, m.nest(START + 1), m.nest(START + 1),
|
||||||
|
m.nest(START + 2),
|
||||||
|
m.nest(START + 3, m.nest(START + 3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T7024096 nest(int expectedline, T7024096... args) {
|
||||||
|
Exception e = new Exception("expected line#: " + expectedline);
|
||||||
|
int myline = e.getStackTrace()[1].getLineNumber();
|
||||||
|
if( myline != expectedline) {
|
||||||
|
throw new RuntimeException("Incorrect line number " +
|
||||||
|
"expected: " + expectedline +
|
||||||
|
", got: " + myline, e);
|
||||||
|
}
|
||||||
|
System.out.format("Got expected line number %d correct %n", myline);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
716
langtools/test/tools/javac/parser/netbeans/JavacParserTest.java
Normal file
716
langtools/test/tools/javac/parser/netbeans/JavacParserTest.java
Normal file
@ -0,0 +1,716 @@
|
|||||||
|
/*
|
||||||
|
* 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 7073631
|
||||||
|
* @summary tests error and diagnostics positions
|
||||||
|
* @author jan.lahoda@oracle.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.source.tree.BinaryTree;
|
||||||
|
import com.sun.source.tree.BlockTree;
|
||||||
|
import com.sun.source.tree.ClassTree;
|
||||||
|
import com.sun.source.tree.CompilationUnitTree;
|
||||||
|
import com.sun.source.tree.ExpressionStatementTree;
|
||||||
|
import com.sun.source.tree.ExpressionTree;
|
||||||
|
import com.sun.source.tree.MethodInvocationTree;
|
||||||
|
import com.sun.source.tree.MethodTree;
|
||||||
|
import com.sun.source.tree.ModifiersTree;
|
||||||
|
import com.sun.source.tree.StatementTree;
|
||||||
|
import com.sun.source.tree.Tree;
|
||||||
|
import com.sun.source.tree.Tree.Kind;
|
||||||
|
import com.sun.source.tree.VariableTree;
|
||||||
|
import com.sun.source.tree.WhileLoopTree;
|
||||||
|
import com.sun.source.util.SourcePositions;
|
||||||
|
import com.sun.source.util.TreeScanner;
|
||||||
|
import com.sun.source.util.Trees;
|
||||||
|
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||||
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
import javax.tools.DiagnosticCollector;
|
||||||
|
import javax.tools.DiagnosticListener;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
public class JavacParserTest extends TestCase {
|
||||||
|
final JavaCompiler tool;
|
||||||
|
public JavacParserTest(String testName) {
|
||||||
|
tool = ToolProvider.getSystemJavaCompiler();
|
||||||
|
System.out.println("java.home=" + System.getProperty("java.home"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MyFileObject extends SimpleJavaFileObject {
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public MyFileObject(String text) {
|
||||||
|
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPositionForSuperConstructorCalls() throws IOException {
|
||||||
|
assert tool != null;
|
||||||
|
|
||||||
|
String code = "package test; public class Test {public Test() {super();}}";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
SourcePositions pos = Trees.instance(ct).getSourcePositions();
|
||||||
|
|
||||||
|
MethodTree method =
|
||||||
|
(MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0);
|
||||||
|
ExpressionStatementTree es =
|
||||||
|
(ExpressionStatementTree) method.getBody().getStatements().get(0);
|
||||||
|
|
||||||
|
assertEquals("testPositionForSuperConstructorCalls",
|
||||||
|
72 - 24, pos.getStartPosition(cut, es));
|
||||||
|
assertEquals("testPositionForSuperConstructorCalls",
|
||||||
|
80 - 24, pos.getEndPosition(cut, es));
|
||||||
|
|
||||||
|
MethodInvocationTree mit = (MethodInvocationTree) es.getExpression();
|
||||||
|
|
||||||
|
assertEquals("testPositionForSuperConstructorCalls",
|
||||||
|
72 - 24, pos.getStartPosition(cut, mit));
|
||||||
|
assertEquals("testPositionForSuperConstructorCalls",
|
||||||
|
79 - 24, pos.getEndPosition(cut, mit));
|
||||||
|
|
||||||
|
assertEquals("testPositionForSuperConstructorCalls",
|
||||||
|
72 - 24, pos.getStartPosition(cut, mit.getMethodSelect()));
|
||||||
|
assertEquals("testPositionForSuperConstructorCalls",
|
||||||
|
77 - 24, pos.getEndPosition(cut, mit.getMethodSelect()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPositionForEnumModifiers() throws IOException {
|
||||||
|
|
||||||
|
String code = "package test; public enum Test {A;}";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
SourcePositions pos = Trees.instance(ct).getSourcePositions();
|
||||||
|
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
ModifiersTree mt = clazz.getModifiers();
|
||||||
|
|
||||||
|
assertEquals("testPositionForEnumModifiers",
|
||||||
|
38 - 24, pos.getStartPosition(cut, mt));
|
||||||
|
assertEquals("testPositionForEnumModifiers",
|
||||||
|
44 - 24, pos.getEndPosition(cut, mt));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNewClassWithEnclosing() throws IOException {
|
||||||
|
|
||||||
|
|
||||||
|
String code = "package test; class Test { " +
|
||||||
|
"class d {} private void method() { " +
|
||||||
|
"Object o = Test.this.new d(); } }";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
SourcePositions pos = Trees.instance(ct).getSourcePositions();
|
||||||
|
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
ExpressionTree est =
|
||||||
|
((VariableTree) ((MethodTree) clazz.getMembers().get(1)).getBody().getStatements().get(0)).getInitializer();
|
||||||
|
|
||||||
|
assertEquals("testNewClassWithEnclosing",
|
||||||
|
97 - 24, pos.getStartPosition(cut, est));
|
||||||
|
assertEquals("testNewClassWithEnclosing",
|
||||||
|
114 - 24, pos.getEndPosition(cut, est));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPreferredPositionForBinaryOp() throws IOException {
|
||||||
|
|
||||||
|
String code = "package test; public class Test {" +
|
||||||
|
"private void test() {" +
|
||||||
|
"Object o = null; boolean b = o != null && o instanceof String;" +
|
||||||
|
"} private Test() {}}";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
MethodTree method = (MethodTree) clazz.getMembers().get(0);
|
||||||
|
VariableTree condSt = (VariableTree) method.getBody().getStatements().get(1);
|
||||||
|
BinaryTree cond = (BinaryTree) condSt.getInitializer();
|
||||||
|
|
||||||
|
JCTree condJC = (JCTree) cond;
|
||||||
|
|
||||||
|
assertEquals("testNewClassWithEnclosing",
|
||||||
|
117 - 24, condJC.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPositionBrokenSource126732a() throws IOException {
|
||||||
|
String[] commands = new String[]{
|
||||||
|
"return Runnable()",
|
||||||
|
"do { } while (true)",
|
||||||
|
"throw UnsupportedOperationException()",
|
||||||
|
"assert true",
|
||||||
|
"1 + 1",};
|
||||||
|
|
||||||
|
for (String command : commands) {
|
||||||
|
|
||||||
|
String code = "package test;\n"
|
||||||
|
+ "public class Test {\n"
|
||||||
|
+ " public static void test() {\n"
|
||||||
|
+ " " + command + " {\n"
|
||||||
|
+ " new Runnable() {\n"
|
||||||
|
+ " };\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ "}";
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null,
|
||||||
|
null, null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
MethodTree method = (MethodTree) clazz.getMembers().get(0);
|
||||||
|
List<? extends StatementTree> statements =
|
||||||
|
method.getBody().getStatements();
|
||||||
|
|
||||||
|
StatementTree ret = statements.get(0);
|
||||||
|
StatementTree block = statements.get(1);
|
||||||
|
|
||||||
|
Trees t = Trees.instance(ct);
|
||||||
|
int len = code.indexOf(command + " {") + (command + " ").length();
|
||||||
|
assertEquals(command, len,
|
||||||
|
t.getSourcePositions().getEndPosition(cut, ret));
|
||||||
|
assertEquals(command, len,
|
||||||
|
t.getSourcePositions().getStartPosition(cut, block));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPositionBrokenSource126732b() throws IOException {
|
||||||
|
String[] commands = new String[]{
|
||||||
|
"break",
|
||||||
|
"break A",
|
||||||
|
"continue ",
|
||||||
|
"continue A",};
|
||||||
|
|
||||||
|
for (String command : commands) {
|
||||||
|
|
||||||
|
String code = "package test;\n"
|
||||||
|
+ "public class Test {\n"
|
||||||
|
+ " public static void test() {\n"
|
||||||
|
+ " while (true) {\n"
|
||||||
|
+ " " + command + " {\n"
|
||||||
|
+ " new Runnable() {\n"
|
||||||
|
+ " };\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null,
|
||||||
|
null, null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
MethodTree method = (MethodTree) clazz.getMembers().get(0);
|
||||||
|
List<? extends StatementTree> statements =
|
||||||
|
((BlockTree) ((WhileLoopTree) method.getBody().getStatements().get(0)).getStatement()).getStatements();
|
||||||
|
|
||||||
|
StatementTree ret = statements.get(0);
|
||||||
|
StatementTree block = statements.get(1);
|
||||||
|
|
||||||
|
Trees t = Trees.instance(ct);
|
||||||
|
int len = code.indexOf(command + " {") + (command + " ").length();
|
||||||
|
assertEquals(command, len,
|
||||||
|
t.getSourcePositions().getEndPosition(cut, ret));
|
||||||
|
assertEquals(command, len,
|
||||||
|
t.getSourcePositions().getStartPosition(cut, block));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testErrorRecoveryForEnhancedForLoop142381() throws IOException {
|
||||||
|
|
||||||
|
String code = "package test; class Test { " +
|
||||||
|
"private void method() { " +
|
||||||
|
"java.util.Set<String> s = null; for (a : s) {} } }";
|
||||||
|
|
||||||
|
final List<Diagnostic<? extends JavaFileObject>> errors =
|
||||||
|
new LinkedList<Diagnostic<? extends JavaFileObject>>();
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null,
|
||||||
|
new DiagnosticListener<JavaFileObject>() {
|
||||||
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
errors.add(diagnostic);
|
||||||
|
}
|
||||||
|
}, null, null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
StatementTree forStatement =
|
||||||
|
((MethodTree) clazz.getMembers().get(0)).getBody().getStatements().get(1);
|
||||||
|
|
||||||
|
assertEquals("testErrorRecoveryForEnhancedForLoop142381",
|
||||||
|
Kind.ENHANCED_FOR_LOOP, forStatement.getKind());
|
||||||
|
assertFalse("testErrorRecoveryForEnhancedForLoop142381", errors.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPositionAnnotationNoPackage187551() throws IOException {
|
||||||
|
|
||||||
|
String code = "\n@interface Test {}";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
Trees t = Trees.instance(ct);
|
||||||
|
|
||||||
|
assertEquals("testPositionAnnotationNoPackage187551",
|
||||||
|
1, t.getSourcePositions().getStartPosition(cut, clazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPositionsSane() throws IOException {
|
||||||
|
performPositionsSanityTest("package test; class Test { " +
|
||||||
|
"private void method() { " +
|
||||||
|
"java.util.List<? extends java.util.List<? extends String>> l; " +
|
||||||
|
"} }");
|
||||||
|
performPositionsSanityTest("package test; class Test { " +
|
||||||
|
"private void method() { " +
|
||||||
|
"java.util.List<? super java.util.List<? super String>> l; " +
|
||||||
|
"} }");
|
||||||
|
performPositionsSanityTest("package test; class Test { " +
|
||||||
|
"private void method() { " +
|
||||||
|
"java.util.List<? super java.util.List<?>> l; } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performPositionsSanityTest(String code) throws IOException {
|
||||||
|
|
||||||
|
final List<Diagnostic<? extends JavaFileObject>> errors =
|
||||||
|
new LinkedList<Diagnostic<? extends JavaFileObject>>();
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null,
|
||||||
|
new DiagnosticListener<JavaFileObject>() {
|
||||||
|
|
||||||
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
errors.add(diagnostic);
|
||||||
|
}
|
||||||
|
}, null, null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
final CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
final Trees trees = Trees.instance(ct);
|
||||||
|
|
||||||
|
new TreeScanner<Void, Void>() {
|
||||||
|
|
||||||
|
private long parentStart = 0;
|
||||||
|
private long parentEnd = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void scan(Tree node, Void p) {
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
long start = trees.getSourcePositions().getStartPosition(cut, node);
|
||||||
|
|
||||||
|
if (start == (-1)) {
|
||||||
|
return null; //synthetic tree
|
||||||
|
}
|
||||||
|
assertTrue(node.toString() + ":" + start + "/" + parentStart,
|
||||||
|
parentStart <= start);
|
||||||
|
|
||||||
|
long prevParentStart = parentStart;
|
||||||
|
|
||||||
|
parentStart = start;
|
||||||
|
|
||||||
|
long end = trees.getSourcePositions().getEndPosition(cut, node);
|
||||||
|
|
||||||
|
assertTrue(node.toString() + ":" + end + "/" + parentEnd,
|
||||||
|
end <= parentEnd);
|
||||||
|
|
||||||
|
long prevParentEnd = parentEnd;
|
||||||
|
|
||||||
|
parentEnd = end;
|
||||||
|
|
||||||
|
super.scan(node, p);
|
||||||
|
|
||||||
|
parentStart = prevParentStart;
|
||||||
|
parentEnd = prevParentEnd;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertTrue(String message, boolean b) {
|
||||||
|
if (!b) fail(message);
|
||||||
|
}
|
||||||
|
}.scan(cut, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCorrectWilcardPositions() throws IOException {
|
||||||
|
performWildcardPositionsTest("package test; import java.util.List; " +
|
||||||
|
"class Test { private void method() { List<? extends List<? extends String>> l; } }",
|
||||||
|
|
||||||
|
Arrays.asList("List<? extends List<? extends String>> l;",
|
||||||
|
"List<? extends List<? extends String>>",
|
||||||
|
"List",
|
||||||
|
"? extends List<? extends String>",
|
||||||
|
"List<? extends String>",
|
||||||
|
"List",
|
||||||
|
"? extends String",
|
||||||
|
"String"));
|
||||||
|
performWildcardPositionsTest("package test; import java.util.List; " +
|
||||||
|
"class Test { private void method() { List<? super List<? super String>> l; } }",
|
||||||
|
|
||||||
|
Arrays.asList("List<? super List<? super String>> l;",
|
||||||
|
"List<? super List<? super String>>",
|
||||||
|
"List",
|
||||||
|
"? super List<? super String>",
|
||||||
|
"List<? super String>",
|
||||||
|
"List",
|
||||||
|
"? super String",
|
||||||
|
"String"));
|
||||||
|
performWildcardPositionsTest("package test; import java.util.List; " +
|
||||||
|
"class Test { private void method() { List<? super List<?>> l; } }",
|
||||||
|
|
||||||
|
Arrays.asList("List<? super List<?>> l;",
|
||||||
|
"List<? super List<?>>",
|
||||||
|
"List",
|
||||||
|
"? super List<?>",
|
||||||
|
"List<?>",
|
||||||
|
"List",
|
||||||
|
"?"));
|
||||||
|
performWildcardPositionsTest("package test; import java.util.List; " +
|
||||||
|
"class Test { private void method() { " +
|
||||||
|
"List<? extends List<? extends List<? extends String>>> l; } }",
|
||||||
|
|
||||||
|
Arrays.asList("List<? extends List<? extends List<? extends String>>> l;",
|
||||||
|
"List<? extends List<? extends List<? extends String>>>",
|
||||||
|
"List",
|
||||||
|
"? extends List<? extends List<? extends String>>",
|
||||||
|
"List<? extends List<? extends String>>",
|
||||||
|
"List",
|
||||||
|
"? extends List<? extends String>",
|
||||||
|
"List<? extends String>",
|
||||||
|
"List",
|
||||||
|
"? extends String",
|
||||||
|
"String"));
|
||||||
|
performWildcardPositionsTest("package test; import java.util.List; " +
|
||||||
|
"class Test { private void method() { " +
|
||||||
|
"List<? extends List<? extends List<? extends String >>> l; } }",
|
||||||
|
Arrays.asList("List<? extends List<? extends List<? extends String >>> l;",
|
||||||
|
"List<? extends List<? extends List<? extends String >>>",
|
||||||
|
"List",
|
||||||
|
"? extends List<? extends List<? extends String >>",
|
||||||
|
"List<? extends List<? extends String >>",
|
||||||
|
"List",
|
||||||
|
"? extends List<? extends String >",
|
||||||
|
"List<? extends String >",
|
||||||
|
"List",
|
||||||
|
"? extends String",
|
||||||
|
"String"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void performWildcardPositionsTest(final String code,
|
||||||
|
List<String> golden) throws IOException {
|
||||||
|
|
||||||
|
final List<Diagnostic<? extends JavaFileObject>> errors =
|
||||||
|
new LinkedList<Diagnostic<? extends JavaFileObject>>();
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null,
|
||||||
|
new DiagnosticListener<JavaFileObject>() {
|
||||||
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
errors.add(diagnostic);
|
||||||
|
}
|
||||||
|
}, null, null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
final CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
final List<String> content = new LinkedList<String>();
|
||||||
|
final Trees trees = Trees.instance(ct);
|
||||||
|
|
||||||
|
new TreeScanner<Void, Void>() {
|
||||||
|
@Override
|
||||||
|
public Void scan(Tree node, Void p) {
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
long start = trees.getSourcePositions().getStartPosition(cut, node);
|
||||||
|
|
||||||
|
if (start == (-1)) {
|
||||||
|
return null; //synthetic tree
|
||||||
|
}
|
||||||
|
long end = trees.getSourcePositions().getEndPosition(cut, node);
|
||||||
|
String s = code.substring((int) start, (int) end);
|
||||||
|
content.add(s);
|
||||||
|
|
||||||
|
return super.scan(node, p);
|
||||||
|
}
|
||||||
|
}.scan(((MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0)).getBody().getStatements().get(0), null);
|
||||||
|
|
||||||
|
assertEquals("performWildcardPositionsTest",golden.toString(),
|
||||||
|
content.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStartPositionForMethodWithoutModifiers() throws IOException {
|
||||||
|
|
||||||
|
String code = "package t; class Test { <T> void t() {} }";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
MethodTree mt = (MethodTree) clazz.getMembers().get(0);
|
||||||
|
Trees t = Trees.instance(ct);
|
||||||
|
int start = (int) t.getSourcePositions().getStartPosition(cut, mt);
|
||||||
|
int end = (int) t.getSourcePositions().getEndPosition(cut, mt);
|
||||||
|
|
||||||
|
assertEquals("testStartPositionForMethodWithoutModifiers",
|
||||||
|
"<T> void t() {}", code.substring(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStartPositionEnumConstantInit() throws IOException {
|
||||||
|
|
||||||
|
String code = "package t; enum Test { AAA; }";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
|
||||||
|
VariableTree enumAAA = (VariableTree) clazz.getMembers().get(0);
|
||||||
|
Trees t = Trees.instance(ct);
|
||||||
|
int start = (int) t.getSourcePositions().getStartPosition(cut,
|
||||||
|
enumAAA.getInitializer());
|
||||||
|
|
||||||
|
assertEquals("testStartPositionEnumConstantInit", -1, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testVariableInIfThen1() throws IOException {
|
||||||
|
|
||||||
|
String code = "package t; class Test { " +
|
||||||
|
"private static void t(String name) { " +
|
||||||
|
"if (name != null) String nn = name.trim(); } }";
|
||||||
|
|
||||||
|
DiagnosticCollector<JavaFileObject> coll =
|
||||||
|
new DiagnosticCollector<JavaFileObject>();
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
ct.parse();
|
||||||
|
|
||||||
|
List<String> codes = new LinkedList<String>();
|
||||||
|
|
||||||
|
for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
|
||||||
|
codes.add(d.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("testVariableInIfThen1",
|
||||||
|
Arrays.<String>asList("compiler.err.variable.not.allowed"),
|
||||||
|
codes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testVariableInIfThen2() throws IOException {
|
||||||
|
|
||||||
|
String code = "package t; class Test { " +
|
||||||
|
"private static void t(String name) { " +
|
||||||
|
"if (name != null) class X {} } }";
|
||||||
|
DiagnosticCollector<JavaFileObject> coll =
|
||||||
|
new DiagnosticCollector<JavaFileObject>();
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
ct.parse();
|
||||||
|
|
||||||
|
List<String> codes = new LinkedList<String>();
|
||||||
|
|
||||||
|
for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
|
||||||
|
codes.add(d.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("testVariableInIfThen2",
|
||||||
|
Arrays.<String>asList("compiler.err.class.not.allowed"), codes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testVariableInIfThen3() throws IOException {
|
||||||
|
|
||||||
|
String code = "package t; class Test { "+
|
||||||
|
"private static void t(String name) { " +
|
||||||
|
"if (name != null) abstract } }";
|
||||||
|
DiagnosticCollector<JavaFileObject> coll =
|
||||||
|
new DiagnosticCollector<JavaFileObject>();
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
ct.parse();
|
||||||
|
|
||||||
|
List<String> codes = new LinkedList<String>();
|
||||||
|
|
||||||
|
for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
|
||||||
|
codes.add(d.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("testVariableInIfThen3",
|
||||||
|
Arrays.<String>asList("compiler.err.illegal.start.of.expr"),
|
||||||
|
codes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//see javac bug #6882235, NB bug #98234:
|
||||||
|
public void testMissingExponent() throws IOException {
|
||||||
|
|
||||||
|
String code = "\nclass Test { { System.err.println(0e); } }";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
|
||||||
|
assertNotNull(ct.parse().iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTryResourcePos() throws IOException {
|
||||||
|
|
||||||
|
final String code = "package t; class Test { " +
|
||||||
|
"{ try (java.io.InputStream in = null) { } } }";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
|
||||||
|
new TreeScanner<Void, Void>() {
|
||||||
|
@Override
|
||||||
|
public Void visitVariable(VariableTree node, Void p) {
|
||||||
|
if ("in".contentEquals(node.getName())) {
|
||||||
|
JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node;
|
||||||
|
System.out.println(node.getName() + "," + var.pos);
|
||||||
|
assertEquals("testTryResourcePos", "in = null) { } } }",
|
||||||
|
code.substring(var.pos));
|
||||||
|
}
|
||||||
|
return super.visitVariable(node, p);
|
||||||
|
}
|
||||||
|
}.scan(cut, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testVarPos() throws IOException {
|
||||||
|
|
||||||
|
final String code = "package t; class Test { " +
|
||||||
|
"{ java.io.InputStream in = null; } }";
|
||||||
|
|
||||||
|
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
|
||||||
|
null, Arrays.asList(new MyFileObject(code)));
|
||||||
|
CompilationUnitTree cut = ct.parse().iterator().next();
|
||||||
|
|
||||||
|
new TreeScanner<Void, Void>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitVariable(VariableTree node, Void p) {
|
||||||
|
if ("in".contentEquals(node.getName())) {
|
||||||
|
JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node;
|
||||||
|
assertEquals("testVarPos","in = null; } }",
|
||||||
|
code.substring(var.pos));
|
||||||
|
}
|
||||||
|
return super.visitVariable(node, p);
|
||||||
|
}
|
||||||
|
}.scan(cut, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testsNotWorking() throws IOException {
|
||||||
|
|
||||||
|
// Fails with nb-javac, needs further investigation
|
||||||
|
testPositionBrokenSource126732a();
|
||||||
|
testPositionBrokenSource126732b();
|
||||||
|
|
||||||
|
// Fails, these tests yet to be addressed
|
||||||
|
testVariableInIfThen1();
|
||||||
|
testVariableInIfThen2();
|
||||||
|
testPositionForEnumModifiers();
|
||||||
|
testStartPositionEnumConstantInit();
|
||||||
|
}
|
||||||
|
void testPositions() throws IOException {
|
||||||
|
testPositionsSane();
|
||||||
|
testCorrectWilcardPositions();
|
||||||
|
testPositionAnnotationNoPackage187551();
|
||||||
|
testPositionForSuperConstructorCalls();
|
||||||
|
testPreferredPositionForBinaryOp();
|
||||||
|
testStartPositionForMethodWithoutModifiers();
|
||||||
|
testVarPos();
|
||||||
|
testVariableInIfThen3();
|
||||||
|
testTryResourcePos();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws IOException {
|
||||||
|
JavacParserTest jpt = new JavacParserTest("JavacParserTest");
|
||||||
|
jpt.testPositions();
|
||||||
|
System.out.println("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class TestCase {
|
||||||
|
|
||||||
|
void assertEquals(String message, int i, int pos) {
|
||||||
|
if (i != pos) {
|
||||||
|
fail(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertFalse(String message, boolean empty) {
|
||||||
|
throw new UnsupportedOperationException("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertEquals(String message, int i, long l) {
|
||||||
|
if (i != l) {
|
||||||
|
fail(message + ":" + i + ":" + l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertEquals(String message, Object o1, Object o2) {
|
||||||
|
System.out.println(o1);
|
||||||
|
System.out.println(o2);
|
||||||
|
if (o1 != null && o2 != null && !o1.equals(o2)) {
|
||||||
|
fail(message);
|
||||||
|
}
|
||||||
|
if (o1 == null && o2 != null) {
|
||||||
|
fail(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertNotNull(Object o) {
|
||||||
|
if (o == null) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fail() {
|
||||||
|
fail("test failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fail(String message) {
|
||||||
|
throw new RuntimeException(message);
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -35,6 +35,7 @@ import javax.lang.model.element.TypeElement;
|
|||||||
import javax.tools.*;
|
import javax.tools.*;
|
||||||
|
|
||||||
import com.sun.source.util.JavacTask;
|
import com.sun.source.util.JavacTask;
|
||||||
|
import com.sun.tools.javac.api.ClientCodeWrapper;
|
||||||
import com.sun.tools.javac.api.JavacTool;
|
import com.sun.tools.javac.api.JavacTool;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic;
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
|
|
||||||
@ -171,7 +172,7 @@ public class TestSuppression {
|
|||||||
|
|
||||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
System.err.println((++total) + ": "
|
System.err.println((++total) + ": "
|
||||||
+ "resolveError:" + isResolveError((JCDiagnostic) diagnostic) + "\n"
|
+ "resolveError:" + isResolveError(unwrap(diagnostic)) + "\n"
|
||||||
+ diagnostic);
|
+ diagnostic);
|
||||||
Diagnostic.Kind dk = diagnostic.getKind();
|
Diagnostic.Kind dk = diagnostic.getKind();
|
||||||
Integer c = counts.get(dk);
|
Integer c = counts.get(dk);
|
||||||
@ -181,6 +182,14 @@ public class TestSuppression {
|
|||||||
private static boolean isResolveError(JCDiagnostic d) {
|
private static boolean isResolveError(JCDiagnostic d) {
|
||||||
return d.isFlagSet(RESOLVE_ERROR);
|
return d.isFlagSet(RESOLVE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JCDiagnostic unwrap(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
if (diagnostic instanceof JCDiagnostic)
|
||||||
|
return (JCDiagnostic) diagnostic;
|
||||||
|
if (diagnostic instanceof ClientCodeWrapper.DiagnosticSourceUnwrapper)
|
||||||
|
return ((ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic).d;
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SupportedAnnotationTypes("*")
|
@SupportedAnnotationTypes("*")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user