提交 71787079 编写于 作者: L lana

Merge

......@@ -42,7 +42,6 @@ import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.apt.comp.*;
import com.sun.tools.apt.util.Bark;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.tools.javac.parser.DocCommentScanner;
/**
* <p><b>This is NOT part of any supported API.
......
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 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
......@@ -56,7 +56,7 @@ import com.sun.tools.apt.comp.UsageMessageNeededException;
import com.sun.tools.apt.util.Bark;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import static com.sun.tools.javac.file.Paths.pathToURLs;
import static com.sun.tools.javac.file.Locations.pathToURLs;
/** This class provides a commandline interface to the apt build-time
* tool.
......
......@@ -258,7 +258,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
ClassType norm = (ClassType) t.tsym.type;
if (norm == null) {
s = localize(locale, "compiler.misc.anonymous.class", (Object) null);
} else if (norm.interfaces_field.nonEmpty()) {
} else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
s = localize(locale, "compiler.misc.anonymous.class",
visit(norm.interfaces_field.head, locale));
} else {
......
......@@ -278,7 +278,6 @@ public class Types {
boolean tPrimitive = t.isPrimitive();
boolean sPrimitive = s.isPrimitive();
if (tPrimitive == sPrimitive) {
checkUnsafeVarargsConversion(t, s, warn);
return isSubtypeUnchecked(t, s, warn);
}
if (!allowBoxing) return false;
......@@ -286,27 +285,6 @@ public class Types {
? isSubtype(boxedClass(t).type, s)
: isSubtype(unboxedType(t), s);
}
//where
private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
if (t.tag != ARRAY || isReifiable(t)) return;
ArrayType from = (ArrayType)t;
boolean shouldWarn = false;
switch (s.tag) {
case ARRAY:
ArrayType to = (ArrayType)s;
shouldWarn = from.isVarargs() &&
!to.isVarargs() &&
!isReifiable(from);
break;
case CLASS:
shouldWarn = from.isVarargs() &&
isSubtype(from, s);
break;
}
if (shouldWarn) {
warn.warn(LintCategory.VARARGS);
}
}
/**
* Is t a subtype of or convertiable via boxing/unboxing
......@@ -328,42 +306,63 @@ public class Types {
* Is t an unchecked subtype of s?
*/
public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
if (t.tag == ARRAY && s.tag == ARRAY) {
if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
return isSameType(elemtype(t), elemtype(s));
} else {
ArrayType from = (ArrayType)t;
ArrayType to = (ArrayType)s;
if (from.isVarargs() &&
!to.isVarargs() &&
!isReifiable(from)) {
warn.warn(LintCategory.VARARGS);
boolean result = isSubtypeUncheckedInternal(t, s, warn);
if (result) {
checkUnsafeVarargsConversion(t, s, warn);
}
return result;
}
//where
private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
if (t.tag == ARRAY && s.tag == ARRAY) {
if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
return isSameType(elemtype(t), elemtype(s));
} else {
return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
}
return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
} else if (isSubtype(t, s)) {
return true;
}
} else if (isSubtype(t, s)) {
return true;
}
else if (t.tag == TYPEVAR) {
return isSubtypeUnchecked(t.getUpperBound(), s, warn);
}
else if (s.tag == UNDETVAR) {
UndetVar uv = (UndetVar)s;
if (uv.inst != null)
return isSubtypeUnchecked(t, uv.inst, warn);
else if (t.tag == TYPEVAR) {
return isSubtypeUnchecked(t.getUpperBound(), s, warn);
}
else if (s.tag == UNDETVAR) {
UndetVar uv = (UndetVar)s;
if (uv.inst != null)
return isSubtypeUnchecked(t, uv.inst, warn);
}
else if (!s.isRaw()) {
Type t2 = asSuper(t, s.tsym);
if (t2 != null && t2.isRaw()) {
if (isReifiable(s))
warn.silentWarn(LintCategory.UNCHECKED);
else
warn.warn(LintCategory.UNCHECKED);
return true;
}
}
return false;
}
else if (!s.isRaw()) {
Type t2 = asSuper(t, s.tsym);
if (t2 != null && t2.isRaw()) {
if (isReifiable(s))
warn.silentWarn(LintCategory.UNCHECKED);
else
warn.warn(LintCategory.UNCHECKED);
return true;
private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
if (t.tag != ARRAY || isReifiable(t)) return;
ArrayType from = (ArrayType)t;
boolean shouldWarn = false;
switch (s.tag) {
case ARRAY:
ArrayType to = (ArrayType)s;
shouldWarn = from.isVarargs() &&
!to.isVarargs() &&
!isReifiable(from);
break;
case CLASS:
shouldWarn = from.isVarargs();
break;
}
if (shouldWarn) {
warn.warn(LintCategory.VARARGS);
}
}
return false;
}
/**
* Is t a subtype of s?<br>
......
......@@ -34,7 +34,8 @@ import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import static com.sun.tools.javac.code.TypeTags.*;
......@@ -56,6 +57,7 @@ public class Infer {
Types types;
Check chk;
Resolve rs;
Log log;
JCDiagnostic.Factory diags;
public static Infer instance(Context context) {
......@@ -70,6 +72,7 @@ public class Infer {
syms = Symtab.instance(context);
types = Types.instance(context);
rs = Resolve.instance(context);
log = Log.instance(context);
chk = Check.instance(context);
diags = JCDiagnostic.Factory.instance(context);
ambiguousNoInstanceException =
......@@ -460,7 +463,7 @@ public class Infer {
// quantify result type with them
final List<Type> inferredTypes = insttypes.toList();
final List<Type> all_tvars = tvars; //this is the wrong tvars
return new UninferredMethodType(mt, restvars.toList()) {
return new UninferredMethodType(env.tree.pos(), msym, mt, restvars.toList()) {
@Override
List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
for (Type t : restundet.toList()) {
......@@ -502,13 +505,17 @@ public class Infer {
* type - when the return type is instantiated (see Infer.instantiateExpr)
* the underlying method type is also updated.
*/
static abstract class UninferredMethodType extends DelegatedType {
abstract class UninferredMethodType extends DelegatedType {
final List<Type> tvars;
final Symbol msym;
final DiagnosticPosition pos;
public UninferredMethodType(MethodType mtype, List<Type> tvars) {
public UninferredMethodType(DiagnosticPosition pos, Symbol msym, MethodType mtype, List<Type> tvars) {
super(METHOD, new MethodType(mtype.argtypes, null, mtype.thrown, mtype.tsym));
this.tvars = tvars;
this.msym = msym;
this.pos = pos;
asMethodType().restype = new UninferredReturnType(tvars, mtype.restype);
}
......@@ -543,6 +550,9 @@ public class Infer {
public Type inst(List<Type> actuals, Types types) {
Type newRestype = super.inst(actuals, types);
instantiateReturnType(newRestype, actuals, types);
if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
log.note(pos, "deferred.method.inst", msym, UninferredMethodType.this.qtype, newRestype);
}
return newRestype;
}
@Override
......
......@@ -25,29 +25,33 @@
package com.sun.tools.javac.comp;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.api.Formattable.LocalizedString;
import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.TypeTags.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
import javax.lang.model.element.ElementVisitor;
import java.util.Map;
import java.util.Set;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.lang.model.element.ElementVisitor;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.TypeTags.*;
import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
/** Helper class for name resolution, used mostly by the attribution phase.
*
......@@ -73,9 +77,45 @@ public class Resolve {
public final boolean varargsEnabled; // = source.allowVarargs();
public final boolean allowMethodHandles;
private final boolean debugResolve;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
Scope polymorphicSignatureScope;
enum VerboseResolutionMode {
SUCCESS("success"),
FAILURE("failure"),
APPLICABLE("applicable"),
INAPPLICABLE("inapplicable"),
DEFERRED_INST("deferred-inference"),
PREDEF("predef"),
OBJECT_INIT("object-init"),
INTERNAL("internal");
String opt;
private VerboseResolutionMode(String opt) {
this.opt = opt;
}
static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
String s = opts.get("verboseResolution");
EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
if (s == null) return res;
if (s.contains("all")) {
res = EnumSet.allOf(VerboseResolutionMode.class);
}
Collection<String> args = Arrays.asList(s.split(","));
for (VerboseResolutionMode mode : values()) {
if (args.contains(mode.opt)) {
res.add(mode);
} else if (args.contains("-" + mode.opt)) {
res.remove(mode);
}
}
return res;
}
}
public static Resolve instance(Context context) {
Resolve instance = context.get(resolveKey);
if (instance == null)
......@@ -111,6 +151,7 @@ public class Resolve {
varargsEnabled = source.allowVarargs();
Options options = Options.instance(context);
debugResolve = options.isSet("debugresolve");
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
polymorphicSignatureScope = new Scope(syms.noSymbol);
......@@ -684,13 +725,16 @@ public class Resolve {
if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
Assert.check(sym.kind < AMBIGUOUS);
try {
rawInstantiate(env, site, sym, argtypes, typeargtypes,
Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
allowBoxing, useVarargs, Warner.noWarnings);
if (!operator) addVerboseApplicableCandidateDiag(sym ,mt);
} catch (InapplicableMethodException ex) {
if (!operator) addVerboseInapplicableCandidateDiag(sym, ex.getDiagnostic());
switch (bestSoFar.kind) {
case ABSENT_MTH:
return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
case WRONG_MTH:
if (operator) return bestSoFar;
wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation);
case WRONG_MTHS:
return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic());
......@@ -708,6 +752,34 @@ public class Resolve {
: mostSpecific(sym, bestSoFar, env, site,
allowBoxing && operator, useVarargs);
}
//where
void addVerboseApplicableCandidateDiag(Symbol sym, Type inst) {
if (!verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE))
return;
JCDiagnostic subDiag = null;
if (inst.getReturnType().tag == FORALL) {
Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
((ForAll)inst.getReturnType()).qtype);
subDiag = diags.fragment("partial.inst.sig", diagType);
} else if (sym.type.tag == FORALL) {
subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
}
String key = subDiag == null ?
"applicable.method.found" :
"applicable.method.found.1";
verboseResolutionCandidateDiags.put(sym,
diags.fragment(key, verboseResolutionCandidateDiags.size(), sym, subDiag));
}
void addVerboseInapplicableCandidateDiag(Symbol sym, JCDiagnostic subDiag) {
if (!verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))
return;
verboseResolutionCandidateDiags.put(sym,
diags.fragment("not.applicable.method.found", verboseResolutionCandidateDiags.size(), sym, subDiag));
}
/* Return the most specific of the two methods for a call,
* given that both are accessible and applicable.
......@@ -905,8 +977,9 @@ public class Resolve {
boolean allowBoxing,
boolean useVarargs,
boolean operator) {
verboseResolutionCandidateDiags.clear();
Symbol bestSoFar = methodNotFound;
return findMethod(env,
bestSoFar = findMethod(env,
site,
name,
argtypes,
......@@ -918,6 +991,8 @@ public class Resolve {
useVarargs,
operator,
new HashSet<TypeSymbol>());
reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
return bestSoFar;
}
// where
private Symbol findMethod(Env<AttrContext> env,
......@@ -975,6 +1050,37 @@ public class Resolve {
}
return bestSoFar;
}
//where
void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
boolean success = bestSoFar.kind < ERRONEOUS;
if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
return;
} else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
return;
}
if (bestSoFar.name == names.init &&
bestSoFar.owner == syms.objectType.tsym &&
!verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
return; //skip diags for Object constructor resolution
} else if (site == syms.predefClass.type && !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
return; //skip spurious diags for predef symbols (i.e. operators)
} else if (internalResolution && !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
return;
}
int pos = 0;
for (Symbol s : verboseResolutionCandidateDiags.keySet()) {
if (s == bestSoFar) break;
pos++;
}
String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, site.tsym, pos, currentStep,
methodArguments(argtypes), methodArguments(typeargtypes));
JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, List.from(verboseResolutionCandidateDiags.values().toArray(new JCDiagnostic[verboseResolutionCandidateDiags.size()])));
log.report(d);
}
/** Find unqualified method matching given name, type and value arguments.
* @param env The current environment.
......@@ -1543,12 +1649,19 @@ public class Resolve {
Type site, Name name,
List<Type> argtypes,
List<Type> typeargtypes) {
Symbol sym = resolveQualifiedMethod(
pos, env, site.tsym, site, name, argtypes, typeargtypes);
if (sym.kind == MTH) return (MethodSymbol)sym;
else throw new FatalError(
diags.fragment("fatal.err.cant.locate.meth",
name));
boolean prevInternal = internalResolution;
try {
internalResolution = true;
Symbol sym = resolveQualifiedMethod(
pos, env, site.tsym, site, name, argtypes, typeargtypes);
if (sym.kind == MTH) return (MethodSymbol)sym;
else throw new FatalError(
diags.fragment("fatal.err.cant.locate.meth",
name));
}
finally {
internalResolution = prevInternal;
}
}
/** Resolve constructor.
......@@ -1685,6 +1798,7 @@ public class Resolve {
*/
Symbol resolveOperator(DiagnosticPosition pos, int optag,
Env<AttrContext> env, List<Type> argtypes) {
startResolution();
Name name = treeinfo.operatorName(optag);
Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
null, false, false, true);
......@@ -1828,7 +1942,7 @@ public class Resolve {
private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
public Object methodArguments(List<Type> argtypes) {
return argtypes.isEmpty() ? noArgs : argtypes;
return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
}
/**
......@@ -2375,10 +2489,15 @@ public class Resolve {
private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
private Map<Symbol, JCDiagnostic> verboseResolutionCandidateDiags =
new LinkedHashMap<Symbol, JCDiagnostic>();
final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
private MethodResolutionPhase currentStep = null;
private boolean internalResolution = false;
private MethodResolutionPhase firstErroneousResolutionPhase() {
MethodResolutionPhase bestSoFar = BASIC;
Symbol sym = methodNotFound;
......
......@@ -25,7 +25,6 @@
package com.sun.tools.javac.file;
import java.util.Comparator;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
......@@ -41,6 +40,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
......@@ -56,14 +56,12 @@ import javax.tools.StandardJavaFileManager;
import com.sun.tools.javac.file.RelativePath.RelativeFile;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.main.OptionName;
import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import static javax.tools.StandardLocation.*;
import static com.sun.tools.javac.main.OptionName.*;
/**
* This class provides access to the source, class and other files
......@@ -83,32 +81,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return buffer.toString().toCharArray();
}
/** Encapsulates knowledge of paths
*/
private Paths paths;
private FSInfo fsInfo;
private boolean contextUseOptimizedZip;
private ZipFileIndexCache zipFileIndexCache;
private final File uninited = new File("U N I N I T E D");
private final Set<JavaFileObject.Kind> sourceOrClass =
EnumSet.of(JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS);
/** The standard output directory, primarily used for classes.
* Initialized by the "-d" option.
* If classOutDir = null, files are written into same directory as the sources
* they were generated from.
*/
private File classOutDir = uninited;
/** The output directory, used when generating sources while processing annotations.
* Initialized by the "-s" option.
*/
private File sourceOutDir = uninited;
protected boolean mmappedIO;
protected boolean ignoreSymbolFile;
......@@ -154,13 +134,6 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override
public void setContext(Context context) {
super.setContext(context);
if (paths == null) {
paths = Paths.instance(context);
} else {
// Reuse the Paths object as it stores the locations that
// have been set with setLocation, etc.
paths.setContext(context);
}
fsInfo = FSInfo.instance(context);
......@@ -179,7 +152,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override
public boolean isDefaultBootClassPath() {
return paths.isDefaultBootClassPath();
return locations.isDefaultBootClassPath();
}
public JavaFileObject getFileForInput(String name) {
......@@ -493,7 +466,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
*/
private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException {
File origZipFileName = zipFileName;
if (!ignoreSymbolFile && paths.isDefaultBootClassPathRtJar(zipFileName)) {
if (!ignoreSymbolFile && locations.isDefaultBootClassPathRtJar(zipFileName)) {
File file = zipFileName.getParentFile().getParentFile(); // ${java.home}
if (new File(file.getName()).equals(new File("jre")))
file = file.getParentFile();
......@@ -780,7 +753,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
} else if (location == SOURCE_OUTPUT) {
dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
} else {
Iterable<? extends File> path = paths.getPathForLocation(location);
Iterable<? extends File> path = locations.getLocation(location);
dir = null;
for (File f: path) {
dir = f;
......@@ -815,64 +788,20 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
throws IOException
{
nullCheck(location);
paths.lazy();
final File dir = location.isOutputLocation() ? getOutputDirectory(path) : null;
if (location == CLASS_OUTPUT)
classOutDir = getOutputLocation(dir, D);
else if (location == SOURCE_OUTPUT)
sourceOutDir = getOutputLocation(dir, S);
else
paths.setPathForLocation(location, path);
}
// where
private File getOutputDirectory(Iterable<? extends File> path) throws IOException {
if (path == null)
return null;
Iterator<? extends File> pathIter = path.iterator();
if (!pathIter.hasNext())
throw new IllegalArgumentException("empty path for directory");
File dir = pathIter.next();
if (pathIter.hasNext())
throw new IllegalArgumentException("path too long for directory");
if (!dir.exists())
throw new FileNotFoundException(dir + ": does not exist");
else if (!dir.isDirectory())
throw new IOException(dir + ": not a directory");
return dir;
}
private File getOutputLocation(File dir, OptionName defaultOptionName) {
if (dir != null)
return dir;
String arg = options.get(defaultOptionName);
if (arg == null)
return null;
return new File(arg);
locations.setLocation(location, path);
}
public Iterable<? extends File> getLocation(Location location) {
nullCheck(location);
paths.lazy();
if (location == CLASS_OUTPUT) {
return (getClassOutDir() == null ? null : List.of(getClassOutDir()));
} else if (location == SOURCE_OUTPUT) {
return (getSourceOutDir() == null ? null : List.of(getSourceOutDir()));
} else
return paths.getPathForLocation(location);
return locations.getLocation(location);
}
private File getClassOutDir() {
if (classOutDir == uninited)
classOutDir = getOutputLocation(null, D);
return classOutDir;
return locations.getOutputLocation(CLASS_OUTPUT);
}
private File getSourceOutDir() {
if (sourceOutDir == uninited)
sourceOutDir = getOutputLocation(null, S);
return sourceOutDir;
return locations.getOutputLocation(SOURCE_OUTPUT);
}
/**
......
......@@ -1542,7 +1542,28 @@ public class Code {
*/
public void addCatch(
char startPc, char endPc, char handlerPc, char catchType) {
catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
catchInfo.append(new char[]{startPc, endPc, handlerPc, catchType});
}
public void compressCatchTable() {
ListBuffer<char[]> compressedCatchInfo = ListBuffer.lb();
List<Integer> handlerPcs = List.nil();
for (char[] catchEntry : catchInfo.elems) {
handlerPcs = handlerPcs.prepend((int)catchEntry[2]);
}
for (char[] catchEntry : catchInfo.elems) {
int startpc = catchEntry[0];
int endpc = catchEntry[1];
if (startpc == endpc ||
(startpc == (endpc - 1) &&
handlerPcs.contains(startpc))) {
continue;
} else {
compressedCatchInfo.append(catchEntry);
}
}
catchInfo = compressedCatchInfo;
}
......
......@@ -959,6 +959,9 @@ public class Gen extends JCTree.Visitor {
code.lastFrame = null;
code.frameBeforeLast = null;
}
//compress exception table
code.compressCatchTable();
}
}
......@@ -1437,7 +1440,6 @@ public class Gen extends JCTree.Visitor {
code.markDead();
}
}
// Resolve all breaks.
code.resolve(exitChain);
......@@ -1496,23 +1498,21 @@ public class Gen extends JCTree.Visitor {
void registerCatch(DiagnosticPosition pos,
int startpc, int endpc,
int handler_pc, int catch_type) {
if (startpc != endpc) {
char startpc1 = (char)startpc;
char endpc1 = (char)endpc;
char handler_pc1 = (char)handler_pc;
if (startpc1 == startpc &&
endpc1 == endpc &&
handler_pc1 == handler_pc) {
code.addCatch(startpc1, endpc1, handler_pc1,
(char)catch_type);
char startpc1 = (char)startpc;
char endpc1 = (char)endpc;
char handler_pc1 = (char)handler_pc;
if (startpc1 == startpc &&
endpc1 == endpc &&
handler_pc1 == handler_pc) {
code.addCatch(startpc1, endpc1, handler_pc1,
(char)catch_type);
} else {
if (!useJsrLocally && !target.generateStackMapTable()) {
useJsrLocally = true;
throw new CodeSizeOverflow();
} else {
if (!useJsrLocally && !target.generateStackMapTable()) {
useJsrLocally = true;
throw new CodeSizeOverflow();
} else {
log.error(pos, "limit.code.too.large.for.try.stmt");
nerrs++;
}
log.error(pos, "limit.code.too.large.for.try.stmt");
nerrs++;
}
}
}
......
......@@ -25,9 +25,7 @@
package com.sun.tools.javac.nio;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
......@@ -60,7 +58,6 @@ import javax.tools.StandardLocation;
import static java.nio.file.FileVisitOption.*;
import static javax.tools.StandardLocation.*;
import com.sun.tools.javac.file.Paths;
import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
......@@ -125,9 +122,8 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
* Set the context for JavacPathFileManager.
*/
@Override
protected void setContext(Context context) {
public void setContext(Context context) {
super.setContext(context);
searchPaths = Paths.instance(context);
}
@Override
......@@ -173,7 +169,7 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
@Override
public boolean isDefaultBootClassPath() {
return searchPaths.isDefaultBootClassPath();
return locations.isDefaultBootClassPath();
}
// <editor-fold defaultstate="collapsed" desc="Location handling">
......@@ -231,13 +227,13 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
if (locn instanceof StandardLocation) {
switch ((StandardLocation) locn) {
case CLASS_PATH:
files = searchPaths.userClassPath();
files = locations.userClassPath();
break;
case PLATFORM_CLASS_PATH:
files = searchPaths.bootClassPath();
files = locations.bootClassPath();
break;
case SOURCE_PATH:
files = searchPaths.sourcePath();
files = locations.sourcePath();
break;
case CLASS_OUTPUT: {
String arg = options.get(D);
......@@ -272,7 +268,6 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
private boolean inited = false;
private Map<Location, PathsForLocation> pathsForLocation;
private Paths searchPaths;
private static class PathsForLocation extends LinkedHashSet<Path> {
private static final long serialVersionUID = 6788510222394486733L;
......
......@@ -67,14 +67,14 @@ public class EndPosParser extends JavacParser {
/** {@inheritDoc} */
@Override
protected <T extends JCTree> T to(T t) {
storeEnd(t, S.endPos());
storeEnd(t, token.endPos);
return t;
}
/** {@inheritDoc} */
@Override
protected <T extends JCTree> T toP(T t) {
storeEnd(t, S.prevEndPos());
storeEnd(t, S.prevToken().endPos);
return t;
}
......@@ -88,7 +88,7 @@ public class EndPosParser extends JavacParser {
/** {@inheritDoc} */
@Override
JCExpression parExpression() {
int pos = S.pos();
int pos = token.pos;
JCExpression t = super.parExpression();
return toP(F.at(pos).Parens(t));
}
......
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,9 +25,12 @@
package com.sun.tools.javac.parser;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.parser.Tokens.Token;
import com.sun.tools.javac.util.*;
import java.nio.*;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.util.LayoutCharacters.*;
/** An extension to the base lexical analyzer that captures
......@@ -40,26 +43,22 @@ import static com.sun.tools.javac.util.LayoutCharacters.*;
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class DocCommentScanner extends Scanner {
public class JavadocTokenizer extends JavaTokenizer {
/** Create a scanner from the input buffer. buffer must implement
* array() and compact(), and remaining() must be less than limit().
*/
protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) {
protected JavadocTokenizer(ScannerFactory fac, CharBuffer buffer) {
super(fac, buffer);
}
/** Create a scanner from the input array. The array must have at
* least a single character of extra space.
*/
protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) {
protected JavadocTokenizer(ScannerFactory fac, char[] input, int inputLength) {
super(fac, input, inputLength);
}
/** Starting position of the comment in original source
*/
private int pos;
/** The comment input buffer, index of next chacter to be read,
* index of one past last character in buffer.
*/
......@@ -178,6 +177,14 @@ public class DocCommentScanner extends Scanner {
}
}
@Override
public Token readToken() {
docComment = null;
Token tk = super.readToken();
tk.docComment = docComment;
return tk;
}
/**
* Read next character in doc comment, skipping over double '\' characters.
* If a double '\' is skipped, put in the buffer and update buffer count.
......@@ -196,32 +203,17 @@ public class DocCommentScanner extends Scanner {
}
}
/* Reset doc comment before reading each new token
*/
public void nextToken() {
docComment = null;
super.nextToken();
}
/**
* Returns the documentation string of the current token.
*/
public String docComment() {
return docComment;
}
/**
* Process a doc comment and make the string content available.
* Strips leading whitespace and stars.
*/
@SuppressWarnings("fallthrough")
protected void processComment(CommentStyle style) {
protected void processComment(int pos, int endPos, CommentStyle style) {
if (style != CommentStyle.JAVADOC) {
return;
}
pos = pos();
buf = getRawCharacters(pos, endPos());
buf = reader.getRawCharacters(pos, endPos);
buflen = buf.length;
bp = 0;
col = 0;
......@@ -414,7 +406,7 @@ public class DocCommentScanner extends Scanner {
*
* @return a LineMap */
public Position.LineMap getLineMap() {
char[] buf = getRawCharacters();
char[] buf = reader.getRawCharacters();
return Position.makeLineMap(buf, buf.length, true);
}
}
......@@ -25,7 +25,7 @@
package com.sun.tools.javac.parser;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.parser.Tokens.*;
import com.sun.tools.javac.util.Position.LineMap;
/**
......@@ -40,22 +40,26 @@ import com.sun.tools.javac.util.Position.LineMap;
public interface Lexer {
/**
* Has a @deprecated been encountered in last doc comment?
* This needs to be reset by client with resetDeprecatedFlag.
* Consume the next token.
*/
boolean deprecatedFlag();
void nextToken();
void resetDeprecatedFlag();
/**
* Return current token.
*/
Token token();
/**
* Returns the documentation string of the current token.
* Return the last character position of the previous token.
*/
String docComment();
Token prevToken();
/**
* Return the last character position of the current token.
* Splits the current token in two and return the first (splitted) token.
* For instance '<<<' is splitted into two tokens '<' and '<<' respectively,
* and the latter is returned.
*/
int endPos();
Token split();
/**
* Return the position where a lexical error occurred;
......@@ -74,69 +78,4 @@ public interface Lexer {
* @return a LineMap
*/
LineMap getLineMap();
/**
* Returns a copy of the input buffer, up to its inputLength.
* Unicode escape sequences are not translated.
*/
char[] getRawCharacters();
/**
* Returns a copy of a character array subset of the input buffer.
* The returned array begins at the <code>beginIndex</code> and
* extends to the character at index <code>endIndex - 1</code>.
* Thus the length of the substring is <code>endIndex-beginIndex</code>.
* This behavior is like
* <code>String.substring(beginIndex, endIndex)</code>.
* Unicode escape sequences are not translated.
*
* @param beginIndex the beginning index, inclusive.
* @param endIndex the ending index, exclusive.
* @throws IndexOutOfBounds if either offset is outside of the
* array bounds
*/
char[] getRawCharacters(int beginIndex, int endIndex);
/**
* Return the name of an identifier or token for the current token.
*/
Name name();
/**
* Read token.
*/
void nextToken();
/**
* Return the current token's position: a 0-based
* offset from beginning of the raw input stream
* (before unicode translation)
*/
int pos();
/**
* Return the last character position of the previous token.
*/
int prevEndPos();
/**
* Return the radix of a numeric literal token.
*/
int radix();
/**
* The value of a literal token, recorded as a string.
* For integers, leading 0x and 'l' suffixes are suppressed.
*/
String stringVal();
/**
* Return the current token, set by nextToken().
*/
Token token();
/**
* Sets the current token.
*/
void token(Token token);
}
......@@ -55,7 +55,7 @@ public class ParserFactory {
final TreeMaker F;
final Log log;
final Keywords keywords;
final Tokens tokens;
final Source source;
final Names names;
final Options options;
......@@ -67,7 +67,7 @@ public class ParserFactory {
this.F = TreeMaker.instance(context);
this.log = Log.instance(context);
this.names = Names.instance(context);
this.keywords = Keywords.instance(context);
this.tokens = Tokens.instance(context);
this.source = Source.instance(context);
this.options = Options.instance(context);
this.scannerFactory = ScannerFactory.instance(context);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册