--- a/langtools/make/build.properties Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/make/build.properties Sun Jan 20 23:39:11 2013 -0800
@@ -29,18 +29,18 @@
# Override this path as needed, either on the command line or in
# one of the standard user build.properties files (see build.xml)
-# boot.java.home = /opt/jdk/1.6.0
+# boot.java.home = /opt/jdk/1.7.0
boot.java = ${boot.java.home}/bin/java
boot.javac = ${boot.java.home}/bin/javac
-boot.javac.source = 6
-boot.javac.target = 6
+boot.javac.source = 7
+boot.javac.target = 7
# This is the JDK used to run the product version of the tools,
# for example, for testing. If you're building a complete JDK, specify that.
# Override this path as needed, either on the command line or in
# one of the standard user build.properties files (see build.xml)
-# target.java.home = /opt/jdk/1.7.0
+# target.java.home = /opt/jdk/1.8.0
target.java = ${target.java.home}/bin/java
# Version info -- override as needed
@@ -161,6 +161,14 @@
#
+sjavac.includes = \
+ com/sun/tools/sjavac/
+
+sjavac.tests = \
+ tools/sjavac
+
+#
+
# The following files require the latest JDK to be available.
# The API can be provided by using a suitable boot.java.home
# or by setting import.jdk
--- a/langtools/make/build.xml Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/make/build.xml Sun Jan 20 23:39:11 2013 -0800
@@ -241,15 +241,15 @@
</target>
<target name="build-bootstrap-tools"
- depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah"
+ depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah,build-bootstrap-sjavac"
/>
<target name="build-all-tools"
- depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap"
+ depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap,build-sjavac"
/>
<target name="build-all-classes" depends="build-bootstrap-javac,-create-import-jdk-stubs">
- <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes}"/>
+ <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes} ${sjavac.includes}"/>
</target>
<!-- clean -->
@@ -656,6 +656,40 @@
<target name="javap" depends="build-javap,jtreg-javap,findbugs-javap"/>
+ <!--
+ **** sjavac targets.
+ -->
+
+ <target name="build-bootstrap-sjavac"
+ depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
+ <build-bootstrap-classes includes="${sjavac.includes}"/>
+ <build-bootstrap-jar name="sjavac" includes="${sjavac.includes}"
+ jarmainclass="com.sun.tools.sjavac.Main"/>
+ <build-bootstrap-tool name="sjavac"/>
+ </target>
+
+ <target name="build-classes-sjavac" depends="build-classes-javac">
+ <build-classes includes="${sjavac.includes}"/>
+ </target>
+
+ <target name="build-sjavac" depends="build-classes-sjavac">
+ <build-jar name="sjavac" includes="${sjavac.includes}"
+ jarmainclass="com.sun.tools.sjavac.Main"
+ jarclasspath="sjavac.jar"/>
+ <build-tool name="sjavac"/>
+ </target>
+
+ <!-- (no javadoc for javap) -->
+
+ <target name="jtreg-sjavac" depends="build-sjavac,-def-jtreg">
+ <jtreg-tool name="sjavac" tests="${sjavac.tests}"/>
+ </target>
+
+ <target name="findbugs-sjavac" depends="build-sjavac,-def-findbugs">
+ <findbugs-tool name="sjavac"/>
+ </target>
+
+ <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
<!--
**** Create import JDK stubs.
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, 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
@@ -33,8 +33,10 @@
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
+import com.sun.tools.doclint.DocLint;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
+import com.sun.tools.javadoc.RootDocImpl;
/**
* Configure the output based on the command line options.
@@ -172,6 +174,11 @@
public boolean createoverview = false;
/**
+ * Collected set of doclint options
+ */
+ public Set<String> doclintOpts = new LinkedHashSet<String>();
+
+ /**
* Unique Resource Handler for this package.
*/
public final MessageRetriever standardmessage;
@@ -255,6 +262,10 @@
nooverview = true;
} else if (opt.equals("-overview")) {
overview = true;
+ } else if (opt.equals("-xdoclint")) {
+ doclintOpts.add(null);
+ } else if (opt.startsWith("-xdoclint:")) {
+ doclintOpts.add(opt.substring(opt.indexOf(":") + 1));
}
}
if (root.specifiedClasses().length > 0) {
@@ -270,6 +281,10 @@
}
setCreateOverview();
setTopFile(root);
+
+ if (root instanceof RootDocImpl) {
+ ((RootDocImpl) root).initDocLint(doclintOpts);
+ }
}
/**
@@ -303,7 +318,9 @@
option.equals("-serialwarn") ||
option.equals("-use") ||
option.equals("-nonavbar") ||
- option.equals("-nooverview")) {
+ option.equals("-nooverview") ||
+ option.equals("-xdoclint") ||
+ option.startsWith("-xdoclint:")) {
return 1;
} else if (option.equals("-help")) {
System.out.println(getText("doclet.usage"));
@@ -410,6 +427,16 @@
return false;
}
noindex = true;
+ } else if (opt.startsWith("-xdoclint:")) {
+ if (opt.contains("/")) {
+ reporter.printError(getText("doclet.Option_doclint_no_qualifiers"));
+ return false;
+ }
+ if (!DocLint.isValidOption(
+ opt.replace("-xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX))) {
+ reporter.printError(getText("doclet.Option_doclint_invalid_arg"));
+ return false;
+ }
}
}
return true;
@@ -506,8 +533,8 @@
*/
@Override
public Locale getLocale() {
- if (root instanceof com.sun.tools.javadoc.RootDocImpl)
- return ((com.sun.tools.javadoc.RootDocImpl)root).getLocale();
+ if (root instanceof RootDocImpl)
+ return ((RootDocImpl)root).getLocale();
else
return Locale.getDefault();
}
@@ -518,8 +545,8 @@
@Override
public JavaFileManager getFileManager() {
if (fileManager == null) {
- if (root instanceof com.sun.tools.javadoc.RootDocImpl)
- fileManager = ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager();
+ if (root instanceof RootDocImpl)
+ fileManager = ((RootDocImpl) root).getFileManager();
else
fileManager = new JavacFileManager(new Context(), false, null);
}
@@ -527,4 +554,12 @@
}
private JavaFileManager fileManager;
+
+ @Override
+ public boolean showMessage(SourcePosition pos, String key) {
+ if (root instanceof RootDocImpl) {
+ return pos == null || ((RootDocImpl) root).showTagMessages();
+ }
+ return true;
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -781,4 +781,6 @@
sourcetab = n;
tabSpaces = String.format("%" + n + "s", "");
}
+
+ public abstract boolean showMessage(SourcePosition pos, String key);
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Sun Jan 20 23:39:11 2013 -0800
@@ -11,6 +11,8 @@
doclet.Class_0_extends_implements_serializable=Class {0} extends {1} implements Serializable
doclet.Option_conflict=Option {0} conflicts with {1}
doclet.Option_reuse=Option reused: {0}
+doclet.Option_doclint_no_qualifiers=Access qualifiers not permitted for -Xdoclint arguments
+doclet.Option_doclint_invalid_arg=Invalid argument for -Xdoclint option
doclet.exception_encountered= {0} encountered \n\
\twhile attempting to create file: {1}
doclet.perform_copy_exception_encountered= {0} encountered while \n\
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, 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
@@ -60,9 +60,9 @@
private ResourceBundle messageRB;
/**
- * Initilize the ResourceBundle with the given resource.
+ * Initialize the ResourceBundle with the given resource.
*
- * @param rb the esource bundle to read.
+ * @param rb the resource bundle to read.
*/
public MessageRetriever(ResourceBundle rb) {
this.configuration = null;
@@ -71,7 +71,7 @@
}
/**
- * Initilize the ResourceBundle with the given resource.
+ * Initialize the ResourceBundle with the given resource.
*
* @param configuration the configuration
* @param resourcelocation Resource.
@@ -189,7 +189,8 @@
* @param args arguments to be replaced in the message.
*/
public void warning(SourcePosition pos, String key, Object... args) {
- printWarning(pos, getText(key, args));
+ if (configuration.showMessage(pos, key))
+ printWarning(pos, getText(key, args));
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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,6 +25,7 @@
package com.sun.tools.doclint;
+import com.sun.source.doctree.LiteralTree;
import java.util.regex.Matcher;
import com.sun.source.doctree.LinkTree;
import java.net.URI;
@@ -359,9 +360,8 @@
env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
} else if (t.endKind == HtmlTag.EndKind.NONE) {
env.messages.error(HTML, tree, "dc.tag.end.not.permitted", treeName);
- } else if (tagStack.isEmpty()) {
- env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
} else {
+ boolean done = false;
while (!tagStack.isEmpty()) {
TagStackItem top = tagStack.peek();
if (t == top.tag) {
@@ -383,6 +383,7 @@
env.messages.error(HTML, tree, "dc.text.not.allowed", treeName);
}
tagStack.pop();
+ done = true;
break;
} else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) {
tagStack.pop();
@@ -400,10 +401,15 @@
tagStack.pop();
} else {
env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+ done = true;
break;
}
}
}
+
+ if (!done && tagStack.isEmpty()) {
+ env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+ }
}
return super.visitEndElement(tree, ignore);
@@ -447,14 +453,18 @@
if (currTag != HtmlTag.A) {
break;
}
- // fallthrough
+ // fallthrough
case ID:
String value = getAttrValue(tree);
- if (!validName.matcher(value).matches()) {
- env.messages.error(HTML, tree, "dc.invalid.anchor", value);
- }
- if (!foundAnchors.add(value)) {
- env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+ if (value == null) {
+ env.messages.error(HTML, tree, "dc.anchor.value.missing");
+ } else {
+ if (!validName.matcher(value).matches()) {
+ env.messages.error(HTML, tree, "dc.invalid.anchor", value);
+ }
+ if (!foundAnchors.add(value)) {
+ env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+ }
}
break;
@@ -542,6 +552,19 @@
}
@Override
+ public Void visitLiteral(LiteralTree tree, Void ignore) {
+ if (tree.getKind() == DocTree.Kind.CODE) {
+ for (TagStackItem tsi: tagStack) {
+ if (tsi.tag == HtmlTag.CODE) {
+ env.messages.warning(HTML, tree, "dc.tag.code.within.code");
+ break;
+ }
+ }
+ }
+ return super.visitLiteral(tree, ignore);
+ }
+
+ @Override
public Void visitParam(ParamTree tree, Void ignore) {
boolean typaram = tree.isTypeParameter();
IdentifierTree nameTree = tree.getName();
--- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2013, 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
@@ -24,6 +24,7 @@
#
dc.anchor.already.defined = anchor already defined: {0}
+dc.anchor.value.missing = no value given for anchor
dc.attr.lacks.value = attribute lacks value
dc.attr.obsolete = attribute obsolete: {0}
dc.attr.obsolete.use.css = attribute obsolete, use CSS instead: {0}
@@ -47,6 +48,7 @@
dc.no.summary.or.caption.for.table=no summary or caption for table
dc.param.name.not.found = @param name not found
dc.ref.not.found = reference not found
+dc.tag.code.within.code = '{@code'} within <code>
dc.tag.empty = empty <{0}> tag
dc.tag.end.not.permitted = invalid end tag: </{0}>
dc.tag.end.unexpected = unexpected end tag: </{0}>
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -126,12 +126,12 @@
//
// We need to do this in two passes because when creating
// a container for a repeating annotation we must
- // guarantee that the @ContainedBy on the
+ // guarantee that the @Repeatable on the
// contained annotation is fully annotated
//
// The way we force this order is to do all repeating
// annotations in a pass after all non-repeating are
- // finished. This will work because @ContainedBy
+ // finished. This will work because @Repeatable
// is non-repeating and therefore will be annotated in the
// fist pass.
@@ -261,7 +261,7 @@
// its contained annotation.
ListBuffer<Attribute.Compound> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
if (manualContainer != null) {
- log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present",
+ log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
manualContainer.first().type.tsym);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, 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
@@ -450,7 +450,7 @@
* This is the implementation for {@code
* javax.lang.model.element.Element.getAnnotationMirrors()}.
*/
- public final List<Attribute.Compound> getAnnotationMirrors() {
+ public final List<? extends AnnotationMirror> getAnnotationMirrors() {
return getRawAttributes();
}
@@ -462,6 +462,11 @@
return JavacElements.getAnnotation(this, annoType);
}
+ // This method is part of the javax.lang.model API, do not use this in javac code.
+ public <A extends java.lang.annotation.Annotation> A[] getAnnotations(Class<A> annoType) {
+ return JavacElements.getAnnotations(this, annoType);
+ }
+
// TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
public java.util.List<Symbol> getEnclosedElements() {
return List.nil();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, 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
@@ -161,10 +161,10 @@
public final Type autoCloseableType;
public final Type trustMeType;
public final Type lambdaMetafactory;
- public final Type containedByType;
- public final Type containerForType;
+ public final Type repeatableType;
public final Type documentedType;
public final Type elementTypeType;
+ public final Type functionalInterfaceType;
/** The symbol representing the length field of an array.
*/
@@ -494,8 +494,7 @@
deprecatedType = enterClass("java.lang.Deprecated");
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
inheritedType = enterClass("java.lang.annotation.Inherited");
- containedByType = enterClass("java.lang.annotation.ContainedBy");
- containerForType = enterClass("java.lang.annotation.ContainerFor");
+ repeatableType = enterClass("java.lang.annotation.Repeatable");
documentedType = enterClass("java.lang.annotation.Documented");
elementTypeType = enterClass("java.lang.annotation.ElementType");
systemType = enterClass("java.lang.System");
@@ -509,6 +508,7 @@
nativeHeaderType = enterClass("java.lang.annotation.Native");
nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader");
lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
+ functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
synthesizeEmptyInterfaceIfMissing(autoCloseableType);
synthesizeEmptyInterfaceIfMissing(cloneableType);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Sun Jan 20 23:39:11 2013 -0800
@@ -392,9 +392,9 @@
* Compute the function descriptor associated with a given functional interface
*/
public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError {
- if (!origin.isInterface()) {
+ if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) {
//t must be an interface
- throw failure("not.a.functional.intf");
+ throw failure("not.a.functional.intf", origin);
}
final ListBuffer<Symbol> abstracts = ListBuffer.lb();
@@ -406,13 +406,13 @@
abstracts.append(sym);
} else {
//the target method(s) should be the only abstract members of t
- throw failure("not.a.functional.intf.1",
+ throw failure("not.a.functional.intf.1", origin,
diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin));
}
}
if (abstracts.isEmpty()) {
//t must define a suitable non-generic method
- throw failure("not.a.functional.intf.1",
+ throw failure("not.a.functional.intf.1", origin,
diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
} else if (abstracts.size() == 1) {
return new FunctionDescriptor(abstracts.first());
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -392,7 +392,7 @@
List.of(p)));
if (!chk.annotationApplicable(annoTree, on))
- log.error(annoTree.pos(), "invalid.containedby.annotation.incompatible.target", targetContainerType, origAnnoType);
+ log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
if (!chk.validateAnnotationDeferErrors(annoTree))
log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
@@ -414,11 +414,11 @@
Type origAnnoType = currentAnno.type;
TypeSymbol origAnnoDecl = origAnnoType.tsym;
- // Fetch the ContainedBy annotation from the current
+ // Fetch the Repeatable annotation from the current
// annotation's declaration, or null if it has none
- Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym);
- if (ca == null) { // has no ContainedBy annotation
- log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.containedByType);
+ Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym);
+ if (ca == null) { // has no Repeatable annotation
+ log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
return null;
}
@@ -440,23 +440,23 @@
DiagnosticPosition pos,
TypeSymbol annoDecl)
{
- // The next three checks check that the ContainedBy annotation
+ // The next three checks check that the Repeatable annotation
// on the declaration of the annotation type that is repeating is
// valid.
- // ContainedBy must have at least one element
+ // Repeatable must have at least one element
if (ca.values.isEmpty()) {
- log.error(pos, "invalid.containedby.annotation", annoDecl);
+ log.error(pos, "invalid.repeatable.annotation", annoDecl);
return null;
}
Pair<MethodSymbol,Attribute> p = ca.values.head;
Name name = p.fst.name;
if (name != names.value) { // should contain only one element, named "value"
- log.error(pos, "invalid.containedby.annotation", annoDecl);
+ log.error(pos, "invalid.repeatable.annotation", annoDecl);
return null;
}
if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
- log.error(pos, "invalid.containedby.annotation", annoDecl);
+ log.error(pos, "invalid.repeatable.annotation", annoDecl);
return null;
}
@@ -491,13 +491,13 @@
}
if (error) {
log.error(pos,
- "invalid.containedby.annotation.multiple.values",
+ "invalid.repeatable.annotation.multiple.values",
targetContainerType,
nr_value_elems);
return null;
} else if (nr_value_elems == 0) {
log.error(pos,
- "invalid.containedby.annotation.no.value",
+ "invalid.repeatable.annotation.no.value",
targetContainerType);
return null;
}
@@ -506,7 +506,7 @@
// probably "impossible" to fail this
if (containerValueSymbol.kind != Kinds.MTH) {
log.error(pos,
- "invalid.containedby.annotation.invalid.value",
+ "invalid.repeatable.annotation.invalid.value",
targetContainerType);
fatalError = true;
}
@@ -518,7 +518,7 @@
if (!(types.isArray(valueRetType) &&
types.isSameType(expectedType, valueRetType))) {
log.error(pos,
- "invalid.containedby.annotation.value.return",
+ "invalid.repeatable.annotation.value.return",
targetContainerType,
valueRetType,
expectedType);
@@ -528,10 +528,7 @@
fatalError = true;
}
- // Explicitly no check for/validity of @ContainerFor. That is
- // done on declaration of the container, and at reflect time.
-
- // The rest of the conditions for a valid containing annotation are made
+ // The conditions for a valid containing annotation are made
// in Check.validateRepeatedAnnotaton();
return fatalError ? null : containerValueSymbol;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, 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
@@ -3844,24 +3844,14 @@
log.error(tree.typarams.head.pos(),
"intf.annotation.cant.have.type.params");
- // If this annotation has a @ContainedBy, validate
- Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym);
- if (containedBy != null) {
- // get diagnositc position for error reporting
- DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type);
+ // If this annotation has a @Repeatable, validate
+ Attribute.Compound repeatable = c.attribute(syms.repeatableType.tsym);
+ if (repeatable != null) {
+ // get diagnostic position for error reporting
+ DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type);
Assert.checkNonNull(cbPos);
- chk.validateContainedBy(c, containedBy, cbPos);
- }
-
- // If this annotation has a @ContainerFor, validate
- Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym);
- if (containerFor != null) {
- // get diagnositc position for error reporting
- DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type);
- Assert.checkNonNull(cfPos);
-
- chk.validateContainerFor(c, containerFor, cfPos);
+ chk.validateRepeatable(c, repeatable, cbPos);
}
} else {
// Check that all extended classes and interfaces
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, 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
@@ -634,25 +634,40 @@
}
}
+ Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
+ if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
+ return typeTagError(pos,
+ diags.fragment("type.req.class.array"),
+ asTypeParam(t));
+ } else {
+ return t;
+ }
+ }
+
/** Check that type is a class or interface type.
* @param pos Position to be used for error reporting.
* @param t The type to be checked.
*/
Type checkClassType(DiagnosticPosition pos, Type t) {
- if (!t.hasTag(CLASS) && !t.hasTag(ERROR))
+ if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
return typeTagError(pos,
diags.fragment("type.req.class"),
- (t.hasTag(TYPEVAR))
- ? diags.fragment("type.parameter", t)
- : t);
- else
+ asTypeParam(t));
+ } else {
return t;
+ }
}
+ //where
+ private Object asTypeParam(Type t) {
+ return (t.hasTag(TYPEVAR))
+ ? diags.fragment("type.parameter", t)
+ : t;
+ }
/** Check that type is a valid qualifier for a constructor reference expression
*/
Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
- t = checkClassType(pos, t);
+ t = checkClassOrArrayType(pos, t);
if (t.hasTag(CLASS)) {
if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
log.error(pos, "abstract.cant.be.instantiated");
@@ -690,11 +705,8 @@
* @param t The type to be checked.
*/
Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
- if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
- return typeTagError(pos,
- diags.fragment("type.req.class.array"),
- t);
- } else if (!types.isReifiable(t)) {
+ t = checkClassOrArrayType(pos, t);
+ if (!t.isErroneous() && !types.isReifiable(t)) {
log.error(pos, "illegal.generic.type.for.instof");
return types.createErrorType(t);
} else {
@@ -2589,33 +2601,45 @@
if (!isOverrider(s))
log.error(a.pos(), "method.does.not.override.superclass");
}
+
+ if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
+ if (s.kind != TYP) {
+ log.error(a.pos(), "bad.functional.intf.anno");
+ } else {
+ try {
+ types.findDescriptorSymbol((TypeSymbol)s);
+ } catch (Types.FunctionDescriptorLookupError ex) {
+ log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
+ }
+ }
+ }
}
/**
- * Validate the proposed container 'containedBy' on the
+ * Validate the proposed container 'repeatable' on the
* annotation type symbol 's'. Report errors at position
* 'pos'.
*
- * @param s The (annotation)type declaration annotated with a @ContainedBy
- * @param containedBy the @ContainedBy on 's'
+ * @param s The (annotation)type declaration annotated with a @Repeatable
+ * @param repeatable the @Repeatable on 's'
* @param pos where to report errors
*/
- public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
- Assert.check(types.isSameType(containedBy.type, syms.containedByType));
+ public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
+ Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+ List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
if (!l.isEmpty()) {
Assert.check(l.head.fst.name == names.value);
t = ((Attribute.Class)l.head.snd).getValue();
}
if (t == null) {
- log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
+ // errors should already have been reported during Annotate
return;
}
- validateHasContainerFor(t.tsym, s, pos);
+ validateValue(t.tsym, s, pos);
validateRetention(t.tsym, s, pos);
validateDocumented(t.tsym, s, pos);
validateInherited(t.tsym, s, pos);
@@ -2623,79 +2647,18 @@
validateDefault(t.tsym, s, pos);
}
- /**
- * Validate the proposed container 'containerFor' on the
- * annotation type symbol 's'. Report errors at position
- * 'pos'.
- *
- * @param s The (annotation)type declaration annotated with a @ContainerFor
- * @param containerFor the @ContainedFor on 's'
- * @param pos where to report errors
- */
- public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
- Assert.check(types.isSameType(containerFor.type, syms.containerForType));
-
- Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
- if (!l.isEmpty()) {
- Assert.check(l.head.fst.name == names.value);
- t = ((Attribute.Class)l.head.snd).getValue();
- }
-
- if (t == null) {
- log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
- return;
- }
-
- validateHasContainedBy(t.tsym, s, pos);
- }
-
- private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
- Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
-
- if (containedBy == null) {
- log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
- return;
+ private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+ Scope.Entry e = container.members().lookup(names.value);
+ if (e.scope != null && e.sym.kind == MTH) {
+ MethodSymbol m = (MethodSymbol) e.sym;
+ Type ret = m.getReturnType();
+ if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
+ log.error(pos, "invalid.repeatable.annotation.value.return",
+ container, ret, types.makeArrayType(contained.type));
+ }
+ } else {
+ log.error(pos, "invalid.repeatable.annotation.no.value", container);
}
-
- Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
- if (!l.isEmpty()) {
- Assert.check(l.head.fst.name == names.value);
- t = ((Attribute.Class)l.head.snd).getValue();
- }
-
- if (t == null) {
- log.error(pos, "invalid.container.wrong.containedby", container, contained);
- return;
- }
-
- if (!types.isSameType(t, contained.type))
- log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
- }
-
- private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
- Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
-
- if (containerFor == null) {
- log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
- return;
- }
-
- Type t = null;
- List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
- if (!l.isEmpty()) {
- Assert.check(l.head.fst.name == names.value);
- t = ((Attribute.Class)l.head.snd).getValue();
- }
-
- if (t == null) {
- log.error(pos, "invalid.container.wrong.containerfor", container, contained);
- return;
- }
-
- if (!types.isSameType(t, contained.type))
- log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
}
private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
@@ -2715,7 +2678,7 @@
}
}
if (error ) {
- log.error(pos, "invalid.containedby.annotation.retention",
+ log.error(pos, "invalid.repeatable.annotation.retention",
container, containerRetention,
contained, containedRetention);
}
@@ -2724,7 +2687,7 @@
private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
if (contained.attribute(syms.documentedType.tsym) != null) {
if (container.attribute(syms.documentedType.tsym) == null) {
- log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
}
}
}
@@ -2732,7 +2695,7 @@
private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
if (contained.attribute(syms.inheritedType.tsym) != null) {
if (container.attribute(syms.inheritedType.tsym) == null) {
- log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
}
}
}
@@ -2752,7 +2715,7 @@
// contained has target, but container has not, error
Attribute.Array containerTarget = getAttributeTargetAttribute(container);
if (containerTarget == null) {
- log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
return;
}
@@ -2775,7 +2738,7 @@
}
if (!isTargetSubset(containedTargets, containerTargets)) {
- log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
}
}
@@ -2809,7 +2772,7 @@
elm.kind == Kinds.MTH &&
((MethodSymbol)elm).defaultValue == null) {
log.error(pos,
- "invalid.containedby.annotation.elem.nondefault",
+ "invalid.repeatable.annotation.elem.nondefault",
container,
elm);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, 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
@@ -131,7 +131,11 @@
predefClassDef = make.ClassDef(
make.Modifiers(PUBLIC),
- syms.predefClass.name, null, null, null, null);
+ syms.predefClass.name,
+ List.<JCTypeParameter>nil(),
+ null,
+ List.<JCExpression>nil(),
+ List.<JCTree>nil());
predefClassDef.sym = syms.predefClass;
todo = Todo.instance(context);
fileManager = context.get(JavaFileManager.class);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Sun Jan 20 23:39:11 2013 -0800
@@ -302,6 +302,7 @@
case UNBOUND: /** Type :: instMethod */
case STATIC: /** Type :: staticMethod */
case TOPLEVEL: /** Top level :: new */
+ case ARRAY_CTOR: /** ArrayType :: new */
init = null;
break;
@@ -645,24 +646,33 @@
* to the first bridge synthetic parameter
*/
private JCExpression bridgeExpressionNew() {
- JCExpression encl = null;
- switch (tree.kind) {
- case UNBOUND:
- case IMPLICIT_INNER:
- encl = make.Ident(params.first());
- }
+ if (tree.kind == ReferenceKind.ARRAY_CTOR) {
+ //create the array creation expression
+ JCNewArray newArr = make.NewArray(make.Type(types.elemtype(tree.getQualifierExpression().type)),
+ List.of(make.Ident(params.first())),
+ null);
+ newArr.type = tree.getQualifierExpression().type;
+ return newArr;
+ } else {
+ JCExpression encl = null;
+ switch (tree.kind) {
+ case UNBOUND:
+ case IMPLICIT_INNER:
+ encl = make.Ident(params.first());
+ }
- //create the instance creation expression
- JCNewClass newClass = make.NewClass(encl,
- List.<JCExpression>nil(),
- make.Type(tree.getQualifierExpression().type),
- convertArgs(tree.sym, args.toList(), tree.varargsElement),
- null);
- newClass.constructor = tree.sym;
- newClass.constructorType = tree.sym.erasure(types);
- newClass.type = tree.getQualifierExpression().type;
- setVarargsIfNeeded(newClass, tree.varargsElement);
- return newClass;
+ //create the instance creation expression
+ JCNewClass newClass = make.NewClass(encl,
+ List.<JCExpression>nil(),
+ make.Type(tree.getQualifierExpression().type),
+ convertArgs(tree.sym, args.toList(), tree.varargsElement),
+ null);
+ newClass.constructor = tree.sym;
+ newClass.constructorType = tree.sym.erasure(types);
+ newClass.type = tree.getQualifierExpression().type;
+ setVarargsIfNeeded(newClass, tree.varargsElement);
+ return newClass;
+ }
}
private VarSymbol addParameter(String name, Type p, boolean genArg) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sun Jan 20 23:39:11 2013 -0800
@@ -2386,10 +2386,23 @@
List<Type> typeargtypes,
boolean boxingAllowed) {
MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
+
+ ReferenceLookupHelper boundLookupHelper;
+ if (!name.equals(names.init)) {
+ //method reference
+ boundLookupHelper =
+ new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ } else if (site.hasTag(ARRAY)) {
+ //array constructor reference
+ boundLookupHelper =
+ new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
+ } else {
+ //class constructor reference
+ boundLookupHelper =
+ new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
+ }
+
//step 1 - bound lookup
- ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
- new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase) :
- new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper);
@@ -2627,6 +2640,33 @@
}
/**
+ * Helper class for array constructor lookup; an array constructor lookup
+ * is simulated by looking up a method that returns the array type specified
+ * as qualifier, and that accepts a single int parameter (size of the array).
+ */
+ class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
+
+ ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
+ List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
+ }
+
+ @Override
+ protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ Scope sc = new Scope(syms.arrayClass);
+ MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
+ arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass);
+ sc.enter(arrayConstr);
+ return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ return ReferenceKind.ARRAY_CTOR;
+ }
+ }
+
+ /**
* Helper class for constructor reference lookup. The lookup logic is based
* upon either Resolve.findMethod or Resolve.findDiamond - depending on
* whether the constructor reference needs diamond inference (this is the case
@@ -3381,7 +3421,10 @@
@Override
protected Symbol access(Name name, TypeSymbol location) {
- return ambiguousSyms.last();
+ Symbol firstAmbiguity = ambiguousSyms.last();
+ return firstAmbiguity.kind == TYP ?
+ types.createErrorType(name, location, firstAmbiguity.type).tsym :
+ firstAmbiguity;
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -27,6 +27,8 @@
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.Map;
import javax.lang.model.SourceVersion;
@@ -96,32 +98,43 @@
enter = Enter.instance(context);
}
-
/**
- * An internal-use utility that creates a reified annotation.
+ * An internal-use utility that creates a runtime view of an
+ * annotation. This is the implementation of
+ * Element.getAnnotation(Class).
*/
public static <A extends Annotation> A getAnnotation(Symbol annotated,
Class<A> annoType) {
if (!annoType.isAnnotation())
throw new IllegalArgumentException("Not an annotation type: "
+ annoType);
- String name = annoType.getName();
- for (Attribute.Compound anno : annotated.getAnnotationMirrors())
- if (name.equals(anno.type.tsym.flatName().toString()))
- return AnnotationProxyMaker.generateAnnotation(anno, annoType);
- return null;
+ Attribute.Compound c;
+ if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
+ c = getAttributeOnClass((ClassSymbol)annotated, annoType);
+ } else {
+ c = getAttribute(annotated, annoType);
+ }
+ return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
}
- /**
- * An internal-use utility that creates a reified annotation.
- * This overloaded version take annotation inheritance into account.
- */
- public static <A extends Annotation> A getAnnotation(ClassSymbol annotated,
- Class<A> annoType) {
+ // Helper to getAnnotation[s]
+ private static <A extends Annotation> Attribute.Compound getAttribute(Symbol annotated,
+ Class<A> annoType) {
+ String name = annoType.getName();
+
+ for (Attribute.Compound anno : annotated.getRawAttributes())
+ if (name.equals(anno.type.tsym.flatName().toString()))
+ return anno;
+
+ return null;
+ }
+ // Helper to getAnnotation[s]
+ private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated,
+ Class<A> annoType) {
boolean inherited = annoType.isAnnotationPresent(Inherited.class);
- A result = null;
+ Attribute.Compound result = null;
while (annotated.name != annotated.name.table.names.java_lang_Object) {
- result = getAnnotation((Symbol)annotated, annoType);
+ result = getAttribute(annotated, annoType);
if (result != null || !inherited)
break;
Type sup = annotated.getSuperclass();
@@ -132,6 +145,189 @@
return result;
}
+ /**
+ * An internal-use utility that creates a runtime view of
+ * annotations. This is the implementation of
+ * Element.getAnnotations(Class).
+ */
+ public static <A extends Annotation> A[] getAnnotations(Symbol annotated,
+ Class<A> annoType) {
+ if (!annoType.isAnnotation())
+ throw new IllegalArgumentException("Not an annotation type: "
+ + annoType);
+ // If annoType does not declare a container this is equivalent to wrapping
+ // getAnnotation(...) in an array.
+ Class <? extends Annotation> containerType = getContainer(annoType);
+ if (containerType == null) {
+ A res = getAnnotation(annotated, annoType);
+ int size;
+ if (res == null) {
+ size = 0;
+ } else {
+ size = 1;
+ }
+ @SuppressWarnings("unchecked") // annoType is the Class for A
+ A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
+ if (res != null)
+ arr[0] = res;
+ return arr;
+ }
+
+ // So we have a containing type
+ String name = annoType.getName();
+ String annoTypeName = annoType.getSimpleName();
+ String containerTypeName = containerType.getSimpleName();
+ int directIndex = -1, containerIndex = -1;
+ Attribute.Compound direct = null, container = null;
+ Attribute.Compound[] rawAttributes = annotated.getRawAttributes().toArray(new Attribute.Compound[0]);
+
+ // Find directly present annotations
+ for (int i = 0; i < rawAttributes.length; i++) {
+ if (annoTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
+ directIndex = i;
+ direct = rawAttributes[i];
+ } else if(containerTypeName != null &&
+ containerTypeName.equals(rawAttributes[i].type.tsym.flatName().toString())) {
+ containerIndex = i;
+ container = rawAttributes[i];
+ }
+ }
+ // Deal with inherited annotations
+ if (annotated.kind == Kinds.TYP &&
+ (annotated instanceof ClassSymbol)) {
+ ClassSymbol s = (ClassSymbol)annotated;
+ if (direct == null && container == null) {
+ direct = getAttributeOnClass(s, annoType);
+ container = getAttributeOnClass(s, containerType);
+
+ // both are inherited and found, put container last
+ if (direct != null && container != null) {
+ directIndex = 0;
+ containerIndex = 1;
+ } else if (direct != null) {
+ directIndex = 0;
+ } else {
+ containerIndex = 0;
+ }
+ } else if (direct == null) {
+ direct = getAttributeOnClass(s, annoType);
+ if (direct != null)
+ directIndex = containerIndex + 1;
+ } else if (container == null) {
+ container = getAttributeOnClass(s, containerType);
+ if (container != null)
+ containerIndex = directIndex + 1;
+ }
+ }
+
+ // Pack them in an array
+ Attribute[] contained0 = new Attribute[0];
+ if (container != null)
+ contained0 = unpackAttributes(container);
+ ListBuffer<Attribute.Compound> compounds = ListBuffer.lb();
+ for (Attribute a : contained0)
+ if (a instanceof Attribute.Compound)
+ compounds = compounds.append((Attribute.Compound)a);
+ Attribute.Compound[] contained = compounds.toArray(new Attribute.Compound[0]);
+
+ int size = (direct == null ? 0 : 1) + contained.length;
+ @SuppressWarnings("unchecked") // annoType is the Class for A
+ A[] arr = (A[])java.lang.reflect.Array.newInstance(annoType, size);
+
+ // if direct && container, which is first?
+ int insert = -1;
+ int length = arr.length;
+ if (directIndex >= 0 && containerIndex >= 0) {
+ if (directIndex < containerIndex) {
+ arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+ insert = 1;
+ } else {
+ arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+ insert = 0;
+ length--;
+ }
+ } else if (directIndex >= 0) {
+ arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
+ return arr;
+ } else {
+ // Only container
+ insert = 0;
+ }
+
+ for (int i = 0; i + insert < length; i++)
+ arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);
+
+ return arr;
+ }
+
+ // Needed to unpack the runtime view of containing annotations
+ private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
+ private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
+
+ private static Class<? extends Annotation> initRepeatable() {
+ try {
+ // Repeatable will not be available when bootstrapping on
+ // JDK 7 so use a reflective lookup instead of a class
+ // literal for Repeatable.class.
+ return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
+ } catch (ClassNotFoundException e) {
+ return null;
+ } catch (SecurityException e) {
+ return null;
+ }
+ }
+ private static Method initValueElementMethod() {
+ if (REPEATABLE_CLASS == null)
+ return null;
+
+ Method m = null;
+ try {
+ m = REPEATABLE_CLASS.getMethod("value");
+ if (m != null)
+ m.setAccessible(true);
+ return m;
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ // Helper to getAnnotations
+ private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
+ // Since we can not refer to java.lang.annotation.Repeatable until we are
+ // bootstrapping with java 8 we need to get the Repeatable annotation using
+ // reflective invocations instead of just using its type and element method.
+ if (REPEATABLE_CLASS != null &&
+ VALUE_ELEMENT_METHOD != null) {
+ // Get the Repeatable instance on the annotations declaration
+ Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
+ if (repeatable != null) {
+ try {
+ // Get the value element, it should be a class
+ // indicating the containing annotation type
+ @SuppressWarnings("unchecked")
+ Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
+ if (containerType == null)
+ return null;
+
+ return containerType;
+ } catch (ClassCastException e) {
+ return null;
+ } catch (IllegalAccessException e) {
+ return null;
+ } catch (InvocationTargetException e ) {
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+ // Helper to getAnnotations
+ private static Attribute[] unpackAttributes(Attribute.Compound container) {
+ // We now have an instance of the container,
+ // unpack it returning an instance of the
+ // contained type or null
+ return ((Attribute.Array)container.member(container.type.tsym.name.table.names.value)).values;
+ }
public PackageSymbol getPackageElement(CharSequence name) {
String strName = name.toString();
@@ -238,8 +434,10 @@
tree.accept(vis);
if (vis.result == null)
return null;
+
+ List<Attribute.Compound> annos = sym.getRawAttributes();
return matchAnnoToTree(cast(Attribute.Compound.class, findme),
- sym.getAnnotationMirrors(),
+ annos,
vis.result);
}
@@ -442,7 +640,7 @@
*/
public List<Attribute.Compound> getAllAnnotationMirrors(Element e) {
Symbol sym = cast(Symbol.class, e);
- List<Attribute.Compound> annos = sym.getAnnotationMirrors();
+ List<Attribute.Compound> annos = sym.getRawAttributes();
while (sym.getKind() == ElementKind.CLASS) {
Type sup = ((ClassSymbol) sym).getSuperclass();
if (!sup.hasTag(CLASS) || sup.isErroneous() ||
@@ -451,7 +649,8 @@
}
sym = sup.tsym;
List<Attribute.Compound> oldAnnos = annos;
- for (Attribute.Compound anno : sym.getAnnotationMirrors()) {
+ List<Attribute.Compound> newAnnos = sym.getRawAttributes();
+ for (Attribute.Compound anno : newAnnos) {
if (isInherited(anno.type) &&
!containsAnnoOfType(oldAnnos, anno.type)) {
annos = annos.prepend(anno);
@@ -465,11 +664,7 @@
* Tests whether an annotation type is @Inherited.
*/
private boolean isInherited(Type annotype) {
- for (Attribute.Compound anno : annotype.tsym.getAnnotationMirrors()) {
- if (anno.type.tsym == syms.inheritedType.tsym)
- return true;
- }
- return false;
+ return annotype.tsym.attribute(syms.inheritedType.tsym) != null;
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Sun Jan 20 23:39:11 2013 -0800
@@ -245,40 +245,42 @@
token = S.token();
}
- protected boolean peekToken(TokenKind tk) {
+ protected boolean peekToken(Filter<TokenKind> tk) {
return peekToken(0, tk);
}
- protected boolean peekToken(int lookahead, TokenKind tk) {
- return S.token(lookahead + 1).kind == tk;
+ protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
+ return tk.accepts(S.token(lookahead + 1).kind);
}
- protected boolean peekToken(TokenKind tk1, TokenKind tk2) {
+ protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
return peekToken(0, tk1, tk2);
}
- protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2) {
- return S.token(lookahead + 1).kind == tk1 &&
- S.token(lookahead + 2).kind == tk2;
+ protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
+ return tk1.accepts(S.token(lookahead + 1).kind) &&
+ tk2.accepts(S.token(lookahead + 2).kind);
}
- protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) {
+ protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
return peekToken(0, tk1, tk2, tk3);
}
- protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2, TokenKind tk3) {
- return S.token(lookahead + 1).kind == tk1 &&
- S.token(lookahead + 2).kind == tk2 &&
- S.token(lookahead + 3).kind == tk3;
+ protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
+ return tk1.accepts(S.token(lookahead + 1).kind) &&
+ tk2.accepts(S.token(lookahead + 2).kind) &&
+ tk3.accepts(S.token(lookahead + 3).kind);
}
- protected boolean peekToken(TokenKind... kinds) {
+ @SuppressWarnings("unchecked")
+ protected boolean peekToken(Filter<TokenKind>... kinds) {
return peekToken(0, kinds);
}
- protected boolean peekToken(int lookahead, TokenKind... kinds) {
+ @SuppressWarnings("unchecked")
+ protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
for (; lookahead < kinds.length ; lookahead++) {
- if (S.token(lookahead + 1).kind != kinds[lookahead]) {
+ if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
return false;
}
}
@@ -333,6 +335,7 @@
if (stopAtMemberDecl)
return;
break;
+ case UNDERSCORE:
case IDENTIFIER:
if (stopAtIdentifier)
return;
@@ -552,11 +555,16 @@
nextToken();
return name;
}
+ } else if (token.kind == UNDERSCORE) {
+ warning(token.pos, "underscore.as.identifier");
+ Name name = token.name();
+ nextToken();
+ return name;
} else {
accept(IDENTIFIER);
return names.error;
}
-}
+ }
/**
* Qualident = Ident { DOT Ident }
@@ -1056,7 +1064,7 @@
typeArgs = null;
} else return illegal();
break;
- case IDENTIFIER: case ASSERT: case ENUM:
+ case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
if (typeArgs != null) return illegal();
if ((mode & EXPR) != 0 && peekToken(ARROW)) {
t = lambdaExpressionOrStatement(false, false, pos);
@@ -1274,7 +1282,7 @@
int pos = 0, depth = 0;
for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
switch (t.kind) {
- case IDENTIFIER: case QUES: case EXTENDS: case SUPER:
+ case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
case DOT: case RBRACKET: case LBRACKET: case COMMA:
case BYTE: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case BOOLEAN: case CHAR:
@@ -1323,8 +1331,8 @@
if (peekToken(lookahead, RPAREN)) {
//Type, ')' -> cast
return ParensResult.CAST;
- } else if (peekToken(lookahead, IDENTIFIER)) {
- //Type, 'Identifier -> explicit lambda
+ } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
+ //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
}
break;
@@ -1350,16 +1358,19 @@
case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
case TRUE: case FALSE: case NULL:
- case NEW: case IDENTIFIER: case ASSERT: case ENUM:
+ case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
case BYTE: case SHORT: case CHAR: case INT:
case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
return ParensResult.CAST;
default:
return ParensResult.PARENS;
}
+ case UNDERSCORE:
+ case ASSERT:
+ case ENUM:
case IDENTIFIER:
- if (peekToken(lookahead, IDENTIFIER)) {
- // Identifier, Identifier -> explicit lambda
+ if (peekToken(lookahead, LAX_IDENTIFIER)) {
+ // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
} else if (peekToken(lookahead, RPAREN, ARROW)) {
// Identifier, ')' '->' -> implicit lambda
@@ -1372,8 +1383,8 @@
//those can only appear in explicit lambdas
return ParensResult.EXPLICIT_LAMBDA;
case LBRACKET:
- if (peekToken(lookahead, RBRACKET, IDENTIFIER)) {
- // '[', ']', Identifier -> explicit lambda
+ if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
+ // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
} else if (peekToken(lookahead, RBRACKET, RPAREN) ||
peekToken(lookahead, RBRACKET, AMP)) {
@@ -1402,11 +1413,11 @@
// '>', ')' -> cast
// '>', '&' -> cast
return ParensResult.CAST;
- } else if (peekToken(lookahead, IDENTIFIER, COMMA) ||
- peekToken(lookahead, IDENTIFIER, RPAREN, ARROW) ||
+ } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
+ peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
peekToken(lookahead, ELLIPSIS)) {
- // '>', Identifier, ',' -> explicit lambda
- // '>', Identifier, ')', '->' -> explicit lambda
+ // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
+ // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
// '>', '...' -> explicit lambda
return ParensResult.EXPLICIT_LAMBDA;
}
@@ -1426,6 +1437,13 @@
}
}
+ /** Accepts all identifier-like tokens */
+ Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
+ public boolean accepts(TokenKind t) {
+ return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
+ }
+ };
+
enum ParensResult {
CAST,
EXPLICIT_LAMBDA,
@@ -1433,21 +1451,9 @@
PARENS;
}
- JCExpression lambdaExpressionOrStatement(JCVariableDecl firstParam, int pos) {
- ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
- params.append(firstParam);
- JCVariableDecl lastParam = firstParam;
- while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
- nextToken();
- params.append(lastParam = formalParameter());
- }
- accept(RPAREN);
- return lambdaExpressionOrStatementRest(params.toList(), pos);
- }
-
JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
List<JCVariableDecl> params = explicitParams ?
- formalParameters() :
+ formalParameters(true) :
implicitParameters(hasParens);
return lambdaExpressionOrStatementRest(params, pos);
@@ -1628,7 +1634,7 @@
nextToken();
JCExpression bound = parseType();
return F.at(pos).Wildcard(t, bound);
- } else if (token.kind == IDENTIFIER) {
+ } else if (LAX_IDENTIFIER.accepts(token.kind)) {
//error recovery
TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
JCExpression wc = toP(F.at(pos).Wildcard(t, null));
@@ -1678,7 +1684,7 @@
if (token.pos == endPosTable.errorEndPos) {
// error recovery
Name name = null;
- if (token.kind == IDENTIFIER) {
+ if (LAX_IDENTIFIER.accepts(token.kind)) {
name = token.name();
nextToken();
} else {
@@ -2026,10 +2032,7 @@
nextToken();
JCStatement stat = parseStatement();
return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
- } else if ((lastmode & TYPE) != 0 &&
- (token.kind == IDENTIFIER ||
- token.kind == ASSERT ||
- token.kind == ENUM)) {
+ } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
pos = token.pos;
JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
F.at(pos);
@@ -2183,14 +2186,14 @@
}
case BREAK: {
nextToken();
- Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
+ Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
JCBreak t = to(F.at(pos).Break(label));
accept(SEMI);
return t;
}
case CONTINUE: {
nextToken();
- Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null;
+ Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
JCContinue t = to(F.at(pos).Continue(label));
accept(SEMI);
return t;
@@ -2351,9 +2354,7 @@
return variableDeclarators(optFinal(0), parseType(), stats).toList();
} else {
JCExpression t = term(EXPR | TYPE);
- if ((lastmode & TYPE) != 0 &&
- (token.kind == IDENTIFIER || token.kind == ASSERT ||
- token.kind == ENUM)) {
+ if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
return variableDeclarators(modifiersOpt(), t, stats).toList();
} else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
error(pos, "bad.initializer", "for-loop");
@@ -2609,8 +2610,18 @@
/** VariableDeclaratorId = Ident BracketsOpt
*/
JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
+ return variableDeclaratorId(mods, type, false);
+ }
+ //where
+ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
int pos = token.pos;
- Name name = ident();
+ Name name;
+ if (lambdaParameter && token.kind == UNDERSCORE) {
+ syntaxError(pos, "expected", IDENTIFIER);
+ name = token.name();
+ } else {
+ name = ident();
+ }
if ((mods.flags & Flags.VARARGS) != 0 &&
token.kind == LBRACKET) {
log.error(token.pos, "varargs.and.old.array.syntax");
@@ -2770,7 +2781,7 @@
} else {
int pos = token.pos;
List<JCTree> errs;
- if (token.kind == IDENTIFIER) {
+ if (LAX_IDENTIFIER.accepts(token.kind)) {
errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
setErrorEndPos(token.pos);
} else {
@@ -2787,7 +2798,7 @@
}
int pos = token.pos;
List<JCTree> errs;
- if (token.kind == IDENTIFIER) {
+ if (LAX_IDENTIFIER.accepts(token.kind)) {
errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
setErrorEndPos(token.pos);
} else {
@@ -3182,14 +3193,17 @@
* FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
*/
List<JCVariableDecl> formalParameters() {
+ return formalParameters(false);
+ }
+ List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
JCVariableDecl lastParam = null;
accept(LPAREN);
if (token.kind != RPAREN) {
- params.append(lastParam = formalParameter());
+ params.append(lastParam = formalParameter(lambdaParameters));
while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
nextToken();
- params.append(lastParam = formalParameter());
+ params.append(lastParam = formalParameter(lambdaParameters));
}
}
accept(RPAREN);
@@ -3225,6 +3239,9 @@
* LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
*/
protected JCVariableDecl formalParameter() {
+ return formalParameter(false);
+ }
+ protected JCVariableDecl formalParameter(boolean lambdaParameter) {
JCModifiers mods = optFinal(Flags.PARAMETER);
JCExpression type = parseType();
if (token.kind == ELLIPSIS) {
@@ -3233,12 +3250,12 @@
type = to(F.at(token.pos).TypeArray(type));
nextToken();
}
- return variableDeclaratorId(mods, type);
+ return variableDeclaratorId(mods, type, lambdaParameter);
}
protected JCVariableDecl implicitParameter() {
JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
- return variableDeclaratorId(mods, null);
+ return variableDeclaratorId(mods, null, true);
}
/* ---------- auxiliary methods -------------- */
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java Sun Jan 20 23:39:11 2013 -0800
@@ -33,6 +33,7 @@
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Filter;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Names;
@@ -74,7 +75,6 @@
protected Tokens(Context context) {
context.put(tokensKey, this);
names = Names.instance(context);
-
for (TokenKind t : TokenKind.values()) {
if (t.name != null)
enterKeyword(t.name, t);
@@ -113,7 +113,7 @@
* This enum defines all tokens used by the javac scanner. A token is
* optionally associated with a name.
*/
- public enum TokenKind implements Formattable {
+ public enum TokenKind implements Formattable, Filter<TokenKind> {
EOF(),
ERROR(),
IDENTIFIER(Tag.NAMED),
@@ -176,6 +176,7 @@
TRUE("true", Tag.NAMED),
FALSE("false", Tag.NAMED),
NULL("null", Tag.NAMED),
+ UNDERSCORE("_", Tag.NAMED),
ARROW("->"),
COLCOL("::"),
LPAREN("("),
@@ -283,6 +284,11 @@
public String toString(Locale locale, Messages messages) {
return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
}
+
+ @Override
+ public boolean accepts(TokenKind that) {
+ return this == that;
+ }
}
public interface Comment {
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, 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
@@ -178,13 +178,22 @@
compiler.misc.incompatible.abstracts=\
multiple non-overriding abstract methods found in {0} {1}
-compiler.misc.not.a.functional.intf=\
- the target type must be a functional interface
+compiler.err.bad.functional.intf.anno=\
+ Unexpected @FunctionalInterface annotation
# 0: message segment
+compiler.err.bad.functional.intf.anno.1=\
+ Unexpected @FunctionalInterface annotation\n\
+ {0}
+
+# 0: symbol
+compiler.misc.not.a.functional.intf=\
+ {0} is not a functional interface
+
+# 0: symbol, 1: message segment
compiler.misc.not.a.functional.intf.1=\
- the target type must be a functional interface\n\
- {0}
+ {0} is not a functional interface\n\
+ {1}
# 0: symbol, 1: symbol kind, 2: symbol
compiler.misc.invalid.generic.lambda.target=\
@@ -319,64 +328,48 @@
compiler.err.duplicate.annotation.missing.container=\
duplicate annotation, the declaration of {0} does not have a valid {1} annotation
-# 0: type, 1: type
-compiler.err.invalid.container.no.containedby=\
- invalid contained repeatable annotation, {0} is not annotated with {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.wrong.containedby=\
- invalid contained repeatable annotation, {0} does not match {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.no.containerfor=\
- invalid container for repeating annotations, {0} is not annotated with {1}
-
-# 0: type, 1: type
-compiler.err.invalid.container.wrong.containerfor=\
- invalid container for repeating annotations, {0} does not match {1}
+# 0: type
+compiler.err.invalid.repeatable.annotation=\
+ duplicate annotation, {0} is annotated with an invalid Repeatable annotation
# 0: type
-compiler.err.invalid.containedby.annotation=\
- duplicate annotation, {0} is annotated with an invalid ContainedBy annotation
-
-# 0: type
-compiler.err.invalid.containedby.annotation.no.value=\
- duplicate annotation, {0} is not a valid ContainedBy, no value element method declared
+compiler.err.invalid.repeatable.annotation.no.value=\
+ duplicate annotation, {0} is not a valid Repeatable, no value element method declared
# 0: type, 1: number
-compiler.err.invalid.containedby.annotation.multiple.values=\
- duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared
+compiler.err.invalid.repeatable.annotation.multiple.values=\
+ duplicate annotation, {0} is not a valid Repeatable, {1} value element methods declared
# 0: type
-compiler.err.invalid.containedby.annotation.invalid.value=\
- duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method
+compiler.err.invalid.repeatable.annotation.invalid.value=\
+ duplicate annotation, {0} is not a valid Repeatable, invalid value element, need a method
# 0: type, 1: type, 2: type
-compiler.err.invalid.containedby.annotation.value.return=\
+compiler.err.invalid.repeatable.annotation.value.return=\
duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
# 0: type, 1: symbol
-compiler.err.invalid.containedby.annotation.elem.nondefault=\
+compiler.err.invalid.repeatable.annotation.elem.nondefault=\
containing annotation {0} does not have a default value for element {1}
# 0: symbol, 1: type, 2: symbol, 3: type
-compiler.err.invalid.containedby.annotation.retention=\
+compiler.err.invalid.repeatable.annotation.retention=\
containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3}
# 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.not.documented=\
+compiler.err.invalid.repeatable.annotation.not.documented=\
containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is
# 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.not.inherited=\
+compiler.err.invalid.repeatable.annotation.not.inherited=\
containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is
# 0: symbol, 1: symbol
-compiler.err.invalid.containedby.annotation.incompatible.target=\
+compiler.err.invalid.repeatable.annotation.incompatible.target=\
target of container annotation {0} is not a subset of target of repeated annotation {1}
# 0: symbol
-compiler.err.invalid.containedby.annotation.repeated.and.container.present=\
+compiler.err.invalid.repeatable.annotation.repeated.and.container.present=\
container {0} must not be present at the same time as the element it contains
# 0: name
@@ -2139,6 +2132,10 @@
as of release 1.4, ''assert'' is a keyword, and may not be used as an identifier\n\
(use -source 1.4 or higher to use ''assert'' as a keyword)
+compiler.warn.underscore.as.identifier=\
+ ''_'' used as an identifier\n\
+ (use of ''_'' as an identifier might not be supported in future releases)
+
compiler.err.enum.as.identifier=\
as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\
(use -source 1.4 or lower to use ''enum'' as an identifier)
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Sun Jan 20 23:39:11 2013 -0800
@@ -1838,7 +1838,9 @@
/** Inner # new */
IMPLICIT_INNER(ReferenceMode.NEW, false),
/** Toplevel # new */
- TOPLEVEL(ReferenceMode.NEW, false);
+ TOPLEVEL(ReferenceMode.NEW, false),
+ /** ArrayType # new */
+ ARRAY_CTOR(ReferenceMode.NEW, false);
final ReferenceMode mode;
final boolean unbound;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Sun Jan 20 23:39:11 2013 -0800
@@ -288,7 +288,7 @@
public String simplify(Symbol s) {
String name = s.getQualifiedName().toString();
- if (!s.type.isCompound()) {
+ if (!s.type.isCompound() && !s.type.isPrimitive()) {
List<Symbol> conflicts = nameClashes.get(s.getSimpleName());
if (conflicts == null ||
(conflicts.size() == 1 &&
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, 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
@@ -31,8 +31,10 @@
import javax.tools.JavaFileManager;
import com.sun.javadoc.*;
+import com.sun.source.util.JavacTask;
import com.sun.source.util.TreePath;
-import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ClassType;
@@ -105,6 +107,7 @@
Types types;
JavaFileManager fileManager;
Context context;
+ DocLint doclint;
WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<JCTree, TreePath>();
@@ -400,6 +403,9 @@
public void warning(DocImpl doc, String key, String a1) {
if (silent)
return;
+ // suppress messages that have (probably) been covered by doclint
+ if (doclint != null && doc != null && key.startsWith("tag"))
+ return;
messager.warning(doc==null ? null : doc.position(), key, a1);
}
@@ -732,9 +738,15 @@
return p;
}
- TreePath getTreePath(JCCompilationUnit toplevel, JCTree tree) {
- // don't bother to cache paths for classes and members
- return new TreePath(getTreePath(toplevel), tree);
+ TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl tree) {
+ TreePath p = treePaths.get(tree);
+ if (p == null)
+ treePaths.put(tree, p = new TreePath(getTreePath(toplevel), tree));
+ return p;
+ }
+
+ TreePath getTreePath(JCCompilationUnit toplevel, JCClassDecl cdecl, JCTree tree) {
+ return new TreePath(getTreePath(toplevel, cdecl), tree);
}
/**
@@ -781,4 +793,25 @@
result |= Modifier.VOLATILE;
return result;
}
+
+ void initDoclint(Collection<String> opts) {
+ ArrayList<String> doclintOpts = new ArrayList<String>();
+
+ for (String opt: opts) {
+ doclintOpts.add(opt == null ? DocLint.XMSGS_OPTION : DocLint.XMSGS_CUSTOM_PREFIX + opt);
+ }
+
+ if (doclintOpts.size() == 1
+ && doclintOpts.get(0).equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) {
+ return;
+ }
+
+ JavacTask t = BasicJavacTask.instance(context);
+ doclint = new DocLint();
+ doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
+ }
+
+ boolean showTagMessages() {
+ return (doclint == null);
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -126,7 +126,13 @@
*/
Comment comment() {
if (comment == null) {
- comment = new Comment(this, documentation());
+ String d = documentation();
+ if (env.doclint != null
+ && treePath != null
+ && d.equals(getCommentText(treePath))) {
+ env.doclint.scan(treePath);
+ }
+ comment = new Comment(this, d);
}
return comment;
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -72,7 +72,7 @@
super.visitMethodDef(tree);
MethodSymbol meth = tree.sym;
if (meth == null || meth.kind != Kinds.MTH) return;
- TreePath treePath = docenv.getTreePath(env.toplevel, tree);
+ TreePath treePath = docenv.getTreePath(env.toplevel, env.enclClass, tree);
if (meth.isConstructor())
docenv.makeConstructorDoc(meth, treePath);
else if (isAnnotationTypeElement(meth))
@@ -90,7 +90,7 @@
if (tree.sym != null &&
tree.sym.kind == Kinds.VAR &&
!isParameter(tree.sym)) {
- docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, tree));
+ docenv.makeFieldDoc(tree.sym, docenv.getTreePath(env.toplevel, env.enclClass, tree));
}
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -26,13 +26,14 @@
package com.sun.tools.javadoc;
import java.io.IOException;
+import java.util.Collection;
import java.util.Locale;
+
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import com.sun.javadoc.*;
-
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
@@ -375,4 +376,12 @@
public JavaFileManager getFileManager() {
return env.fileManager;
}
+
+ public void initDocLint(Collection<String> opts) {
+ env.initDoclint(opts);
+ }
+
+ public boolean showTagMessages() {
+ return env.showTagMessages();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The build state class captures the source code and generated artifacts
+ * from a build. There are usually two build states, the previous one (prev),
+ * loaded from the javac_state file, and the current one (now).
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class BuildState {
+ private Map<String,Module> modules = new HashMap<String,Module>();
+ private Map<String,Package> packages = new HashMap<String,Package>();
+ private Map<String,Source> sources = new HashMap<String,Source>();
+ private Map<String,File> artifacts = new HashMap<String,File>();
+ // Map from package to a set of packages that depend on said package.
+ private Map<String,Set<String>> dependents = new HashMap<String,Set<String>>();
+
+ public Map<String,Module> modules() { return modules; }
+ public Map<String,Package> packages() { return packages; }
+ public Map<String,Source> sources() { return sources; }
+ public Map<String,File> artifacts() { return artifacts; }
+ public Map<String,Set<String>> dependents() { return dependents; }
+
+ /**
+ * Lookup a module from a name. Create the module if it does
+ * not exist yet.
+ */
+ public Module lookupModule(String mod) {
+ Module m = modules.get(mod);
+ if (m == null) {
+ m = new Module(mod, "???");
+ modules.put(mod, m);
+ }
+ return m;
+ }
+
+ /**
+ * Find a module from a given package name. For example:
+ * The package name "base:java.lang" will fetch the module named "base".
+ * The package name ":java.net" will fetch the default module.
+ */
+ Module findModuleFromPackageName(String pkg) {
+ int cp = pkg.indexOf(':');
+ assert(cp != -1);
+ String mod = pkg.substring(0, cp);
+ return lookupModule(mod);
+ }
+
+ /**
+ * Collect all packages, sources and artifacts for all modules
+ * into the build state.
+ *
+ * @param m The set of modules.
+ */
+ public void collectPackagesSourcesAndArtifacts(Map<String,Module> m) {
+ modules = m;
+ // Extract all the found packages.
+ for (Module i : modules.values()) {
+ for (Map.Entry<String,Package> j : i.packages().entrySet()) {
+ Package p = packages.get(j.getKey());
+ // Check that no two different packages are stored under same name.
+ assert(p == null || p == j.getValue());
+ if (p == null) {
+ p = j.getValue();
+ packages.put(j.getKey(),j.getValue());
+ }
+ for (Map.Entry<String,Source> k : p.sources().entrySet()) {
+ Source s = sources.get(k.getKey());
+ // Check that no two different sources are stored under same name.
+ assert(s == null || s == k.getValue());
+ if (s == null) {
+ s = k.getValue();
+ sources.put(k.getKey(), k.getValue());
+ }
+ }
+ for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
+ File f = artifacts.get(g.getKey());
+ // Check that no two artifacts are stored under the same file.
+ assert(f == null || f == g.getValue());
+ if (f == null) {
+ f = g.getValue();
+ artifacts.put(g.getKey(), g.getValue());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Collect all the artifacts of all modules and packages.
+ *
+ * @param m The set of modules.
+ */
+ public void collectArtifacts(Map<String,Module> m) {
+ modules = m;
+ // Extract all the found packages.
+ for (Module i : modules.values()) {
+ for (Map.Entry<String,Package> j : i.packages().entrySet()) {
+ Package p = packages.get(j.getKey());
+ // Check that no two different packages are stored under same name.
+ assert(p == null || p == j.getValue());
+ p = j.getValue();
+ packages.put(j.getKey(),j.getValue());
+ for (Map.Entry<String,File> g : p.artifacts().entrySet()) {
+ File f = artifacts.get(g.getKey());
+ // Check that no two artifacts are stored under the same file.
+ assert(f == null || f == g.getValue());
+ artifacts.put(g.getKey(), g.getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * Calculate the package dependents (ie the reverse of the dependencies).
+ */
+ public void calculateDependents() {
+ dependents = new HashMap<String,Set<String>>();
+ for (String s : packages.keySet()) {
+ Package p = packages.get(s);
+ for (String d : p.dependencies()) {
+ Set<String> ss = dependents.get(d);
+ if (ss == null) {
+ ss = new HashSet<String>();
+ dependents.put(d, ss);
+ }
+ // Add the dependent information to the global dependent map.
+ ss.add(s);
+ Package dp = packages.get(d);
+ // Also add the dependent information to the package specific map.
+ // Normally, you do not compile java.lang et al. Therefore
+ // there are several packages that p depends upon that you
+ // do not have in your state database. This is perfectly fine.
+ if (dp != null) {
+ // But this package did exist in the state database.
+ dp.addDependent(p.name());
+ }
+ }
+ }
+ }
+
+ /**
+ * Verify that the setModules method above did the right thing when
+ * running through the module->package->source structure.
+ */
+ public void checkInternalState(String msg, boolean linkedOnly, Map<String,Source> srcs) {
+ boolean baad = false;
+ Map<String,Source> original = new HashMap<String,Source>();
+ Map<String,Source> calculated = new HashMap<String,Source>();
+
+ for (String s : sources.keySet()) {
+ Source ss = sources.get(s);
+ if (ss.isLinkedOnly() == linkedOnly) {
+ calculated.put(s,ss);
+ }
+ }
+ for (String s : srcs.keySet()) {
+ Source ss = srcs.get(s);
+ if (ss.isLinkedOnly() == linkedOnly) {
+ original.put(s,ss);
+ }
+ }
+ if (original.size() != calculated.size()) {
+ Log.error("INTERNAL ERROR "+msg+" original and calculated are not the same size!");
+ baad = true;
+ }
+ if (!original.keySet().equals(calculated.keySet())) {
+ Log.error("INTERNAL ERROR "+msg+" original and calculated do not have the same domain!");
+ baad = true;
+ }
+ if (!baad) {
+ for (String s : original.keySet()) {
+ Source s1 = original.get(s);
+ Source s2 = calculated.get(s);
+ if (s1 == null || s2 == null || !s1.equals(s2)) {
+ Log.error("INTERNAL ERROR "+msg+" original and calculated have differing elements for "+s);
+ }
+ baad = true;
+ }
+ }
+ if (baad) {
+ for (String s : original.keySet()) {
+ Source ss = original.get(s);
+ Source sss = calculated.get(s);
+ if (sss == null) {
+ Log.error("The file "+s+" does not exist in calculated tree of sources.");
+ }
+ }
+ for (String s : calculated.keySet()) {
+ Source ss = calculated.get(s);
+ Source sss = original.get(s);
+ if (sss == null) {
+ Log.error("The file "+s+" does not exist in original set of found sources.");
+ }
+ }
+ }
+ }
+
+ /**
+ * Load a module from the javac state file.
+ */
+ public Module loadModule(String l) {
+ Module m = Module.load(l);
+ modules.put(m.name(), m);
+ return m;
+ }
+
+ /**
+ * Load a package from the javac state file.
+ */
+ public Package loadPackage(Module lastModule, String l) {
+ Package p = Package.load(lastModule, l);
+ lastModule.addPackage(p);
+ packages.put(p.name(), p);
+ return p;
+ }
+
+ /**
+ * Load a source from the javac state file.
+ */
+ public Source loadSource(Package lastPackage, String l, boolean is_generated) {
+ Source s = Source.load(lastPackage, l, is_generated);
+ lastPackage.addSource(s);
+ sources.put(s.name(), s);
+ return s;
+ }
+
+ /**
+ * During an incremental compile we need to copy the old javac state
+ * information about packages that were not recompiled.
+ */
+ public void copyPackagesExcept(BuildState prev, Set<String> recompiled, Set<String> removed) {
+ for (String pkg : prev.packages().keySet()) {
+ // Do not copy recompiled or removed packages.
+ if (recompiled.contains(pkg) || removed.contains(pkg)) continue;
+ Module mnew = findModuleFromPackageName(pkg);
+ Package pprev = prev.packages().get(pkg);
+ mnew.addPackage(pprev);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * The clean properties transform should not be necessary.
+ * Eventually we will cleanup the property file sources in the OpenJDK instead.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CleanProperties implements Transformer
+{
+ public void setExtra(String e) {
+ // Any extra information is ignored for clean properties.
+ }
+
+ public void setExtra(String[] a) {
+ // Any extra information is ignored for clean properties.
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSrcs,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependencies,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePublicApis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err)
+ {
+ boolean rc = true;
+ for (String pkgName : pkgSrcs.keySet()) {
+ String pkgNameF = pkgName.replace('.',File.separatorChar);
+ for (URI u : pkgSrcs.get(pkgName)) {
+ File src = new File(u);
+ boolean r = clean(pkgName, pkgNameF, src, new File(destRoot), debugLevel,
+ packageArtifacts);
+ if (r == false) {
+ rc = false;
+ }
+ }
+ }
+ return rc;
+ }
+
+ boolean clean(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
+ Map<String,Set<URI>> packageArtifacts)
+ {
+ // Load the properties file.
+ Properties p = new Properties();
+ try {
+ p.load(new FileInputStream(src));
+ } catch (IOException e) {
+ Log.error("Error reading file "+src.getPath());
+ return false;
+ }
+
+ // Sort the properties in increasing key order.
+ List<String> sortedKeys = new ArrayList<String>();
+ for (Object key : p.keySet()) {
+ sortedKeys.add((String)key);
+ }
+ Collections.sort(sortedKeys);
+ Iterator<String> keys = sortedKeys.iterator();
+
+ // Collect the properties into a string buffer.
+ StringBuilder data = new StringBuilder();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ data.append(CompileProperties.escape(key)+":"+CompileProperties.escape((String)p.get(key))+"\n");
+ }
+
+ String destFilename = destRoot.getPath()+File.separator+pkgNameF+File.separator+src.getName();
+ File dest = new File(destFilename);
+
+ // Make sure the dest directories exist.
+ if (!dest.getParentFile().isDirectory()) {
+ if (!dest.getParentFile().mkdirs()) {
+ Log.error("Could not create the directory "+dest.getParentFile().getPath());
+ return false;
+ }
+ }
+
+ Set<URI> as = packageArtifacts.get(pkgName);
+ if (as == null) {
+ as = new HashSet<URI>();
+ packageArtifacts.put(pkgName, as);
+ }
+ as.add(dest.toURI());
+
+ if (dest.exists() && dest.lastModified() > src.lastModified()) {
+ // A cleaned property file exists, and its timestamp is newer than the source.
+ // Assume that we do not need to clean!
+ // Thus we are done.
+ return true;
+ }
+
+ Log.info("Cleaning property file "+pkgNameF+File.separator+src.getName());
+ try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest)))) {
+ writer.write(data.toString());
+ } catch ( IOException e ) {
+ Log.error("Could not write file "+dest.getPath());
+ return false;
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileChunk.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A compile chunk is a list of sources/packages to be compiled. Possibly a subset of
+ * the total number of sources/packages to be compiled for this sjavac invocation.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompileChunk implements Comparable<CompileChunk> {
+ public int numPackages;
+ public int numDependents;
+ public Set<URI> srcs = new HashSet<URI>();
+ public StringBuilder pkgNames = new StringBuilder();
+ public String pkgFromTos = "";
+
+ public int compareTo(CompileChunk c) {
+ if (numDependents == c.numDependents) return 0;
+ if (numDependents > c.numDependents) return -1;
+ return -1;
+ }
+
+ boolean equal(CompileChunk c) {
+ return numDependents == c.numDependents;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.Set;
+import java.util.Map;
+
+import com.sun.tools.sjavac.server.JavacServer;
+import com.sun.tools.sjavac.server.SysInfo;
+import java.io.PrintStream;
+
+/**
+ * This transform compiles a set of packages containing Java sources.
+ * The compile request is divided into separate sets of source files.
+ * For each set a separate request thread is dispatched to a javac server
+ * and the meta data is accumulated. The number of sets correspond more or
+ * less to the number of cores. Less so now, than it will in the future.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompileJavaPackages implements Transformer {
+
+ // The current limited sharing of data between concurrent JavaCompilers
+ // in the server will not give speedups above 3 cores. Thus this limit.
+ // We hope to improve this in the future.
+ final static int limitOnConcurrency = 3;
+
+ String serverSettings;
+ public void setExtra(String e) {
+ serverSettings = e;
+ }
+
+ String[] args;
+ public void setExtra(String[] a) {
+ args = a;
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSources,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependents,
+ URI destRoot,
+ final Map<String,Set<URI>> packageArtifacts,
+ final Map<String,Set<String>> packageDependencies,
+ final Map<String,String> packagePubapis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err)
+ {
+ boolean rc = true;
+ boolean concurrentCompiles = true;
+
+ // Fetch the id.
+ String id = Util.extractStringOption("id", serverSettings);
+ if (id == null || id.equals("")) {
+ // No explicit id set. Create a random id so that the requests can be
+ // grouped properly in the server.
+ id = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
+ }
+ // Only keep portfile and sjavac settings..
+ String psServerSettings = Util.cleanSubOptions("--server:", Util.set("portfile","sjavac","background","keepalive"), serverSettings);
+
+ // Get maximum heap size from the server!
+ SysInfo sysinfo = JavacServer.connectGetSysInfo(psServerSettings, out, err);
+ if (sysinfo.numCores == -1) {
+ Log.error("Could not query server for sysinfo!");
+ return false;
+ }
+ int numMBytes = (int)(sysinfo.maxMemory / ((long)(1024*1024)));
+ Log.debug("Server reports "+numMBytes+"MiB of memory and "+sysinfo.numCores+" cores");
+
+ if (numCores <= 0) {
+ // Set the requested number of cores to the number of cores on the server.
+ numCores = sysinfo.numCores;
+ Log.debug("Number of jobs not explicitly set, defaulting to "+sysinfo.numCores);
+ } else if (sysinfo.numCores < numCores) {
+ // Set the requested number of cores to the number of cores on the server.
+ Log.debug("Limiting jobs from explicitly set "+numCores+" to cores available on server: "+sysinfo.numCores);
+ numCores = sysinfo.numCores;
+ } else {
+ Log.debug("Number of jobs explicitly set to "+numCores);
+ }
+ // More than three concurrent cores does not currently give a speedup, at least for compiling the jdk
+ // in the OpenJDK. This will change in the future.
+ int numCompiles = numCores;
+ if (numCores > limitOnConcurrency) numCompiles = limitOnConcurrency;
+ // Split the work up in chunks to compiled.
+
+ int numSources = 0;
+ for (String s : pkgSrcs.keySet()) {
+ Set<URI> ss = pkgSrcs.get(s);
+ numSources += ss.size();
+ }
+
+ int sourcesPerCompile = numSources / numCompiles;
+
+ // For 64 bit Java, it seems we can compile the OpenJDK 8800 files with a 1500M of heap
+ // in a single chunk, with reasonable performance.
+ // For 32 bit java, it seems we need 1G of heap.
+ // Number experimentally determined when compiling the OpenJDK.
+ // Includes space for reasonably efficient garbage collection etc,
+ // Calculating backwards gives us a requirement of
+ // 1500M/8800 = 175 KiB for 64 bit platforms
+ // and 1G/8800 = 119 KiB for 32 bit platform
+ // for each compile.....
+ int kbPerFile = 175;
+ String osarch = System.getProperty("os.arch");
+ if (osarch.equals("i386")) {
+ // For 32 bit platforms, assume it is slightly smaller
+ // because of smaller object headers and pointers.
+ kbPerFile = 119;
+ }
+ int numRequiredMBytes = (kbPerFile*numSources)/1024;
+ Log.debug("For os.arch "+osarch+" the empirically determined heap required per file is "+kbPerFile+"KiB");
+ Log.debug("Server has "+numMBytes+"MiB of heap.");
+ Log.debug("Heuristics say that we need "+numRequiredMBytes+"MiB of heap for all source files.");
+ // Perform heuristics to see how many cores we can use,
+ // or if we have to the work serially in smaller chunks.
+ if (numMBytes < numRequiredMBytes) {
+ // Ouch, cannot fit even a single compile into the heap.
+ // Split it up into several serial chunks.
+ concurrentCompiles = false;
+ // Limit the number of sources for each compile to 500.
+ if (numSources < 500) {
+ numCompiles = 1;
+ sourcesPerCompile = numSources;
+ Log.debug("Compiling as a single source code chunk to stay within heap size limitations!");
+ } else if (sourcesPerCompile > 500) {
+ // This number is very low, and tuned to dealing with the OpenJDK
+ // where the source is >very< circular! In normal application,
+ // with less circularity the number could perhaps be increased.
+ numCompiles = numSources / 500;
+ sourcesPerCompile = numSources/numCompiles;
+ Log.debug("Compiling source as "+numCompiles+" code chunks serially to stay within heap size limitations!");
+ }
+ } else {
+ if (numCompiles > 1) {
+ // Ok, we can fit at least one full compilation on the heap.
+ float usagePerCompile = (float)numRequiredMBytes / ((float)numCompiles * (float)0.7);
+ int usage = (int)(usagePerCompile * (float)numCompiles);
+ Log.debug("Heuristics say that for "+numCompiles+" concurrent compiles we need "+usage+"MiB");
+ if (usage > numMBytes) {
+ // Ouch it does not fit. Reduce to a single chunk.
+ numCompiles = 1;
+ sourcesPerCompile = numSources;
+ // What if the relationship betweem number of compile_chunks and num_required_mbytes
+ // is not linear? Then perhaps 2 chunks would fit where 3 does not. Well, this is
+ // something to experiment upon in the future.
+ Log.debug("Limiting compile to a single thread to stay within heap size limitations!");
+ }
+ }
+ }
+
+ Log.debug("Compiling sources in "+numCompiles+" chunk(s)");
+
+ // Create the chunks to be compiled.
+ final CompileChunk[] compileChunks = createCompileChunks(pkgSrcs, oldPackageDependents,
+ numCompiles, sourcesPerCompile);
+
+ if (Log.isDebugging()) {
+ int cn = 1;
+ for (CompileChunk cc : compileChunks) {
+ Log.debug("Chunk "+cn+" for "+id+" ---------------");
+ cn++;
+ for (URI u : cc.srcs) {
+ Log.debug(""+u);
+ }
+ }
+ }
+
+ // The return values for each chunked compile.
+ final int[] rn = new int[numCompiles];
+ // The requets, might or might not run as a background thread.
+ final Thread[] requests = new Thread[numCompiles];
+
+ final Set<URI> fvisible_sources = visibleSources;
+ final Map<URI,Set<String>> fvisible_classes = visibleClasses;
+
+ long start = System.currentTimeMillis();
+
+ for (int i=0; i<numCompiles; ++i) {
+ final int ii = i;
+ final CompileChunk cc = compileChunks[i];
+
+ // Pass the num_cores and the id (appended with the chunk number) to the server.
+ final String cleanedServerSettings = psServerSettings+",poolsize="+numCores+",id="+id+"-"+ii;
+ final PrintStream fout = out;
+ final PrintStream ferr = err;
+
+ requests[ii] = new Thread() {
+ @Override
+ public void run() {
+ rn[ii] = JavacServer.useServer(cleanedServerSettings,
+ Main.removeWrapperArgs(args),
+ cc.srcs,
+ fvisible_sources,
+ fvisible_classes,
+ packageArtifacts,
+ packageDependencies,
+ packagePubapis,
+ null,
+ fout, ferr);
+ }
+ };
+
+ if (cc.srcs.size() > 0) {
+ String numdeps = "";
+ if (cc.numDependents > 0) numdeps = "(with "+cc.numDependents+" dependents) ";
+ if (!incremental || cc.numPackages > 16) {
+ String info = "("+cc.pkgFromTos+")";
+ if (info.equals("( to )")) {
+ info = "";
+ }
+ Log.info("Compiling "+cc.srcs.size()+" files "+numdeps+"in "+cc.numPackages+" packages "+info);
+ } else {
+ Log.info("Compiling "+cc.pkgNames+numdeps);
+ }
+ if (concurrentCompiles) {
+ requests[ii].start();
+ }
+ else {
+ requests[ii].run();
+ // If there was an error, then stop early when running single threaded.
+ if (rn[i] != 0) {
+ return false;
+ }
+ }
+ }
+ }
+ if (concurrentCompiles) {
+ // If there are background threads for the concurrent compiles, then join them.
+ for (int i=0; i<numCompiles; ++i) {
+ try { requests[i].join(); } catch (InterruptedException e) { }
+ }
+ }
+
+ // Check the return values.
+ for (int i=0; i<numCompiles; ++i) {
+ if (compileChunks[i].srcs.size() > 0) {
+ if (rn[i] != 0) {
+ rc = false;
+ }
+ }
+ }
+ long duration = System.currentTimeMillis() - start;
+ long minutes = duration/60000;
+ long seconds = (duration-minutes*60000)/1000;
+ Log.debug("Compilation of "+numSources+" source files took "+minutes+"m "+seconds+"s");
+
+ return rc;
+ }
+
+
+ /**
+ * Split up the sources into compile chunks. If old package dependents information
+ * is available, sort the order of the chunks into the most dependent first!
+ * (Typically that chunk contains the java.lang package.) In the future
+ * we could perhaps improve the heuristics to put the sources into even more sensible chunks.
+ * Now the package are simple sorted in alphabetical order and chunked, then the chunks
+ * are sorted on how dependent they are.
+ *
+ * @param pkgSrcs The sources to compile.
+ * @param oldPackageDependents Old package dependents, if non-empty, used to sort the chunks.
+ * @param numCompiles The number of chunks.
+ * @param sourcesPerCompile The number of sources per chunk.
+ * @return
+ */
+ CompileChunk[] createCompileChunks(Map<String,Set<URI>> pkgSrcs,
+ Map<String,Set<String>> oldPackageDependents,
+ int numCompiles,
+ int sourcesPerCompile) {
+
+ CompileChunk[] compileChunks = new CompileChunk[numCompiles];
+ for (int i=0; i<compileChunks.length; ++i) {
+ compileChunks[i] = new CompileChunk();
+ }
+
+ // Now go through the packages and spread out the source on the different chunks.
+ int ci = 0;
+ // Sort the packages
+ String[] packageNames = pkgSrcs.keySet().toArray(new String[0]);
+ Arrays.sort(packageNames);
+ String from = null;
+ for (String pkgName : packageNames) {
+ CompileChunk cc = compileChunks[ci];
+ Set<URI> s = pkgSrcs.get(pkgName);
+ if (cc.srcs.size()+s.size() > sourcesPerCompile && ci < numCompiles-1) {
+ from = null;
+ ci++;
+ cc = compileChunks[ci];
+ }
+ cc.numPackages++;
+ cc.srcs.addAll(s);
+
+ // Calculate nice package names to use as information when compiling.
+ String justPkgName = Util.justPackageName(pkgName);
+ // Fetch how many packages depend on this package from the old build state.
+ Set<String> ss = oldPackageDependents.get(pkgName);
+ if (ss != null) {
+ // Accumulate this information onto this chunk.
+ cc.numDependents += ss.size();
+ }
+ if (from == null || from.trim().equals("")) from = justPkgName;
+ cc.pkgNames.append(justPkgName+"("+s.size()+") ");
+ cc.pkgFromTos = from+" to "+justPkgName;
+ }
+ // If we are compiling serially, sort the chunks, so that the chunk (with the most dependents) (usually the chunk
+ // containing java.lang.Object, is to be compiled first!
+ // For concurrent compilation, this does not matter.
+ Arrays.sort(compileChunks);
+ return compileChunks;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Compile properties transform a properties file into a Java source file.
+ * Java has built in support for reading properties from either a text file
+ * in the source or a compiled java source file.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompileProperties implements Transformer
+{
+ // Any extra information passed from the command line, for example if:
+ // -tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
+ // then extra will be "sun.util.resources.LocaleNamesBundle"
+ String extra;
+
+ public void setExtra(String e) {
+ extra = e;
+ }
+
+ public void setExtra(String[] a) {
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSrcs,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependents,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePublicApis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err) {
+ boolean rc = true;
+ for (String pkgName : pkgSrcs.keySet()) {
+ String pkgNameF = Util.toFileSystemPath(pkgName);
+ for (URI u : pkgSrcs.get(pkgName)) {
+ File src = new File(u);
+ boolean r = compile(pkgName, pkgNameF, src, new File(destRoot), debugLevel,
+ packageArtifacts);
+ if (r == false) {
+ rc = false;
+ }
+ }
+ }
+ return rc;
+ }
+
+ boolean compile(String pkgName, String pkgNameF, File src, File destRoot, int debugLevel,
+ Map<String,Set<URI>> packageArtifacts)
+ {
+ String superClass = "java.util.ListResourceBundle";
+
+ if (extra != null) {
+ superClass = extra;
+ }
+ // Load the properties file.
+ Properties p = new Properties();
+ try {
+ p.load(new FileInputStream(src));
+ } catch (IOException e) {
+ Log.error("Error reading file "+src.getPath());
+ return false;
+ }
+
+ // Calculate the name of the Java source file to be generated.
+ int dp = src.getName().lastIndexOf(".");
+ String classname = src.getName().substring(0,dp);
+
+ // Sort the properties in increasing key order.
+ List<String> sortedKeys = new ArrayList<String>();
+ for (Object key : p.keySet()) {
+ sortedKeys.add((String)key);
+ }
+ Collections.sort(sortedKeys);
+ Iterator<String> keys = sortedKeys.iterator();
+
+ // Collect the properties into a string buffer.
+ StringBuilder data = new StringBuilder();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ data.append(" { \"" + escape(key) + "\", \"" +
+ escape((String)p.get(key)) + "\" },\n");
+ }
+
+ // Create dest file name. It is derived from the properties file name.
+ String destFilename = destRoot.getPath()+File.separator+pkgNameF+File.separator+classname+".java";
+ File dest = new File(destFilename);
+
+ // Make sure the dest directories exist.
+ if (!dest.getParentFile().isDirectory()) {
+ if (!dest.getParentFile().mkdirs()) {
+ Log.error("Could not create the directory "+dest.getParentFile().getPath());
+ return false;
+ }
+ }
+
+ Set<URI> as = packageArtifacts.get(pkgName);
+ if (as == null) {
+ as = new HashSet<URI>();
+ packageArtifacts.put(pkgName, as);
+ }
+ as.add(dest.toURI());
+
+ if (dest.exists() && dest.lastModified() > src.lastModified()) {
+ // A generated file exists, and its timestamp is newer than the source.
+ // Assume that we do not need to regenerate the dest file!
+ // Thus we are done.
+ return true;
+ }
+
+ String packageString = "package " + pkgNameF.replace(File.separatorChar,'.') + ";\n\n";
+
+ Log.info("Compiling property file "+pkgNameF+File.separator+src.getName());
+ try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest)))) {
+ MessageFormat format = new MessageFormat(FORMAT);
+ writer.write(format.format(new Object[] { packageString, classname, superClass, data }));
+ } catch ( IOException e ) {
+ Log.error("Could not write file "+dest.getPath());
+ return false;
+ }
+ return true;
+ }
+
+ private static final String FORMAT =
+ "{0}" +
+ "public final class {1} extends {2} '{'\n" +
+ " protected final Object[][] getContents() '{'\n" +
+ " return new Object[][] '{'\n" +
+ "{3}" +
+ " };\n" +
+ " }\n" +
+ "}\n";
+
+ public static String escape(String theString) {
+ int len = theString.length();
+ StringBuilder outBuffer = new StringBuilder(len*2);
+
+ for(int x=0; x<len; x++) {
+ char aChar = theString.charAt(x);
+ switch(aChar) {
+ case '\\':outBuffer.append('\\'); outBuffer.append('\\');
+ break;
+ case '\t':outBuffer.append('\\'); outBuffer.append('t');
+ break;
+ case '\n':outBuffer.append('\\'); outBuffer.append('n');
+ break;
+ case '\r':outBuffer.append('\\'); outBuffer.append('r');
+ break;
+ case '\f':outBuffer.append('\\'); outBuffer.append('f');
+ break;
+ default:
+ if ((aChar < 0x0020) || (aChar > 0x007e)) {
+ outBuffer.append('\\');
+ outBuffer.append('u');
+ outBuffer.append(toHex((aChar >> 12) & 0xF));
+ outBuffer.append(toHex((aChar >> 8) & 0xF));
+ outBuffer.append(toHex((aChar >> 4) & 0xF));
+ outBuffer.append(toHex( aChar & 0xF));
+ } else {
+ if (aChar == '"') {
+ outBuffer.append('\\');
+ }
+ outBuffer.append(aChar);
+ }
+ }
+ }
+ return outBuffer.toString();
+ }
+
+ private static char toHex(int nibble) {
+ return hexDigit[(nibble & 0xF)];
+ }
+
+ private static final char[] hexDigit = {
+ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.net.URI;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * The copy file transform simply copies a matching file from -src to -d .
+ * Such files are typically images, xml documents and other data files.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CopyFile implements Transformer {
+
+ public void setExtra(String e) {
+ }
+
+ public void setExtra(String[] a) {
+ }
+
+ public boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSrcs,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependents,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePubapis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err)
+ {
+ boolean rc = true;
+ String dest_filename;
+ File dest;
+
+ for (String pkgName : pkgSrcs.keySet()) {
+ String pkgNameF = Util.toFileSystemPath(pkgName);
+ for (URI u : pkgSrcs.get(pkgName)) {
+ File src = new File(u);
+ File destDir;
+ destDir = new File(destRoot.getPath()+File.separator+pkgNameF);
+ dest_filename = destRoot.getPath()+File.separator+pkgNameF+File.separator+src.getName();
+ dest = new File(dest_filename);
+
+ if (!destDir.isDirectory()) {
+ if (!destDir.mkdirs()) {
+ Log.error("Error: The copier could not create the directory "+
+ destDir.getPath());
+ return false;
+ }
+ }
+
+ Set<URI> as = packageArtifacts.get(pkgName);
+ if (as == null) {
+ as = new HashSet<URI>();
+ packageArtifacts.put(pkgName, as);
+ }
+ as.add(dest.toURI());
+
+ if (dest.exists() && dest.lastModified() > src.lastModified()) {
+ // A copied file exists, and its timestamp is newer than the source.
+ continue;
+ }
+
+ Log.info("Copying "+pkgNameF+File.separator+src.getName());
+
+ try (InputStream fin = new FileInputStream(src);
+ OutputStream fout = new FileOutputStream(dest)) {
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = fin.read(buf)) > 0){
+ fout.write(buf, 0, len);
+ }
+ }
+ catch(IOException e){
+ Log.error("Could not copy the file "+src.getPath()+" to "+dest.getPath());
+ rc = false;
+ }
+ }
+ }
+ return rc;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,857 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.text.SimpleDateFormat;
+import java.net.URI;
+import java.util.*;
+
+/**
+ * The javac state class maintains the previous (prev) and the current (now)
+ * build states and everything else that goes into the javac_state file.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class JavacState
+{
+ // The arguments to the compile. If not identical, then it cannot
+ // be an incremental build!
+ String theArgs;
+ // The number of cores limits how many threads are used for heavy concurrent work.
+ int numCores;
+
+ // The bin_dir/javac_state
+ private String javacStateFilename;
+ private File javacState;
+
+ // The previous build state is loaded from javac_state
+ private BuildState prev;
+ // The current build state is constructed during the build,
+ // then saved as the new javac_state.
+ private BuildState now;
+
+ // Something has changed in the javac_state. It needs to be saved!
+ private boolean needsSaving;
+ // If this is a new javac_state file, then do not print unnecessary messages.
+ private boolean newJavacState;
+
+ // These are packages where something has changed and the package
+ // needs to be recompiled. Actions that trigger recompilation:
+ // * source belonging to the package has changed
+ // * artifact belonging to the package is lost, or its timestamp has been changed.
+ // * an unknown artifact has appeared, we simply delete it, but we also trigger a recompilation.
+ // * a package that is tainted, taints all packages that depend on it.
+ private Set<String> taintedPackages;
+ // After a compile, the pubapis are compared with the pubapis stored in the javac state file.
+ // Any packages where the pubapi differ are added to this set.
+ // Later we use this set and the dependency information to taint dependent packages.
+ private Set<String> packagesWithChangedPublicApis;
+ // When a module-info.java file is changed, taint the module,
+ // then taint all modules that depend on that that module.
+ // A module dependency can occur directly through a require, or
+ // indirectly through a module that does a public export for the first tainted module.
+ // When all modules are tainted, then taint all packages belonging to these modules.
+ // Then rebuild. It is perhaps possible (and valuable?) to do a more finegrained examination of the
+ // change in module-info.java, but that will have to wait.
+ private Set<String> taintedModules;
+ // The set of all packages that has been recompiled.
+ // Copy over the javac_state for the packages that did not need recompilation,
+ // verbatim from the previous (prev) to the new (now) build state.
+ private Set<String> recompiledPackages;
+
+ // The output directories filled with tasty artifacts.
+ private File binDir, gensrcDir, headerDir;
+
+ // The current status of the file system.
+ private Set<File> binArtifacts;
+ private Set<File> gensrcArtifacts;
+ private Set<File> headerArtifacts;
+
+ // The status of the sources.
+ Set<Source> removedSources = null;
+ Set<Source> addedSources = null;
+ Set<Source> modifiedSources = null;
+
+ // Visible sources for linking. These are the only
+ // ones that -sourcepath is allowed to see.
+ Set<URI> visibleSrcs;
+
+ // Visible classes for linking. These are the only
+ // ones that -classpath is allowed to see.
+ // It maps from a classpath root to the set of visible classes for that root.
+ // If the set is empty, then all classes are visible for that root.
+ // It can also map from a jar file to the set of visible classes for that jar file.
+ Map<URI,Set<String>> visibleClasses;
+
+ // Setup two transforms that always exist.
+ private CopyFile copyFiles = new CopyFile();
+ private CompileJavaPackages compileJavaPackages = new CompileJavaPackages();
+
+ // Where to send stdout and stderr.
+ private PrintStream out, err;
+
+ JavacState(String[] args, File bd, File gd, File hd, boolean permitUnidentifiedArtifacts, boolean removeJavacState,
+ PrintStream o, PrintStream e) {
+ out = o;
+ err = e;
+ numCores = Main.findNumberOption(args, "-j");
+ theArgs = "";
+ for (String a : removeArgsNotAffectingState(args)) {
+ theArgs = theArgs+a+" ";
+ }
+ binDir = bd;
+ gensrcDir = gd;
+ headerDir = hd;
+ javacStateFilename = binDir.getPath()+File.separator+"javac_state";
+ javacState = new File(javacStateFilename);
+ if (removeJavacState && javacState.exists()) {
+ javacState.delete();
+ }
+ newJavacState = false;
+ if (!javacState.exists()) {
+ newJavacState = true;
+ // If there is no javac_state then delete the contents of all the artifact dirs!
+ // We do not want to risk building a broken incremental build.
+ // BUT since the makefiles still copy things straight into the bin_dir et al,
+ // we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
+ if (!permitUnidentifiedArtifacts) {
+ deleteContents(binDir);
+ deleteContents(gensrcDir);
+ deleteContents(headerDir);
+ }
+ needsSaving = true;
+ }
+ prev = new BuildState();
+ now = new BuildState();
+ taintedPackages = new HashSet<String>();
+ recompiledPackages = new HashSet<String>();
+ packagesWithChangedPublicApis = new HashSet<String>();
+ }
+
+ public BuildState prev() { return prev; }
+ public BuildState now() { return now; }
+
+ /**
+ * Remove args not affecting the state.
+ */
+ static String[] removeArgsNotAffectingState(String[] args) {
+ String[] out = new String[args.length];
+ int j = 0;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-j")) {
+ // Just skip it and skip following value
+ i++;
+ } else if (args[i].startsWith("--server:")) {
+ // Just skip it.
+ } else if (args[i].startsWith("--log=")) {
+ // Just skip it.
+ } else if (args[i].equals("--compare-found-sources")) {
+ // Just skip it and skip verify file name
+ i++;
+ } else {
+ // Copy argument.
+ out[j] = args[i];
+ j++;
+ }
+ }
+ String[] ret = new String[j];
+ System.arraycopy(out, 0, ret, 0, j);
+ return ret;
+ }
+
+ /**
+ * Specify which sources are visible to the compiler through -sourcepath.
+ */
+ public void setVisibleSources(Map<String,Source> vs) {
+ visibleSrcs = new HashSet<URI>();
+ for (String s : vs.keySet()) {
+ Source src = vs.get(s);
+ visibleSrcs.add(src.file().toURI());
+ }
+ }
+
+ /**
+ * Specify which classes are visible to the compiler through -classpath.
+ */
+ public void setVisibleClasses(Map<String,Source> vs) {
+ visibleSrcs = new HashSet<URI>();
+ for (String s : vs.keySet()) {
+ Source src = vs.get(s);
+ visibleSrcs.add(src.file().toURI());
+ }
+ }
+ /**
+ * Returns true if this is an incremental build.
+ */
+ public boolean isIncremental() {
+ return !prev.sources().isEmpty();
+ }
+
+ /**
+ * Find all artifacts that exists on disk.
+ */
+ public void findAllArtifacts() {
+ binArtifacts = findAllFiles(binDir);
+ gensrcArtifacts = findAllFiles(gensrcDir);
+ headerArtifacts = findAllFiles(headerDir);
+ }
+
+ /**
+ * Lookup the artifacts generated for this package in the previous build.
+ */
+ private Map<String,File> fetchPrevArtifacts(String pkg) {
+ Package p = prev.packages().get(pkg);
+ if (p != null) {
+ return p.artifacts();
+ }
+ return new HashMap<String,File>();
+ }
+
+ /**
+ * Delete all prev artifacts in the currently tainted packages.
+ */
+ public void deleteClassArtifactsInTaintedPackages() {
+ for (String pkg : taintedPackages) {
+ Map<String,File> arts = fetchPrevArtifacts(pkg);
+ for (File f : arts.values()) {
+ if (f.exists() && f.getName().endsWith(".class")) {
+ f.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Mark the javac_state file to be in need of saving and as a side effect,
+ * it gets a new timestamp.
+ */
+ private void needsSaving() {
+ needsSaving = true;
+ }
+
+ /**
+ * Save the javac_state file.
+ */
+ public void save() throws IOException {
+ if (!needsSaving) return;
+ try (FileWriter out = new FileWriter(javacStateFilename)) {
+ StringBuilder b = new StringBuilder();
+ long millisNow = System.currentTimeMillis();
+ Date d = new Date(millisNow);
+ SimpleDateFormat df =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
+ b.append("# javac_state ver 0.3 generated "+millisNow+" "+df.format(d)+"\n");
+ b.append("# This format might change at any time. Please do not depend on it.\n");
+ b.append("# M module\n");
+ b.append("# P package\n");
+ b.append("# S C source_tobe_compiled timestamp\n");
+ b.append("# S L link_only_source timestamp\n");
+ b.append("# G C generated_source timestamp\n");
+ b.append("# A artifact timestamp\n");
+ b.append("# D dependency\n");
+ b.append("# I pubapi\n");
+ b.append("# R arguments\n");
+ b.append("R ").append(theArgs).append("\n");
+
+ // Copy over the javac_state for the packages that did not need recompilation.
+ now.copyPackagesExcept(prev, recompiledPackages, new HashSet<String>());
+ // Save the packages, ie package names, dependencies, pubapis and artifacts!
+ // I.e. the lot.
+ Module.saveModules(now.modules(), b);
+
+ String s = b.toString();
+ out.write(s, 0, s.length());
+ }
+ }
+
+ /**
+ * Load a javac_state file.
+ */
+ public static JavacState load(String[] args, File binDir, File gensrcDir, File headerDir,
+ boolean permitUnidentifiedArtifacts, PrintStream out, PrintStream err) {
+ JavacState db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err);
+ Module lastModule = null;
+ Package lastPackage = null;
+ Source lastSource = null;
+ boolean noFileFound = false;
+ boolean foundCorrectVerNr = false;
+ boolean newCommandLine = false;
+ boolean syntaxError = false;
+
+ try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
+ for (;;) {
+ String l = in.readLine();
+ if (l==null) break;
+ if (l.length()>=3 && l.charAt(1) == ' ') {
+ char c = l.charAt(0);
+ if (c == 'M') {
+ lastModule = db.prev.loadModule(l);
+ } else
+ if (c == 'P') {
+ if (lastModule == null) { syntaxError = true; break; }
+ lastPackage = db.prev.loadPackage(lastModule, l);
+ } else
+ if (c == 'D') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastPackage.loadDependency(l);
+ } else
+ if (c == 'I') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastPackage.loadPubapi(l);
+ } else
+ if (c == 'A') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastPackage.loadArtifact(l);
+ } else
+ if (c == 'S') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastSource = db.prev.loadSource(lastPackage, l, false);
+ } else
+ if (c == 'G') {
+ if (lastModule == null || lastPackage == null) { syntaxError = true; break; }
+ lastSource = db.prev.loadSource(lastPackage, l, true);
+ } else
+ if (c == 'R') {
+ String ncmdl = "R "+db.theArgs;
+ if (!l.equals(ncmdl)) {
+ newCommandLine = true;
+ }
+ } else
+ if (c == '#') {
+ if (l.startsWith("# javac_state ver ")) {
+ int sp = l.indexOf(" ", 18);
+ if (sp != -1) {
+ String ver = l.substring(18,sp);
+ if (!ver.equals("0.3")) {
+ break;
+ }
+ foundCorrectVerNr = true;
+ }
+ }
+ }
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // Silently create a new javac_state file.
+ noFileFound = true;
+ } catch (IOException e) {
+ Log.info("Dropping old javac_state because of errors when reading it.");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ foundCorrectVerNr = true;
+ newCommandLine = false;
+ syntaxError = false;
+ }
+ if (foundCorrectVerNr == false && !noFileFound) {
+ Log.info("Dropping old javac_state since it is of an old version.");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ } else
+ if (newCommandLine == true && !noFileFound) {
+ Log.info("Dropping old javac_state since a new command line is used!");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ } else
+ if (syntaxError == true) {
+ Log.info("Dropping old javac_state since it contains syntax errors.");
+ db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ }
+ db.prev.calculateDependents();
+ return db;
+ }
+
+ /**
+ * Mark a java package as tainted, ie it needs recompilation.
+ */
+ public void taintPackage(String name, String because) {
+ if (!taintedPackages.contains(name)) {
+ if (because != null) Log.debug("Tainting "+Util.justPackageName(name)+" because "+because);
+ // It has not been tainted before.
+ taintedPackages.add(name);
+ needsSaving();
+ Package nowp = now.packages().get(name);
+ if (nowp != null) {
+ for (String d : nowp.dependents()) {
+ taintPackage(d, because);
+ }
+ }
+ }
+ }
+
+ /**
+ * This packages need recompilation.
+ */
+ public Set<String> taintedPackages() {
+ return taintedPackages;
+ }
+
+ /**
+ * Clean out the tainted package set, used after the first round of compiles,
+ * prior to propagating dependencies.
+ */
+ public void clearTaintedPackages() {
+ taintedPackages = new HashSet<String>();
+ }
+
+ /**
+ * Go through all sources and check which have been removed, added or modified
+ * and taint the corresponding packages.
+ */
+ public void checkSourceStatus(boolean check_gensrc) {
+ removedSources = calculateRemovedSources();
+ for (Source s : removedSources) {
+ if (!s.isGenerated() || check_gensrc) {
+ taintPackage(s.pkg().name(), "source "+s.name()+" was removed");
+ }
+ }
+
+ addedSources = calculateAddedSources();
+ for (Source s : addedSources) {
+ String msg = null;
+ if (isIncremental()) {
+ // When building from scratch, there is no point
+ // printing "was added" for every file since all files are added.
+ // However for an incremental build it makes sense.
+ msg = "source "+s.name()+" was added";
+ }
+ if (!s.isGenerated() || check_gensrc) {
+ taintPackage(s.pkg().name(), msg);
+ }
+ }
+
+ modifiedSources = calculateModifiedSources();
+ for (Source s : modifiedSources) {
+ if (!s.isGenerated() || check_gensrc) {
+ taintPackage(s.pkg().name(), "source "+s.name()+" was modified");
+ }
+ }
+ }
+
+ /**
+ * Acquire the compile_java_packages suffix rule for .java files.
+ */
+ public Map<String,Transformer> getJavaSuffixRule() {
+ Map<String,Transformer> sr = new HashMap<String,Transformer>();
+ sr.put(".java", compileJavaPackages);
+ return sr;
+ }
+
+ /**
+ * Acquire the copying transform.
+ */
+ public Transformer getCopier() {
+ return copyFiles;
+ }
+
+ /**
+ * If artifacts have gone missing, force a recompile of the packages
+ * they belong to.
+ */
+ public void taintPackagesThatMissArtifacts() {
+ for (Package pkg : prev.packages().values()) {
+ for (File f : pkg.artifacts().values()) {
+ if (!f.exists()) {
+ // Hmm, the artifact on disk does not exist! Someone has removed it....
+ // Lets rebuild the package.
+ taintPackage(pkg.name(), ""+f+" is missing.");
+ }
+ }
+ }
+ }
+
+ /**
+ * Propagate recompilation through the dependency chains.
+ * Avoid re-tainting packages that have already been compiled.
+ */
+ public void taintPackagesDependingOnChangedPackages(Set<String> pkgs, Set<String> recentlyCompiled) {
+ for (Package pkg : prev.packages().values()) {
+ for (String dep : pkg.dependencies()) {
+ if (pkgs.contains(dep) && !recentlyCompiled.contains(pkg.name())) {
+ taintPackage(pkg.name(), " its depending on "+dep);
+ }
+ }
+ }
+ }
+
+ /**
+ * Scan all output dirs for artifacts and remove those files (artifacts?)
+ * that are not recognized as such, in the javac_state file.
+ */
+ public void removeUnidentifiedArtifacts() {
+ Set<File> allKnownArtifacts = new HashSet<File>();
+ for (Package pkg : prev.packages().values()) {
+ for (File f : pkg.artifacts().values()) {
+ allKnownArtifacts.add(f);
+ }
+ }
+ // Do not forget about javac_state....
+ allKnownArtifacts.add(javacState);
+
+ for (File f : binArtifacts) {
+ if (!allKnownArtifacts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+ f.delete();
+ }
+ }
+ for (File f : headerArtifacts) {
+ if (!allKnownArtifacts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+ f.delete();
+ }
+ }
+ for (File f : gensrcArtifacts) {
+ if (!allKnownArtifacts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
+ f.delete();
+ }
+ }
+ }
+
+ /**
+ * Remove artifacts that are no longer produced when compiling!
+ */
+ public void removeSuperfluousArtifacts(Set<String> recentlyCompiled) {
+ // Nothing to do, if nothing was recompiled.
+ if (recentlyCompiled.size() == 0) return;
+
+ for (String pkg : now.packages().keySet()) {
+ // If this package has not been recompiled, skip the check.
+ if (!recentlyCompiled.contains(pkg)) continue;
+ Collection<File> arts = now.artifacts().values();
+ for (File f : fetchPrevArtifacts(pkg).values()) {
+ if (!arts.contains(f)) {
+ Log.debug("Removing "+f.getPath()+" since it is now superfluous!");
+ if (f.exists()) f.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Return those files belonging to prev, but not now.
+ */
+ private Set<Source> calculateRemovedSources() {
+ Set<Source> removed = new HashSet<Source>();
+ for (String src : prev.sources().keySet()) {
+ if (now.sources().get(src) == null) {
+ removed.add(prev.sources().get(src));
+ }
+ }
+ return removed;
+ }
+
+ /**
+ * Return those files belonging to now, but not prev.
+ */
+ private Set<Source> calculateAddedSources() {
+ Set<Source> added = new HashSet<Source>();
+ for (String src : now.sources().keySet()) {
+ if (prev.sources().get(src) == null) {
+ added.add(now.sources().get(src));
+ }
+ }
+ return added;
+ }
+
+ /**
+ * Return those files where the timestamp is newer.
+ * If a source file timestamp suddenly is older than what is known
+ * about it in javac_state, then consider it modified, but print
+ * a warning!
+ */
+ private Set<Source> calculateModifiedSources() {
+ Set<Source> modified = new HashSet<Source>();
+ for (String src : now.sources().keySet()) {
+ Source n = now.sources().get(src);
+ Source t = prev.sources().get(src);
+ if (prev.sources().get(src) != null) {
+ if (t != null) {
+ if (n.lastModified() > t.lastModified()) {
+ modified.add(n);
+ } else if (n.lastModified() < t.lastModified()) {
+ modified.add(n);
+ Log.warn("The source file "+n.name()+" timestamp has moved backwards in time.");
+ }
+ }
+ }
+ }
+ return modified;
+ }
+
+ /**
+ * Recursively delete a directory and all its contents.
+ */
+ private static void deleteContents(File dir) {
+ if (dir != null && dir.exists()) {
+ for (File f : dir.listFiles()) {
+ if (f.isDirectory()) {
+ deleteContents(f);
+ }
+ f.delete();
+ }
+ }
+ }
+
+ /**
+ * Run the copy translator only.
+ */
+ public void performCopying(File binDir, Map<String,Transformer> suffixRules) {
+ Map<String,Transformer> sr = new HashMap<String,Transformer>();
+ for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
+ if (e.getValue() == copyFiles) {
+ sr.put(e.getKey(), e.getValue());
+ }
+ }
+ perform(binDir, sr);
+ }
+
+ /**
+ * Run all the translators that translate into java source code.
+ * I.e. all translators that are not copy nor compile_java_source.
+ */
+ public void performTranslation(File gensrcDir, Map<String,Transformer> suffixRules) {
+ Map<String,Transformer> sr = new HashMap<String,Transformer>();
+ for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
+ if (e.getValue() != copyFiles &&
+ e.getValue() != compileJavaPackages) {
+ sr.put(e.getKey(), e.getValue());
+ }
+ }
+ perform(gensrcDir, sr);
+ }
+
+ /**
+ * Compile all the java sources. Return true, if it needs to be called again!
+ */
+ public boolean performJavaCompilations(File binDir,
+ String serverSettings,
+ String[] args,
+ Set<String> recentlyCompiled,
+ boolean[] rcValue) {
+ Map<String,Transformer> suffixRules = new HashMap<String,Transformer>();
+ suffixRules.put(".java", compileJavaPackages);
+ compileJavaPackages.setExtra(serverSettings);
+ compileJavaPackages.setExtra(args);
+
+ rcValue[0] = perform(binDir, suffixRules);
+ recentlyCompiled.addAll(taintedPackages());
+ clearTaintedPackages();
+ boolean again = !packagesWithChangedPublicApis.isEmpty();
+ taintPackagesDependingOnChangedPackages(packagesWithChangedPublicApis, recentlyCompiled);
+ packagesWithChangedPublicApis = new HashSet<String>();
+ return again && rcValue[0];
+ }
+
+ /**
+ * Store the source into the set of sources belonging to the given transform.
+ */
+ private void addFileToTransform(Map<Transformer,Map<String,Set<URI>>> gs, Transformer t, Source s) {
+ Map<String,Set<URI>> fs = gs.get(t);
+ if (fs == null) {
+ fs = new HashMap<String,Set<URI>>();
+ gs.put(t, fs);
+ }
+ Set<URI> ss = fs.get(s.pkg().name());
+ if (ss == null) {
+ ss = new HashSet<URI>();
+ fs.put(s.pkg().name(), ss);
+ }
+ ss.add(s.file().toURI());
+ }
+
+ /**
+ * For all packages, find all sources belonging to the package, group the sources
+ * based on their transformers and apply the transformers on each source code group.
+ */
+ private boolean perform(File outputDir, Map<String,Transformer> suffixRules)
+ {
+ boolean rc = true;
+ // Group sources based on transforms. A source file can only belong to a single transform.
+ Map<Transformer,Map<String,Set<URI>>> groupedSources = new HashMap<Transformer,Map<String,Set<URI>>>();
+ for (Source src : now.sources().values()) {
+ Transformer t = suffixRules.get(src.suffix());
+ if (t != null) {
+ if (taintedPackages.contains(src.pkg().name()) && !src.isLinkedOnly()) {
+ addFileToTransform(groupedSources, t, src);
+ }
+ }
+ }
+ // Go through the transforms and transform them.
+ for (Map.Entry<Transformer,Map<String,Set<URI>>> e : groupedSources.entrySet()) {
+ Transformer t = e.getKey();
+ Map<String,Set<URI>> srcs = e.getValue();
+ // These maps need to be synchronized since multiple threads will be writing results into them.
+ Map<String,Set<URI>> packageArtifacts = Collections.synchronizedMap(new HashMap<String,Set<URI>>());
+ Map<String,Set<String>> packageDependencies = Collections.synchronizedMap(new HashMap<String,Set<String>>());
+ Map<String,String> packagePublicApis = Collections.synchronizedMap(new HashMap<String,String>());
+
+ boolean r = t.transform(srcs,
+ visibleSrcs,
+ visibleClasses,
+ prev.dependents(),
+ outputDir.toURI(),
+ packageArtifacts,
+ packageDependencies,
+ packagePublicApis,
+ 0,
+ isIncremental(),
+ numCores,
+ out,
+ err);
+ if (!r) rc = false;
+
+ for (String p : srcs.keySet()) {
+ recompiledPackages.add(p);
+ }
+ // The transform is done! Extract all the artifacts and store the info into the Package objects.
+ for (Map.Entry<String,Set<URI>> a : packageArtifacts.entrySet()) {
+ Module mnow = now.findModuleFromPackageName(a.getKey());
+ mnow.addArtifacts(a.getKey(), a.getValue());
+ }
+ // Extract all the dependencies and store the info into the Package objects.
+ for (Map.Entry<String,Set<String>> a : packageDependencies.entrySet()) {
+ Set<String> deps = a.getValue();
+ Module mnow = now.findModuleFromPackageName(a.getKey());
+ mnow.setDependencies(a.getKey(), deps);
+ }
+ // Extract all the pubapis and store the info into the Package objects.
+ for (Map.Entry<String,String> a : packagePublicApis.entrySet()) {
+ Module mprev = prev.findModuleFromPackageName(a.getKey());
+ List<String> pubapi = Package.pubapiToList(a.getValue());
+ Module mnow = now.findModuleFromPackageName(a.getKey());
+ mnow.setPubapi(a.getKey(), pubapi);
+ if (mprev.hasPubapiChanged(a.getKey(), pubapi)) {
+ // Aha! The pubapi of this package has changed!
+ // It can also be a new compile from scratch.
+ if (mprev.lookupPackage(a.getKey()).existsInJavacState()) {
+ // This is an incremental compile! The pubapi
+ // did change. Trigger recompilation of dependents.
+ packagesWithChangedPublicApis.add(a.getKey());
+ Log.info("The pubapi of "+Util.justPackageName(a.getKey())+" has changed!");
+ }
+ }
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Utility method to recursively find all files below a directory.
+ */
+ private static Set<File> findAllFiles(File dir) {
+ Set<File> foundFiles = new HashSet<File>();
+ if (dir == null) {
+ return foundFiles;
+ }
+ recurse(dir, foundFiles);
+ return foundFiles;
+ }
+
+ private static void recurse(File dir, Set<File> foundFiles) {
+ for (File f : dir.listFiles()) {
+ if (f.isFile()) {
+ foundFiles.add(f);
+ } else if (f.isDirectory()) {
+ recurse(f, foundFiles);
+ }
+ }
+ }
+
+ /**
+ * Compare the calculate source list, with an explicit list, usually supplied from the makefile.
+ * Used to detect bugs where the makefile and sjavac have different opinions on which files
+ * should be compiled.
+ */
+ public void compareWithMakefileList(File makefileSourceList)
+ throws ProblemException
+ {
+ // If we are building on win32 using for example cygwin the paths in the makefile source list
+ // might be /cygdrive/c/.... which does not match c:\....
+ // We need to adjust our calculated sources to be identical, if necessary.
+ boolean mightNeedRewriting = File.pathSeparatorChar == ';';
+
+ if (makefileSourceList == null) return;
+
+ Set<String> calculatedSources = new HashSet<String>();
+ Set<String> listedSources = new HashSet<String>();
+
+ // Create a set of filenames with full paths.
+ for (Source s : now.sources().values()) {
+ calculatedSources.add(s.file().getPath());
+ }
+ // Read in the file and create another set of filenames with full paths.
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(makefileSourceList));
+ for (;;) {
+ String l = in.readLine();
+ if (l==null) break;
+ l = l.trim();
+ if (mightNeedRewriting) {
+ if (l.indexOf(":") == 1 && l.indexOf("\\") == 2) {
+ // Everything a-ok, the format is already C:\foo\bar
+ } else if (l.indexOf(":") == 1 && l.indexOf("/") == 2) {
+ // The format is C:/foo/bar, rewrite into the above format.
+ l = l.replaceAll("/","\\\\");
+ } else if (l.charAt(0) == '/' && l.indexOf("/",1) != -1) {
+ // The format might be: /cygdrive/c/foo/bar, rewrite into the above format.
+ // Do not hardcode the name cygdrive here.
+ int slash = l.indexOf("/",1);
+ l = l.replaceAll("/","\\\\");
+ l = ""+l.charAt(slash+1)+":"+l.substring(slash+2);
+ }
+ if (Character.isLowerCase(l.charAt(0))) {
+ l = Character.toUpperCase(l.charAt(0))+l.substring(1);
+ }
+ }
+ listedSources.add(l);
+ }
+ } catch (FileNotFoundException e) {
+ throw new ProblemException("Could not open "+makefileSourceList.getPath()+" since it does not exist!");
+ } catch (IOException e) {
+ throw new ProblemException("Could not read "+makefileSourceList.getPath());
+ }
+
+ for (String s : listedSources) {
+ if (!calculatedSources.contains(s)) {
+ throw new ProblemException("The makefile listed source "+s+" was not calculated by the smart javac wrapper!");
+ }
+ }
+
+ for (String s : calculatedSources) {
+ if (!listedSources.contains(s)) {
+ throw new ProblemException("The smart javac wrapper calculated source "+s+" was not listed by the makefiles!");
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.PrintStream;
+
+/**
+ * Utility class only for sjavac logging.
+ * The log level can be set using for example --log=DEBUG on the sjavac command line.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Log {
+ private static PrintStream out, err;
+
+ public final static int WARN = 1;
+ public final static int INFO = 2;
+ public final static int DEBUG = 3;
+ public final static int TRACE = 4;
+ private static int level = WARN;
+
+ static public void trace(String msg) {
+ if (level >= TRACE) {
+ out.println(msg);
+ }
+ }
+
+ static public void debug(String msg) {
+ if (level >= DEBUG) {
+ out.println(msg);
+ }
+ }
+
+ static public void info(String msg) {
+ if (level >= INFO) {
+ out.println(msg);
+ }
+ }
+
+ static public void warn(String msg) {
+ err.println(msg);
+ }
+
+ static public void error(String msg) {
+ err.println(msg);
+ }
+
+ static public void setLogLevel(String l, PrintStream o, PrintStream e)
+ throws ProblemException {
+ out = o;
+ err = e;
+ if (l.equals("warn")) level = WARN;
+ else if (l.equals("info")) level = INFO;
+ else if (l.equals("debug")) level = DEBUG;
+ else if (l.equals("trace")) level = TRACE;
+ else throw new ProblemException("No such log level \""+l+"\"");
+ }
+
+ static public boolean isTracing() {
+ return level >= TRACE;
+ }
+
+ static public boolean isDebugging() {
+ return level >= DEBUG;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,969 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import com.sun.tools.sjavac.server.JavacServer;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.*;
+
+/**
+ * The main class of the smart javac wrapper tool.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Main {
+
+ /* This is a smart javac wrapper primarily used when building the OpenJDK,
+ though other projects are welcome to use it too. But please be aware
+ that it is not an official api and will change in the future.
+ (We really mean it!)
+
+ Goals:
+
+ ** Create a state file, containing information about the build, so
+ that incremental builds only rebuild what is necessary. Also the
+ state file can be used by make/ant to detect when to trigger
+ a call to the smart javac wrapper.
+
+ This file is called bin/javac_state (assuming that you specified "-d bin")
+ Thus the simplest makefile is:
+
+ SJAVAC=java -cp .../tools.jar com.sun.tools.sjavac.Main
+ SRCS=$(shell find src -name "*.java")
+ bin/javac_state : $(SRCS)
+ $(SJAVAC) src -d bin
+
+ This makefile will run very fast and detect properly when Java code needs to
+ be recompiled. The smart javac wrapper will then use the information in java_state
+ to do an efficient incremental compile.
+
+ Previously it was near enough impossible to write an efficient makefile for Java
+ with support for incremental builds and dependency tracking.
+
+ ** Separate java sources to be compiled from java
+ sources used >only< for linking. The options:
+
+ "dir" points to root dir with sources to be compiled
+ "-sourcepath dir" points to root dir with sources used only for linking
+ "-classpath dir" points to dir with classes used only for linking (as before)
+
+ ** Use all cores for compilation by default.
+ "-j 4" limit the number of cores to 4.
+ For the moment, the sjavac server additionally limits the number of cores to three.
+ This will improve in the future when more sharing is performed between concurrent JavaCompilers.
+
+ ** Basic translation support from other sources to java, and then compilation of the generated java.
+ This functionality might be moved into annotation processors instead.
+ Again this is driven by the OpenJDK sources where properties and a few other types of files
+ are converted into Java sources regularily. The javac_state embraces copy and tr, and perform
+ incremental recompiles and copying for these as well. META-INF will be a special copy rule
+ that will copy any files found below any META-INF dir in src to the bin/META-INF dir.
+ "-copy .gif"
+ "-copy META-INF"
+ "-tr .prop=com.sun.tools.javac.smart.CompileProperties
+ "-tr .propp=com.sun.tools.javac.smart.CompileProperties,java.util.ListResourceBundle
+ "-tr .proppp=com.sun.tools.javac.smart.CompileProperties,sun.util.resources.LocaleNamesBundle
+
+ ** Control which classes in the src,sourcepath and classpath that javac is allowed to see.
+ Again, this is necessary to deal with the source code structure of the OpenJDK which is
+ intricate (read messy).
+
+ "-i tools.*" to include the tools package and all its subpackages in the build.
+ "-x tools.net.aviancarrier.*" to exclude the aviancarrier package and all its sources and subpackages.
+ "-x tools.net.drums" to exclude the drums package only, keep its subpackages.
+ "-xf tools/net/Bar.java" // Do not compile this file...
+ "-xf *Bor.java" // Do not compile Bor.java wherever it is found, BUT do compile ABor.java!
+ "-if tools/net/Bor.java" // Only compile this file...odd, but sometimes used.
+
+ ** The smart javac wrapper is driven by the modification time on the source files and compared
+ to the modification times written into the javac_state file.
+
+ It does not compare the modification time of the source with the modification time of the artifact.
+ However it will detect if the modification time of an artifact has changed compared to the java_state,
+ and this will trigger a delete of the artifact and a subsequent recompile of the source.
+
+ The smart javac wrapper is not a generic makefile/ant system. Its purpose is to compile java source
+ as the final step before the output dir is finalized and immediately jared, or jmodded. The output
+ dir should be considered opaque. Do not write into the outputdir yourself!
+ Any artifacts found in the outputdir that javac_state does not know of, will be deleted!
+ This can however be prevented, using the switch --permit-unidentified-artifacts
+ This switch is necessary when build the OpenJDK because its makefiles still write directly to
+ the output classes dirs.
+
+ Any makefile/ant rules that want to put contents into the outputdir should put the content
+ in one of several source roots. Static content that is under version control, can be put in the same source
+ code tree as the Java sources. Dynamic content that is generated by make/ant on the fly, should
+ be put in a separate gensrc_stuff root. The smart javac wrapper call will then take the arguments:
+ "gensrc_stuff src -d bin"
+
+ The command line:
+ java -cp tools.jar com.sun.tools.sjavac.Main \
+ -i "com.bar.*" -x "com.bar.foo.*" \
+ first_root \
+ -i "com.bar.foo.*" \
+ second_root \
+ -x "org.net.*" \
+ -sourcepath link_root_sources \
+ -classpath link_root_classes \
+ -d bin
+
+ Will compile all sources for package com.bar and its subpackages, found below first_root,
+ except the package com.bar.foo (and its subpackages), for which the sources are picked
+ from second_root instead. It will link against classes in link_root_classes and against
+ sources in link_root_sources, but will not see (try to link against) sources matching org.net.*
+ but will link against org.net* classes (if they exist) in link_root_classes.
+
+ (If you want a set of complex filter rules to be applied to several source directories, without
+ having to repeat the the filter rules for each root. You can use the explicit -src option. For example:
+ sjavac -x "com.foo.*" -src root1:root2:root3 )
+
+ The resulting classes are written into bin.
+ */
+
+ // This is the final destination for classes and copied files.
+ private File bin_dir;
+ // This is where the annotation process will put generated sources.
+ private File gensrc_dir;
+ // This is where javac -h puts the generated c-header files.
+ private File header_dir;
+
+ // This file contains the list of sources genereated by the makefile.
+ // We double check that our calculated list of sources matches this list,
+ // if not, then we terminate with an error!
+ private File makefile_source_list;
+ // The challenging task to manage an incremental build is done by javac_state.
+ private JavacState javac_state;
+
+ // The suffix rules tells you for example, that .java files should be compiled,
+ // and .html files should be copied and .properties files be translated.
+ Map<String,Transformer> suffix_rules;
+
+ public static void main(String... args) {
+ if (args.length > 0 && args[0].startsWith("--startserver:")) {
+ if (args.length>1) {
+ Log.error("When spawning a background server, only a single --startserver argument is allowed.");
+ return;
+ }
+ // Spawn a background server.
+ int rc = JavacServer.startServer(args[0], System.err);
+ System.exit(rc);
+ }
+ Main main = new Main();
+ int rc = main.go(args, System.out, System.err);
+ // Remove the portfile, but only if this background=false was used.
+ JavacServer.cleanup(args);
+ System.exit(rc);
+ }
+
+ private void printHelp() {
+ System.out.println("Usage: sjavac <options>\n"+
+ "where required options are:\n"+
+ "dir Compile all sources in dir recursively\n"+
+ "-d dir Store generated classes here and the javac_state file\n"+
+ "--server:portfile=/tmp/abc Use a background sjavac server\n\n"+
+ "All other arguments as javac, except -implicit:none which is forced by default.\n"+
+ "No java source files can be supplied on the command line, nor can an @file be supplied.\n\n"+
+ "Warning!\n"+
+ "This tool might disappear at any time, and its command line options might change at any time!");
+ }
+
+ public int go(String[] args, PrintStream out, PrintStream err) {
+ try {
+ if (args.length == 0 || findJavaSourceFiles(args) || findAtFile(args) || null==Util.findServerSettings(args)) {
+ printHelp();
+ return 0;
+ }
+
+ Log.setLogLevel(findLogLevel(args), out, err);
+ String server_settings = Util.findServerSettings(args);
+ args = verifyImplicitOption(args);
+ // Find the source root directories, and add the -src option before these, if not there already.
+ args = addSrcBeforeDirectories(args);
+ // Check that there is at least one -src supplied.
+ checkSrcOption(args);
+ // Check that there is one -d supplied.
+ bin_dir = findDirectoryOption(args,"-d","output", true, false, true);
+ gensrc_dir = findDirectoryOption(args,"-s","gensrc", false, false, true);
+ header_dir = findDirectoryOption(args,"-h","headers", false, false, true);
+ makefile_source_list = findFileOption(args,"--compare-found-sources","makefile source list", false);
+
+ // Load the prev build state database.
+ javac_state = JavacState.load(args, bin_dir, gensrc_dir, header_dir,
+ findBooleanOption(args, "--permit-unidentified-artifacts"), out, err);
+
+ // Setup the suffix rules from the command line.
+ suffix_rules = javac_state.getJavaSuffixRule();
+ findTranslateOptions(args, suffix_rules);
+ if (suffix_rules.keySet().size() > 1 && gensrc_dir == null) {
+ Log.error("You have translators but no gensrc dir (-s) specified!");
+ return -1;
+ }
+ findCopyOptions(args, suffix_rules);
+
+ // All found modules are put here.
+ Map<String,Module> modules = new HashMap<String,Module>();
+ // We start out in the legacy empty no-name module.
+ // As soon as we stumble on a module-info.java file we change to that module.
+ Module current_module = new Module("", "");
+ modules.put("", current_module);
+
+ // Find all sources, use the suffix rules to know which files are sources.
+ Map<String,Source> sources = new HashMap<String,Source>();
+ // Find the files, this will automatically populate the found modules
+ // with found packages where the sources are found!
+ findFiles(args, "-src", suffix_rules.keySet(), sources, modules, current_module, false);
+
+ if (sources.isEmpty()) {
+ Log.error("Found nothing to compile!");
+ return -1;
+ }
+
+ // Find all source files allowable for linking.
+ // We might find more modules here as well.
+ Map<String,Source> sources_to_link_to = new HashMap<String,Source>();
+ // Always reuse -src for linking as well! This means that we might
+ // get two -sourcepath on the commandline after the rewrite, which is
+ // fine. We can have as many as we like. You need to have separate -src/-sourcepath/-classpath
+ // if you need different filtering rules for different roots. If you have the same filtering
+ // rules for all sourcepath roots, you can concatenate them using :(;) as before.
+ rewriteOptions(args, "-src", "-sourcepath");
+ findFiles(args, "-sourcepath", Util.set(".java"), sources_to_link_to, modules, current_module, true);
+
+ // Find all class files allowable for linking.
+ // And pickup knowledge of all modules found here.
+ // This cannot currently filter classes inside jar files.
+ Map<String,Source> classes_to_link_to = new HashMap<String,Source>();
+// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true);
+
+ // Find all module sources allowable for linking.
+ Map<String,Source> modules_to_link_to = new HashMap<String,Source>();
+ // findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true);
+
+ // Add the set of sources to the build database.
+ javac_state.now().collectPackagesSourcesAndArtifacts(modules);
+ javac_state.now().checkInternalState("checking sources", false, sources);
+ javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
+ javac_state.setVisibleSources(sources_to_link_to);
+
+ // If there is any change in the source files, taint packages
+ // and mark the database in need of saving.
+ javac_state.checkSourceStatus(false);
+
+ // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
+ // in javac_state, simply because loading of the JavacState will clean out all artifacts
+ // that do not match the javac_state database.
+ javac_state.findAllArtifacts();
+
+ // Remove unidentified artifacts from the bin, gensrc and header dirs.
+ // (Unless we allow them to be there.)
+ // I.e. artifacts that are not known according to the build database (javac_state).
+ // For examples, files that have been manually copied into these dirs.
+ // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
+ // in javac_state) have already been removed when the javac_state was loaded.
+ if (!findBooleanOption(args, "--permit-unidentified-artifacts")) {
+ javac_state.removeUnidentifiedArtifacts();
+ }
+ // Go through all sources and taint all packages that miss artifacts.
+ javac_state.taintPackagesThatMissArtifacts();
+
+ // Now clean out all known artifacts belonging to tainted packages.
+ javac_state.deleteClassArtifactsInTaintedPackages();
+ // Copy files, for example property files, images files, xml files etc etc.
+ javac_state.performCopying(bin_dir, suffix_rules);
+ // Translate files, for example compile properties or compile idls.
+ javac_state.performTranslation(gensrc_dir, suffix_rules);
+ // Add any potentially generated java sources to the tobe compiled list.
+ // (Generated sources must always have a package.)
+ Map<String,Source> generated_sources = new HashMap<String,Source>();
+ Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null,
+ generated_sources, modules, current_module, false, true, false);
+ javac_state.now().collectPackagesSourcesAndArtifacts(modules);
+ // Recheck the the source files and their timestamps again.
+ javac_state.checkSourceStatus(true);
+
+ // Now do a safety check that the list of source files is identical
+ // to the list Make believes we are compiling. If we do not get this
+ // right, then incremental builds will fail with subtility.
+ // If any difference is detected, then we will fail hard here.
+ // This is an important safety net.
+ javac_state.compareWithMakefileList(makefile_source_list);
+
+ // Do the compilations, repeatedly until no tainted packages exist.
+ boolean again;
+ // Collect the name of all compiled packages.
+ Set<String> recently_compiled = new HashSet<String>();
+ boolean[] rc = new boolean[1];
+ do {
+ // Clean out artifacts in tainted packages.
+ javac_state.deleteClassArtifactsInTaintedPackages();
+ again = javac_state.performJavaCompilations(bin_dir, server_settings, args, recently_compiled, rc);
+ if (!rc[0]) break;
+ } while (again);
+ // Only update the state if the compile went well.
+ if (rc[0]) {
+ javac_state.save();
+ // Collect all the artifacts.
+ javac_state.now().collectArtifacts(modules);
+ // Remove artifacts that were generated during the last compile, but not this one.
+ javac_state.removeSuperfluousArtifacts(recently_compiled);
+ }
+ return rc[0] ? 0 : -1;
+ } catch (ProblemException e) {
+ Log.error(e.getMessage());
+ return -1;
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ return -1;
+ }
+ }
+
+ /**
+ * Are java source files passed on the command line?
+ */
+ private boolean findJavaSourceFiles(String[] args) {
+ String prev = "";
+ for (String s : args) {
+ if (s.endsWith(".java") && !prev.equals("-xf") && !prev.equals("-if")) {
+ return true;
+ }
+ prev = s;
+ }
+ return false;
+ }
+
+ /**
+ * Is an at file passed on the command line?
+ */
+ private boolean findAtFile(String[] args) {
+ for (String s : args) {
+ if (s.startsWith("@")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Find the log level setting.
+ */
+ private String findLogLevel(String[] args) {
+ for (String s : args) {
+ if (s.startsWith("--log=") && s.length()>6) {
+ return s.substring(6);
+ }
+ if (s.equals("-verbose")) {
+ return "info";
+ }
+ }
+ return "info";
+ }
+
+ /**
+ * Remove smart javac wrapper arguments, before feeding
+ * the args to the plain javac.
+ */
+ static String[] removeWrapperArgs(String[] args) {
+ String[] out = new String[args.length];
+ // The first source path index is remembered
+ // here. So that all following can be concatenated to it.
+ int source_path = -1;
+ // The same for class path.
+ int class_path = -1;
+ // And module path.
+ int module_path = -1;
+ int j = 0;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-src") ||
+ args[i].equals("-x") ||
+ args[i].equals("-i") ||
+ args[i].equals("-xf") ||
+ args[i].equals("-if") ||
+ args[i].equals("-copy") ||
+ args[i].equals("-tr") ||
+ args[i].equals("-j")) {
+ // Just skip it and skip following value
+ i++;
+ } else if (args[i].startsWith("--server:")) {
+ // Just skip it.
+ } else if (args[i].startsWith("--log=")) {
+ // Just skip it.
+ } else if (args[i].equals("--permit-unidentified-artifacts")) {
+ // Just skip it.
+ } else if (args[i].equals("--permit-sources-without-package")) {
+ // Just skip it.
+ } else if (args[i].equals("--compare-found-sources")) {
+ // Just skip it and skip verify file name
+ i++;
+ } else if (args[i].equals("-sourcepath")) {
+ if (source_path == -1) {
+ source_path = j;
+ out[j] = args[i];
+ out[j+1] = args[i+1];
+ j+=2;
+ i++;
+ } else {
+ // Skip this and its argument, but
+ // append argument to found sourcepath.
+ out[source_path+1] = out[source_path+1]+File.pathSeparatorChar+args[i+1];
+ i++;
+ }
+ } else if (args[i].equals("-classpath")) {
+ if (class_path == -1) {
+ class_path = j;
+ out[j] = args[i];
+ out[j+1] = args[i+1];
+ j+=2;
+ i++;
+ } else {
+ // Skip this and its argument, but
+ // append argument to found sourcepath.
+ out[class_path+1] = out[class_path+1]+File.pathSeparatorChar+args[i+1];
+ i++;
+ }
+ } else if (args[i].equals("-modulepath")) {
+ if (module_path == -1) {
+ module_path = j;
+ out[j] = args[i];
+ out[j+1] = args[i+1];
+ j+=2;
+ i++;
+ } else {
+ // Skip this and its argument, but
+ // append argument to found sourcepath.
+ out[module_path+1] = out[module_path+1]+File.pathSeparatorChar+args[i+1];
+ i++;
+ }
+ } else {
+ // Copy argument.
+ out[j] = args[i];
+ j++;
+ }
+ }
+ String[] ret = new String[j];
+ System.arraycopy(out, 0, ret, 0, j);
+ return ret;
+ }
+
+ /**
+ * Make sure directory exist, create it if not.
+ */
+ private static boolean makeSureExists(File dir) {
+ // Make sure the dest directories exist.
+ if (!dir.exists()) {
+ if (!dir.mkdirs()) {
+ Log.error("Could not create the directory "+dir.getPath());
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Verify that a package pattern is valid.
+ */
+ private static void checkPattern(String s) throws ProblemException {
+ // Package names like foo.bar.gamma are allowed, and
+ // package names suffixed with .* like foo.bar.* are
+ // also allowed.
+ Pattern p = Pattern.compile("[a-zA-Z_]{1}[a-zA-Z0-9_]*(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)*(\\.\\*)?+");
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper package name pattern.");
+ }
+ }
+
+ /**
+ * Verify that a translate pattern is valid.
+ */
+ private static void checkTranslatePattern(String s) throws ProblemException {
+ // .prop=com.sun.tools.javac.smart.CompileProperties
+ // .idl=com.sun.corba.CompileIdl
+ // .g3=antlr.CompileGrammar,debug=true
+ Pattern p = Pattern.compile(
+ "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*=[a-z_]{1}[a-z0-9_]*(\\.[a-z_]{1}[a-z0-9_]*)*"+
+ "(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)(,.*)?");
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper translate pattern.");
+ }
+ }
+
+ /**
+ * Verify that a copy pattern is valid.
+ */
+ private static void checkCopyPattern(String s) throws ProblemException {
+ // .gif
+ // .html
+ Pattern p = Pattern.compile(
+ "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*");
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper suffix.");
+ }
+ }
+
+ /**
+ * Verify that a source file name is valid.
+ */
+ private static void checkFilePattern(String s) throws ProblemException {
+ // File names like foo/bar/gamma/Bar.java are allowed,
+ // as well as /bar/jndi.properties as well as,
+ // */bar/Foo.java
+ Pattern p = null;
+ if (File.separatorChar == '\\') {
+ p = Pattern.compile("\\*?(.+\\\\)*.+");
+ }
+ else if (File.separatorChar == '/') {
+ p = Pattern.compile("\\*?(.+/)*.+");
+ } else {
+ throw new ProblemException("This platform uses the unsupported "+File.separatorChar+
+ " as file separator character. Please add support for it!");
+ }
+ Matcher m = p.matcher(s);
+ if (!m.matches()) {
+ throw new ProblemException("The string \""+s+"\" is not a proper file name.");
+ }
+ }
+
+ /**
+ * Scan the arguments to find an option is used.
+ */
+ private static boolean hasOption(String[] args, String option) {
+ for (String a : args) {
+ if (a.equals(option)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if -implicit is supplied, if so check that it is none.
+ * If -implicit is not supplied, supply -implicit:none
+ * Only implicit:none is allowed because otherwise the multicore compilations
+ * and dependency tracking will be tangled up.
+ */
+ private static String[] verifyImplicitOption(String[] args)
+ throws ProblemException {
+
+ boolean foundImplicit = false;
+ for (String a : args) {
+ if (a.startsWith("-implicit:")) {
+ foundImplicit = true;
+ if (!a.equals("-implicit:none")) {
+ throw new ProblemException("The only allowed setting for sjavac is -implicit:none, it is also the default.");
+ }
+ }
+ }
+ if (foundImplicit) {
+ return args;
+ }
+ // -implicit:none not found lets add it.
+ String[] newargs = new String[args.length+1];
+ System.arraycopy(args,0, newargs, 0, args.length);
+ newargs[args.length] = "-implicit:none";
+ return newargs;
+ }
+
+ /**
+ * Rewrite a single option into something else.
+ */
+ private static void rewriteOptions(String[] args, String option, String new_option) {
+ for (int i=0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ args[i] = new_option;
+ }
+ }
+ }
+
+ /**
+ * Scan the arguments to find an option that specifies a directory.
+ * Create the directory if necessary.
+ */
+ private static File findDirectoryOption(String[] args, String option, String name, boolean needed, boolean allow_dups, boolean create)
+ throws ProblemException, ProblemException {
+ File dir = null;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ if (dir != null) {
+ throw new ProblemException("You have already specified the "+name+" dir!");
+ }
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a directory following "+option+".");
+ }
+ if (args[i+1].indexOf(File.pathSeparatorChar) != -1) {
+ throw new ProblemException("You must only specify a single directory for "+option+".");
+ }
+ dir = new File(args[i+1]);
+ if (!dir.exists()) {
+ if (!create) {
+ throw new ProblemException("This directory does not exist: "+dir.getPath());
+ } else
+ if (!makeSureExists(dir)) {
+ throw new ProblemException("Cannot create directory "+dir.getPath());
+ }
+ }
+ if (!dir.isDirectory()) {
+ throw new ProblemException("\""+args[i+1]+"\" is not a directory.");
+ }
+ }
+ }
+ if (dir == null && needed) {
+ throw new ProblemException("You have to specify "+option);
+ }
+ try {
+ if (dir != null)
+ return dir.getCanonicalFile();
+ } catch (IOException e) {
+ throw new ProblemException(""+e);
+ }
+ return null;
+ }
+
+ /**
+ * Option is followed by path.
+ */
+ private static boolean shouldBeFollowedByPath(String o) {
+ return o.equals("-s") ||
+ o.equals("-h") ||
+ o.equals("-d") ||
+ o.equals("-sourcepath") ||
+ o.equals("-classpath") ||
+ o.equals("-bootclasspath") ||
+ o.equals("-src");
+ }
+
+ /**
+ * Add -src before source root directories if not already there.
+ */
+ private static String[] addSrcBeforeDirectories(String[] args) {
+ List<String> newargs = new ArrayList<String>();
+ for (int i = 0; i<args.length; ++i) {
+ File dir = new File(args[i]);
+ if (dir.exists() && dir.isDirectory()) {
+ if (i == 0 || !shouldBeFollowedByPath(args[i-1])) {
+ newargs.add("-src");
+ }
+ }
+ newargs.add(args[i]);
+ }
+ return newargs.toArray(new String[0]);
+ }
+
+ /**
+ * Check the -src options.
+ */
+ private static void checkSrcOption(String[] args)
+ throws ProblemException {
+ Set<File> dirs = new HashSet<File>();
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-src")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a directory following -src.");
+ }
+ StringTokenizer st = new StringTokenizer(args[i+1], File.pathSeparator);
+ while (st.hasMoreElements()) {
+ File dir = new File(st.nextToken());
+ if (!dir.exists()) {
+ throw new ProblemException("This directory does not exist: "+dir.getPath());
+ }
+ if (!dir.isDirectory()) {
+ throw new ProblemException("\""+dir.getPath()+"\" is not a directory.");
+ }
+ if (dirs.contains(dir)) {
+ throw new ProblemException("The src directory \""+dir.getPath()+"\" is specified more than once!");
+ }
+ dirs.add(dir);
+ }
+ }
+ }
+ if (dirs.isEmpty()) {
+ throw new ProblemException("You have to specify -src.");
+ }
+ }
+
+ /**
+ * Scan the arguments to find an option that specifies a file.
+ */
+ private static File findFileOption(String[] args, String option, String name, boolean needed)
+ throws ProblemException, ProblemException {
+ File file = null;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ if (file != null) {
+ throw new ProblemException("You have already specified the "+name+" file!");
+ }
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a file following "+option+".");
+ }
+ file = new File(args[i+1]);
+ if (file.isDirectory()) {
+ throw new ProblemException("\""+args[i+1]+"\" is not a file.");
+ }
+ if (!file.exists() && needed) {
+ throw new ProblemException("The file \""+args[i+1]+"\" does not exist.");
+ }
+
+ }
+ }
+ if (file == null && needed) {
+ throw new ProblemException("You have to specify "+option);
+ }
+ return file;
+ }
+
+ /**
+ * Look for a specific switch, return true if found.
+ */
+ public static boolean findBooleanOption(String[] args, String option) {
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Scan the arguments to find an option that specifies a number.
+ */
+ public static int findNumberOption(String[] args, String option) {
+ int rc = 0;
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals(option)) {
+ if (args.length > i+1) {
+ rc = Integer.parseInt(args[i+1]);
+ }
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Scan the arguments to find the option (-tr) that setup translation rules to java source
+ * from different sources. For example: .properties are translated using CompileProperties
+ * The found translators are stored as suffix rules.
+ */
+ private static void findTranslateOptions(String[] args, Map<String,Transformer> suffix_rules)
+ throws ProblemException, ProblemException {
+
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-tr")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a translate rule following -tr.");
+ }
+ String s = args[i+1];
+ checkTranslatePattern(s);
+ int ep = s.indexOf("=");
+ String suffix = s.substring(0,ep);
+ String classname = s.substring(ep+1);
+ if (suffix_rules.get(suffix) != null) {
+ throw new ProblemException("You have already specified a "+
+ "rule for the suffix "+suffix);
+ }
+ if (s.equals(".class")) {
+ throw new ProblemException("You cannot have a translator for .class files!");
+ }
+ if (s.equals(".java")) {
+ throw new ProblemException("You cannot have a translator for .java files!");
+ }
+ String extra = null;
+ int exp = classname.indexOf(",");
+ if (exp != -1) {
+ extra = classname.substring(exp+1);
+ classname = classname.substring(0,exp);
+ }
+ try {
+ Class<?> cl = Class.forName(classname);
+ Transformer t = (Transformer)cl.newInstance();
+ t.setExtra(extra);
+ suffix_rules.put(suffix, t);
+ }
+ catch (Exception e) {
+ throw new ProblemException("Cannot use "+classname+" as a translator!");
+ }
+ }
+ }
+ }
+
+ /**
+ * Scan the arguments to find the option (-copy) that setup copying rules into the bin dir.
+ * For example: -copy .html
+ * The found copiers are stored as suffix rules as well. No translation is done, just copying.
+ */
+ private void findCopyOptions(String[] args, Map<String,Transformer> suffix_rules)
+ throws ProblemException, ProblemException {
+
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-copy")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a translate rule following -tr.");
+ }
+ String s = args[i+1];
+ checkCopyPattern(s);
+ if (suffix_rules.get(s) != null) {
+ throw new ProblemException("You have already specified a "+
+ "rule for the suffix "+s);
+ }
+ if (s.equals(".class")) {
+ throw new ProblemException("You cannot have a copy rule for .class files!");
+ }
+ if (s.equals(".java")) {
+ throw new ProblemException("You cannot have a copy rule for .java files!");
+ }
+ suffix_rules.put(s, javac_state.getCopier());
+ }
+ }
+ }
+
+ /**
+ * Rewrite a / separated path into \ separated, but only
+ * if we are running on a platform were File.separatorChar=='\', ie winapi.
+ */
+ private String fixupSeparator(String p) {
+ if (File.separatorChar == '/') return p;
+ return p.replaceAll("/", "\\\\");
+ }
+
+ /**
+ * Scan the arguments for -i -x -xf -if followed by the option
+ * -src, -sourcepath, -modulepath or -classpath and produce a map of all the
+ * files to referenced for that particular option.
+ *
+ * Store the found sources and the found modules in the supplied maps.
+ */
+ private boolean findFiles(String[] args, String option, Set<String> suffixes,
+ Map<String,Source> found_files, Map<String, Module> found_modules,
+ Module current_module, boolean inLinksrc)
+ throws ProblemException, ProblemException
+ {
+ // Track which source roots, source path roots and class path roots have been added.
+ Set<File> roots = new HashSet<File>();
+ // Track the current set of package includes,excludes as well as excluded source files,
+ // to be used in the next -src/-sourcepath/-classpath
+ List<String> includes = new LinkedList<String>();
+ List<String> excludes = new LinkedList<String>();
+ List<String> excludefiles = new LinkedList<String>();
+ List<String> includefiles = new LinkedList<String>();
+ // This include is used to find all modules in the source.
+ List<String> moduleinfo = new LinkedList<String>();
+ moduleinfo.add("module-info.java");
+
+ for (int i = 0; i<args.length; ++i) {
+ if (args[i].equals("-i")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a package pattern following -i");
+ }
+ String incl = args[i+1];
+ checkPattern(incl);
+ includes.add(incl);
+ }
+ if (args[i].equals("-x")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a package pattern following -x");
+ }
+ String excl = args[i+1];
+ checkPattern(excl);
+ excludes.add(excl);
+ }
+ if (args[i].equals("-xf")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a file following -xf");
+ }
+ String exclf = args[i+1];
+ checkFilePattern(exclf);
+ exclf = Util.normalizeDriveLetter(exclf);
+ excludefiles.add(fixupSeparator(exclf));
+ }
+ if (args[i].equals("-if")) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a file following -xf");
+ }
+ String inclf = args[i+1];
+ checkFilePattern(inclf);
+ inclf = Util.normalizeDriveLetter(inclf);
+ includefiles.add(fixupSeparator(inclf));
+ }
+ if (args[i].equals(option)) {
+ if (i+1 >= args.length) {
+ throw new ProblemException("You have to specify a directory following "+option);
+ }
+ String[] root_dirs = args[i+1].split(File.pathSeparator);
+ for (String r : root_dirs) {
+ File root = new File(r);
+ if (!root.isDirectory()) {
+ throw new ProblemException("\""+r+"\" is not a directory.");
+ }
+ try {
+ root = root.getCanonicalFile();
+ } catch (IOException e) {
+ throw new ProblemException(""+e);
+ }
+ if (roots.contains(root)) {
+ throw new ProblemException("\""+r+"\" has already been used for "+option);
+ }
+ if (roots.equals(bin_dir)) {
+ throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -d");
+ }
+ if (roots.equals(gensrc_dir)) {
+ throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -s");
+ }
+ if (roots.equals(header_dir)) {
+ throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -h");
+ }
+ roots.add(root);
+ Source.scanRoot(root, suffixes, excludes, includes, excludefiles, includefiles,
+ found_files, found_modules, current_module,
+ findBooleanOption(args, "--permit-sources-without-package"),
+ false, inLinksrc);
+ }
+ }
+ if (args[i].equals("-src") ||
+ args[i].equals("-sourcepath") ||
+ args[i].equals("-modulepath") ||
+ args[i].equals("-classpath"))
+ {
+ // Reset the includes,excludes and excludefiles after they have been used.
+ includes = new LinkedList<String>();
+ excludes = new LinkedList<String>();
+ excludefiles = new LinkedList<String>();
+ includefiles = new LinkedList<String>();
+ }
+ }
+ return true;
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Module.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The module is the root of a set of packages/sources/artifacts.
+ * At the moment there is only one module in use, the empty/no-name/default module.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Module implements Comparable<Module> {
+ private String name;
+ private String dirname;
+ private Map<String,Package> packages = new HashMap<String,Package>();
+ private Map<String,Source> sources = new HashMap<String,Source>();
+ private Map<String,File> artifacts = new HashMap<String,File>();
+
+ public Module(String n, String dn) {
+ name = n;
+ dirname = n;
+ }
+
+ public String name() { return name; }
+ public String dirname() { return dirname; }
+ public Map<String,Package> packages() { return packages; }
+ public Map<String,Source> sources() { return sources; }
+ public Map<String,File> artifacts() { return artifacts; }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof Module) && name.equals(((Module)o).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public int compareTo(Module o) {
+ return name.compareTo(o.name);
+ }
+
+ public void save(StringBuilder b) {
+ b.append("M ").append(name).append(":").append("\n");
+ Package.savePackages(packages, b);
+ }
+
+ public static Module load(String l) {
+ int cp = l.indexOf(':',2);
+ if (cp == -1) return null;
+ String name = l.substring(2,cp);
+ return new Module(name, "");
+ }
+
+ public static void saveModules(Map<String,Module> ms, StringBuilder b)
+ {
+ for (Module m : ms.values()) {
+ m.save(b);
+ }
+ }
+
+ public void addPackage(Package p) {
+ packages.put(p.name(), p);
+ }
+
+ public Package lookupPackage(String pkg) {
+ Package p = packages.get(pkg);
+ if (p == null) {
+ p = new Package(this, pkg);
+ packages.put(pkg, p);
+ }
+ return p;
+ }
+
+ public void addSource(String pkg, Source src) {
+ Package p = lookupPackage(pkg);
+ src.setPackage(p);
+ p.addSource(src);
+ sources.put(src.file().getPath(), src);
+ }
+
+ public Source lookupSource(String path) {
+ return sources.get(path);
+ }
+
+ public void addArtifacts(String pkg, Set<URI> as) {
+ Package p = lookupPackage(pkg);
+ for (URI u : as) {
+ p.addArtifact(new File(u));
+ }
+ }
+
+ public void setDependencies(String pkg, Set<String> deps) {
+ Package p = lookupPackage(pkg);
+ p.setDependencies(deps);
+ }
+
+ public void setPubapi(String pkg, List<String> ps) {
+ Package p = lookupPackage(pkg);
+ p.setPubapi(ps);
+ }
+
+ public boolean hasPubapiChanged(String pkg, List<String> ps) {
+ Package p = lookupPackage(pkg);
+ return p.hasPubapiChanged(ps);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Package.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The Package class maintains meta information about a package.
+ * For example its sources, dependents,its pubapi and its artifacts.
+ *
+ * It might look odd that we track dependents/pubapi/artifacts on
+ * a package level, but it makes sense since recompiling a full package
+ * takes as long as recompiling a single java file in that package,
+ * if you take into account the startup time of the jvm.
+ *
+ * Also the dependency information will be much smaller (good for the javac_state file size)
+ * and it simplifies tracking artifact generation, you do not always know from which
+ * source a class file was generated, but you always know which package it belongs to.
+ *
+ * It is also educational to see package dependencies triggering recompilation of
+ * other packages. Even though the recompilation was perhaps not necessary,
+ * the visible recompilation of the dependent packages indicates how much circular
+ * dependencies your code has.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Package implements Comparable<Package> {
+ // The module this package belongs to. (There is a legacy module with an empty string name,
+ // used for all legacy sources.)
+ private Module mod;
+ // Name of this package, module:pkg
+ // ex1 jdk.base:java.lang
+ // ex2 :java.lang (when in legacy mode)
+ private String name;
+ // The directory path to the package. If the package belongs to a module,
+ // then that module's file system name is part of the path.
+ private String dirname;
+ // This package depends on these packages.
+ private Set<String> dependencies = new HashSet<String>();
+ // This package has the following dependents, that depend on this package.
+ private Set<String> dependents = new HashSet<String>();
+ // This is the public api of this package.
+ private List<String> pubapi = new ArrayList<String>();
+ // Map from source file name to Source info object.
+ private Map<String,Source> sources = new HashMap<String,Source>();
+ // This package generated these artifacts.
+ private Map<String,File> artifacts = new HashMap<String,File>();
+
+ public Package(Module m, String n) {
+ int c = n.indexOf(":");
+ assert(c != -1);
+ String mn = n.substring(0,c);
+ assert(m.name().equals(m.name()));
+ name = n;
+ dirname = n.replace('.', File.separatorChar);
+ if (m.name().length() > 0) {
+ // There is a module here, prefix the module dir name to the path.
+ dirname = m.dirname()+File.separatorChar+dirname;
+ }
+ }
+
+ public Module mod() { return mod; }
+ public String name() { return name; }
+ public String dirname() { return dirname; }
+ public Map<String,Source> sources() { return sources; }
+ public Map<String,File> artifacts() { return artifacts; }
+ public List<String> pubapi() { return pubapi; }
+
+ public Set<String> dependencies() { return dependencies; }
+ public Set<String> dependents() { return dependents; }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof Package) && name.equals(((Package)o).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public int compareTo(Package o) {
+ return name.compareTo(o.name);
+ }
+
+ public void addSource(Source s) {
+ sources.put(s.file().getPath(), s);
+ }
+
+ public void addDependency(String d) {
+ dependencies.add(d);
+ }
+
+ public void addDependent(String d) {
+ dependents.add(d);
+ }
+
+ public void addPubapi(String p) {
+ pubapi.add(p);
+ }
+
+ /**
+ * Check if we have knowledge in the javac state that
+ * describe the results of compiling this package before.
+ */
+ public boolean existsInJavacState() {
+ return artifacts.size() > 0 || pubapi.size() > 0;
+ }
+
+ public static List<String> pubapiToList(String ps)
+ {
+ String[] lines = ps.split("\n");
+ List<String> r = new ArrayList<String>();
+ for (String l : lines) {
+ r.add(l);
+ }
+ return r;
+ }
+
+ public boolean hasPubapiChanged(List<String> ps) {
+ Iterator<String> i = ps.iterator();
+ Iterator<String> j = pubapi.iterator();
+ int line = 0;
+ while (i.hasNext() && j.hasNext()) {
+ String is = i.next();
+ String js = j.next();
+ if (!is.equals(js)) {
+ Log.debug("Change in pubapi for package "+name+" line "+line);
+ Log.debug("Old: "+js);
+ Log.debug("New: "+is);
+ return true;
+ }
+ line++;
+ }
+ if ((i.hasNext() && !j.hasNext() ) ||
+ (!i.hasNext() && j.hasNext())) {
+ Log.debug("Change in pubapi for package "+name);
+ if (i.hasNext()) {
+ Log.debug("New has more lines!");
+ } else {
+ Log.debug("Old has more lines!");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void setPubapi(List<String> ps) {
+ pubapi = ps;
+ }
+
+ public void setDependencies(Set<String> ds) {
+ dependencies = ds;
+ }
+
+ public void save(StringBuilder b) {
+ b.append("P ").append(name).append("\n");
+ Source.saveSources(sources, b);
+ saveDependencies(b);
+ savePubapi(b);
+ saveArtifacts(b);
+ }
+
+ static public Package load(Module module, String l) {
+ String name = l.substring(2);
+ return new Package(module, name);
+ }
+
+ public void loadDependency(String l) {
+ String n = l.substring(2);
+ addDependency(n);
+ }
+
+ public void loadPubapi(String l) {
+ String pi = l.substring(2);
+ addPubapi(pi);
+ }
+
+ public void saveDependencies(StringBuilder b) {
+ List<String> sorted_dependencies = new ArrayList<String>();
+ for (String key : dependencies) {
+ sorted_dependencies.add(key);
+ }
+ Collections.sort(sorted_dependencies);
+ for (String a : sorted_dependencies) {
+ b.append("D "+a+"\n");
+ }
+ }
+
+ public void savePubapi(StringBuilder b) {
+ for (String l : pubapi) {
+ b.append("I "+l+"\n");
+ }
+ }
+
+ public static void savePackages(Map<String,Package> packages, StringBuilder b) {
+ List<String> sorted_packages = new ArrayList<String>();
+ for (String key : packages.keySet() ) {
+ sorted_packages.add(key);
+ }
+ Collections.sort(sorted_packages);
+ for (String s : sorted_packages) {
+ Package p = packages.get(s);
+ p.save(b);
+ }
+ }
+
+ public void addArtifact(String a) {
+ artifacts.put(a, new File(a));
+ }
+
+ public void addArtifact(File f) {
+ artifacts.put(f.getPath(), f);
+ }
+
+ public void addArtifacts(Set<URI> as) {
+ for (URI u : as) {
+ addArtifact(new File(u));
+ }
+ }
+
+ public void setArtifacts(Set<URI> as) {
+ assert(!artifacts.isEmpty());
+ artifacts = new HashMap<String,File>();
+ addArtifacts(as);
+ }
+
+ public void loadArtifact(String l) {
+ // Find next space after "A ".
+ int dp = l.indexOf(' ',2);
+ String fn = l.substring(2,dp);
+ long last_modified = Long.parseLong(l.substring(dp+1));
+ File f = new File(fn);
+ if (f.exists() && f.lastModified() != last_modified) {
+ // Hmm, the artifact on disk does not have the same last modified
+ // timestamp as the information from the build database.
+ // We no longer trust the artifact on disk. Delete it.
+ // The smart javac wrapper will then rebuild the artifact.
+ Log.debug("Removing "+f.getPath()+" since its timestamp does not match javac_state.");
+ f.delete();
+ }
+ artifacts.put(f.getPath(), f);
+ }
+
+ public void saveArtifacts(StringBuilder b) {
+ List<File> sorted_artifacts = new ArrayList<File>();
+ for (File f : artifacts.values()) {
+ sorted_artifacts.add(f);
+ }
+ Collections.sort(sorted_artifacts);
+ for (File f : sorted_artifacts) {
+ // The last modified information is only used
+ // to detect tampering with the output dir.
+ // If the outputdir has been modified, not by javac,
+ // then a mismatch will be detected in the last modified
+ // timestamps stored in the build database compared
+ // to the timestamps on disk and the artifact will be deleted.
+
+ b.append("A "+f.getPath()+" "+f.lastModified()+"\n");
+ }
+ }
+
+ /**
+ * Always clean out a tainted package before it is recompiled.
+ */
+ public void deleteArtifacts() {
+ for (File a : artifacts.values()) {
+ a.delete();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/ProblemException.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+/**
+ * Used to signal serious problems when running sjavac.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class ProblemException extends Exception {
+ static final long serialVersionUID = -3387516993124229949L;
+ public ProblemException(String s) {
+ super(s);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.Set;
+import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+/** A Source object maintains information about a source file.
+ * For example which package it belongs to and kind of source it is.
+ * The class also knows how to find source files (scanRoot) given include/exclude
+ * patterns and a root.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Source implements Comparable<Source> {
+ // The package the source belongs to.
+ private Package pkg;
+ // Name of this source file, relative its source root.
+ // For example: java/lang/Object.java
+ // Or if the source file is inside a module:
+ // jdk.base/java/lang/Object.java
+ private String name;
+ // What kind of file is this.
+ private String suffix;
+ // When this source file was last_modified
+ private long lastModified;
+ // The source File.
+ private File file;
+ // The source root under which file resides.
+ private File root;
+ // If the source is generated.
+ private boolean isGenerated;
+ // If the source is only linked to, not compiled.
+ private boolean linkedOnly;
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof Source) && name.equals(((Source)o).name);
+ }
+
+ @Override
+ public int compareTo(Source o) {
+ return name.compareTo(o.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public Source(Module m, String n, File f, File r) {
+ name = n;
+ int dp = n.lastIndexOf(".");
+ if (dp != -1) {
+ suffix = n.substring(dp);
+ } else {
+ suffix = "";
+ }
+ file = f;
+ root = r;
+ lastModified = f.lastModified();
+ linkedOnly = false;
+ }
+
+ public Source(Package p, String n, long lm) {
+ pkg = p;
+ name = n;
+ int dp = n.lastIndexOf(".");
+ if (dp != -1) {
+ suffix = n.substring(dp);
+ } else {
+ suffix = "";
+ }
+ file = null;
+ root = null;
+ lastModified = lm;
+ linkedOnly = false;
+ int ls = n.lastIndexOf('/');
+ }
+
+ public String name() { return name; }
+ public String suffix() { return suffix; }
+ public Package pkg() { return pkg; }
+ public File file() { return file; }
+ public File root() { return root; }
+ public long lastModified() {
+ return lastModified;
+ }
+
+ public void setPackage(Package p) {
+ pkg = p;
+ }
+
+ public void markAsGenerated() {
+ isGenerated = true;
+ }
+
+ public boolean isGenerated() {
+ return isGenerated;
+ }
+
+ public void markAsLinkedOnly() {
+ linkedOnly = true;
+ }
+
+ public boolean isLinkedOnly() {
+ return linkedOnly;
+ }
+
+ private void save(StringBuilder b) {
+ String CL = linkedOnly?"L":"C";
+ String GS = isGenerated?"G":"S";
+ b.append(GS+" "+CL+" "+name+" "+file.lastModified()+"\n");
+ }
+ // Parse a line that looks like this:
+ // S C /code/alfa/A.java 1357631228000
+ static public Source load(Package lastPackage, String l, boolean isGenerated) {
+ int sp = l.indexOf(' ',4);
+ if (sp == -1) return null;
+ String name = l.substring(4,sp);
+ long last_modified = Long.parseLong(l.substring(sp+1));
+
+ boolean isLinkedOnly = false;
+ if (l.charAt(2) == 'L') {
+ isLinkedOnly = true;
+ } else if (l.charAt(2) == 'C') {
+ isLinkedOnly = false;
+ } else return null;
+
+ Source s = new Source(lastPackage, name, last_modified);
+ s.file = new File(name);
+ if (isGenerated) s.markAsGenerated();
+ if (isLinkedOnly) s.markAsLinkedOnly();
+ return s;
+ }
+
+ public static void saveSources(Map<String,Source> sources, StringBuilder b) {
+ List<String> sorted_sources = new ArrayList<String>();
+ for (String key : sources.keySet()) {
+ sorted_sources.add(key);
+ }
+ Collections.sort(sorted_sources);
+ for (String key : sorted_sources) {
+ Source s = sources.get(key);
+ s.save(b);
+ }
+ }
+
+ /**
+ * Recurse into the directory root and find all files matchine the excl/incl/exclfiles/inclfiles rules.
+ * Detects the existence of module-info.java files and presumes that the directory it resides in
+ * is the name of the current module.
+ */
+ static public void scanRoot(File root,
+ Set<String> suffixes,
+ List<String> excludes, List<String> includes,
+ List<String> excludeFiles, List<String> includeFiles,
+ Map<String,Source> foundFiles,
+ Map<String,Module> foundModules,
+ Module currentModule,
+ boolean permitSourcesWithoutPackage,
+ boolean inGensrc,
+ boolean inLinksrc)
+ throws ProblemException {
+
+ if (root == null) return;
+ int root_prefix = root.getPath().length()+1;
+ // This is the root source directory, it must not contain any Java sources files
+ // because we do not allow Java source files without a package.
+ // (Unless of course --permit-sources-without-package has been specified.)
+ // It might contain other source files however, (for -tr and -copy) these will
+ // always be included, since no package pattern can match the root directory.
+ currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage,
+ excludeFiles, includeFiles, false,
+ foundFiles, foundModules, currentModule,
+ inGensrc, inLinksrc);
+
+ File[] dirfiles = root.listFiles();
+ for (File d : dirfiles) {
+ if (d.isDirectory()) {
+ // Descend into the directory structure.
+ scanDirectory(d, root_prefix, root, suffixes,
+ excludes, includes, excludeFiles, includeFiles,
+ false, foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+ }
+ }
+ }
+
+ /**
+ * Test if a path matches any of the patterns given.
+ * The pattern foo.bar matches only foo.bar
+ * The pattern foo.* matches foo.bar and foo.bar.zoo etc
+ */
+ static private boolean hasMatch(String path, List<String> patterns) {
+ for (String p : patterns) {
+ // Exact match
+ if (p.equals(path)) {
+ return true;
+ }
+ // Single dot the end matches this package and all its subpackages.
+ if (p.endsWith(".*")) {
+ // Remove the wildcard
+ String patprefix = p.substring(0,p.length()-2);
+ // Does the path start with the pattern prefix?
+ if (path.startsWith(patprefix)) {
+ // If the path has the same length as the pattern prefix, then it is a match.
+ // If the path is longer, then make sure that
+ // the next part of the path starts with a dot (.) to prevent
+ // wildcard matching in the middle of a package name.
+ if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='.') {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Matches patterns with the asterisk first. */
+ // The pattern foo/bar.java only matches foo/bar.java
+ // The pattern */bar.java matches foo/bar.java and zoo/bar.java etc
+ static private boolean hasFileMatch(String path, List<String> patterns) {
+ path = Util.normalizeDriveLetter(path);
+ for (String p : patterns) {
+ // Exact match
+ if (p.equals(path)) {
+ return true;
+ }
+ // Single dot the end matches this package and all its subpackages.
+ if (p.startsWith("*")) {
+ // Remove the wildcard
+ String patsuffix = p.substring(1);
+ // Does the path start with the pattern prefix?
+ if (path.endsWith(patsuffix)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add the files in the directory, assuming that the file has not been excluded.
+ * Returns a fresh Module object, if this was a dir with a module-info.java file.
+ */
+ static private Module addFilesInDir(File dir, int rootPrefix, File root,
+ Set<String> suffixes, boolean allow_javas,
+ List<String> excludeFiles, List<String> includeFiles, boolean all,
+ Map<String,Source> foundFiles,
+ Map<String,Module> foundModules,
+ Module currentModule,
+ boolean inGensrc,
+ boolean inLinksrc)
+ throws ProblemException
+ {
+ for (File f : dir.listFiles()) {
+ if (f.isFile()) {
+ boolean should_add =
+ (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
+ && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
+
+ if (should_add) {
+ if (!allow_javas && f.getName().endsWith(".java")) {
+ throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
+ ", please remove "+f.getName());
+ }
+ // Extract the file name relative the root.
+ String fn = f.getPath().substring(rootPrefix);
+ // Extract the package name.
+ int sp = fn.lastIndexOf(File.separatorChar);
+ String pkg = "";
+ if (sp != -1) {
+ pkg = fn.substring(0,sp).replace(File.separatorChar,'.');
+ }
+ // Is this a module-info.java file?
+ if (fn.endsWith("module-info.java")) {
+ // Aha! We have recursed into a module!
+ if (!currentModule.name().equals("")) {
+ throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
+ }
+ String module_name = fn.substring(0,fn.length()-16);
+ currentModule = new Module(module_name, f.getPath());
+ foundModules.put(module_name, currentModule);
+ }
+ // Extract the suffix.
+ int dp = fn.lastIndexOf(".");
+ String suffix = "";
+ if (dp > 0) {
+ suffix = fn.substring(dp);
+ }
+ // Should the file be added?
+ if (all || suffixes.contains(suffix)) {
+ Source of = foundFiles.get(f.getPath());
+ if (of != null) {
+ throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
+ }
+ of = currentModule.lookupSource(f.getPath());
+ if (of != null) {
+ // Oups, the source is already added, could be ok, could be not, lets check.
+ if (inLinksrc) {
+ // So we are collecting sources for linking only.
+ if (of.isLinkedOnly()) {
+ // Ouch, this one is also for linking only. Bad.
+ throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
+ }
+ // Ok, the existing source is to be compiled. Thus this link only is redundant
+ // since all compiled are also linked to. Continue to the next source.
+ // But we need to add the source, so that it will be visible to linking,
+ // if not the multi core compile will fail because a JavaCompiler cannot
+ // find the necessary dependencies for its part of the source.
+ foundFiles.put(f.getPath(), of);
+ continue;
+ } else {
+ // We are looking for sources to compile, if we find an existing to be compiled
+ // source with the same name, it is an internal error, since we must
+ // find the sources to be compiled before we find the sources to be linked to.
+ throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
+ }
+ }
+ Source s = new Source(currentModule, f.getPath(), f, root);
+ if (inGensrc) s.markAsGenerated();
+ if (inLinksrc) {
+ s.markAsLinkedOnly();
+ }
+ pkg = currentModule.name()+":"+pkg;
+ foundFiles.put(f.getPath(), s);
+ currentModule.addSource(pkg, s);
+ }
+ }
+ }
+ }
+ return currentModule;
+ }
+
+ private static boolean gurka = false;
+
+ static private void scanDirectory(File dir, int rootPrefix, File root,
+ Set<String> suffixes,
+ List<String> excludes, List<String> includes,
+ List<String> excludeFiles, List<String> includeFiles, boolean all,
+ Map<String,Source> foundFiles,
+ Map<String,Module> foundModules,
+ Module currentModule, boolean inGensrc, boolean inLinksrc)
+ throws ProblemException {
+
+ String pkg_name = "";
+ // Remove the root prefix from the dir path, and replace file separator with dots
+ // to get the package name.
+ if (dir.getPath().length() > rootPrefix) {
+ pkg_name = dir.getPath().substring(rootPrefix).replace(File.separatorChar,'.');
+ }
+ // Should this package directory be included and not excluded?
+ if (all || ((includes==null || includes.isEmpty() || hasMatch(pkg_name, includes)) &&
+ (excludes==null || excludes.isEmpty() || !hasMatch(pkg_name, excludes)))) {
+ // Add the source files.
+ currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, all,
+ foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+ }
+
+ for (File d : dir.listFiles()) {
+ if (d.isDirectory()) {
+ // Descend into the directory structure.
+ scanDirectory(d, rootPrefix, root, suffixes,
+ excludes, includes, excludeFiles, includeFiles, all,
+ foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.PrintStream;
+import java.net.URI;
+import java.util.Set;
+import java.util.Map;
+
+/**
+ * The transform interface is used to transform content inside a package, from one form to another.
+ * Usually the output form is an unpredictable number of output files. (eg class files)
+ * but can also be an unpredictable number of generated source files (eg idl2java)
+ * or a single predictable output file (eg when copying,cleaning or compiling a properties file).
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public interface Transformer
+{
+ /**
+ * The transform method takes a set of package names, mapped to their source files and to the
+ * pubapis of the packages.
+ *
+ * The transform implementation must:
+ * store the names of the generated artifacts for each package into package_artifacts
+ * store found dependencies to other packages into the supplied set package_dependencies
+ * store the public api for a package into the supplied set package_pubapis
+ *
+ * Any benign messages as a result of running the transform
+ * are written into stdout, and errors are written to stderr.
+ *
+ * The debug_level can be 0=silent (only warnings and errors) 1=normal 2=verbose 3 or greater=debug
+ * setExtra is used to set the extra information information that can be passed on
+ * the command line to the smart javac wrapper.
+ *
+ * If sjavac is building incrementally from an existing javac_state, the var incremental is true.
+ *
+ * The transformer will only be called if some source in the package (or dependency) has
+ * a modified timestamp. Thus the transformer might get called with many sources, of which
+ * only one has changed. The transformer is allowed to regenerate all artifacts but
+ * a better transformer will only write those artifacts that need updating.
+ *
+ * However the transformer must verify that the existing artifacts really are there!
+ * and it must always update package_artifacts, package_dependencies, and package_pubapis correctly.
+ * This means that at least for Java source, it will always have to recompile the sources.
+ *
+ * The transformer is allowed to put files anywhere in the dest_root.
+ * An example of this is, can be the META-INF transformer that copy files
+ * below META-INF directories to the single META-INF directory below dest_root.
+ *
+ * False is returned if there was an error that prevented the transform.
+ * I.e. something was printed on stderr.
+ *
+ * If num_cores is set to a non-zero value. The transform should attempt to use no more than these
+ * number of threads for heavy work.
+ */
+ boolean transform(Map<String,Set<URI>> pkgSrcs,
+ Set<URI> visibleSources,
+ Map<URI,Set<String>> visibleClasses,
+ Map<String,Set<String>> oldPackageDependencies,
+ URI destRoot,
+ Map<String,Set<URI>> packageArtifacts,
+ Map<String,Set<String>> packageDependencies,
+ Map<String,String> packagePublicApis,
+ int debugLevel,
+ boolean incremental,
+ int numCores,
+ PrintStream out,
+ PrintStream err);
+
+ void setExtra(String e);
+ void setExtra(String[] args);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Utilities.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Util {
+
+ public static String toFileSystemPath(String pkgId) {
+ if (pkgId == null || pkgId.length()==0) return null;
+ String pn;
+ if (pkgId.charAt(0) == ':') {
+ // When the module is the default empty module.
+ // Do not prepend the module directory, because there is none.
+ // Thus :java.foo.bar translates to java/foo/bar (or \)
+ pn = pkgId.substring(1).replace('.',File.separatorChar);
+ } else {
+ // There is a module. Thus jdk.base:java.foo.bar translates
+ // into jdk.base/java/foo/bar
+ int cp = pkgId.indexOf(':');
+ String mn = pkgId.substring(0,cp);
+ pn = mn+File.separatorChar+pkgId.substring(cp+1).replace('.',File.separatorChar);
+ }
+ return pn;
+ }
+
+ public static String justPackageName(String pkgName) {
+ int c = pkgName.indexOf(":");
+ assert(c != -1);
+ return pkgName.substring(c+1);
+ }
+
+ public static String extractStringOption(String opName, String s) {
+ int p = s.indexOf(opName+"=");
+ if (p == -1) return null;
+ p+=opName.length()+1;
+ int pe = s.indexOf(',', p);
+ if (pe == -1) pe = s.length();
+ return s.substring(p, pe);
+ }
+
+ public static int extractIntOption(String opName, String s) {
+ int p = s.indexOf(opName+"=");
+ if (p == -1) return 0;
+ p+=opName.length()+1;
+ int pe = s.indexOf(',', p);
+ if (pe == -1) pe = s.length();
+ int v = 0;
+ try {
+ v = Integer.parseInt(s.substring(p, pe));
+ } catch (Exception e) {}
+ return v;
+ }
+
+ /**
+ * Clean out unwanted sub options supplied inside a primary option.
+ * For example to only had portfile remaining from:
+ * settings="--server:id=foo,portfile=bar"
+ * do settings = cleanOptions("--server:",Util.set("-portfile"),settings);
+ * now settings equals "--server:portfile=bar"
+ *
+ * @param optionPrefix The option name, including colon, eg --server:
+ * @param allowsSubOptions A set of the allowed sub options, id portfile etc.
+ * @param s The option settings string.
+ */
+ public static String cleanSubOptions(String optionPrefix, Set<String> allowedSubOptions, String s) {
+ StringBuilder sb = new StringBuilder();
+ if (!s.startsWith(optionPrefix)) return "";
+ StringTokenizer st = new StringTokenizer(s.substring(optionPrefix.length()), ",");
+ while (st.hasMoreTokens()) {
+ String o = st.nextToken();
+ int p = o.indexOf('=');
+ if (p>0) {
+ String key = o.substring(0,p);
+ String val = o.substring(p+1);
+ if (allowedSubOptions.contains(key)) {
+ if (sb.length() > 0) sb.append(',');
+ sb.append(key+"="+val);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convenience method to create a set with strings.
+ */
+ public static Set<String> set(String... ss) {
+ Set<String> set = new HashSet<String>();
+ set.addAll(Arrays.asList(ss));
+ return set;
+ }
+
+ /**
+ * Normalize windows drive letter paths to upper case to enable string
+ * comparison.
+ *
+ * @param file File name to normalize
+ * @return The normalized string if file has a drive letter at the beginning,
+ * otherwise the original string.
+ */
+ public static String normalizeDriveLetter(String file) {
+ if (file.length() > 2 && file.charAt(1) == ':') {
+ return Character.toUpperCase(file.charAt(0)) + file.substring(1);
+ } else if (file.length() > 3 && file.charAt(0) == '*'
+ && file.charAt(2) == ':') {
+ // Handle a wildcard * at the beginning of the string.
+ return file.substring(0, 1) + Character.toUpperCase(file.charAt(1))
+ + file.substring(2);
+ }
+ return file;
+ }
+
+ /**
+ * Locate the setting for the server properties.
+ */
+ public static String findServerSettings(String[] args) {
+ for (String s : args) {
+ if (s.startsWith("--server:")) {
+ return s;
+ }
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import javax.lang.model.element.Element;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+
+/** Utility class containing dependency information between packages
+ * and the pubapi for a package.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class Dependencies {
+ protected static final Context.Key<Dependencies> dependenciesKey =
+ new Context.Key<Dependencies>();
+
+ // The log to be used for error reporting.
+ protected Log log;
+ // Map from package name to packages that the package depends upon.
+ protected Map<Name,Set<Name>> deps;
+ // This is the set of all packages that are supplied
+ // through the java files at the command line.
+ protected Set<Name> explicitPackages;
+
+ // Map from a package name to its public api.
+ // Will the Name encode the module in the future?
+ // If not, this will have to change to map from Module+Name to public api.
+ protected Map<Name,StringBuffer> publicApiPerClass;
+
+ public static Dependencies instance(Context context) {
+ Dependencies instance = context.get(dependenciesKey);
+ if (instance == null)
+ instance = new Dependencies(context);
+ return instance;
+ }
+
+ private Dependencies(Context context) {
+ context.put(dependenciesKey, this);
+ log = Log.instance(context);
+ }
+
+ public void reset()
+ {
+ deps = new HashMap<Name, Set<Name>>();
+ explicitPackages = new HashSet<Name>();
+ publicApiPerClass = new HashMap<Name,StringBuffer>();
+ }
+
+ /**
+ * Fetch the set of dependencies that are relevant to the compile
+ * that has just been performed. I.e. we are only interested in
+ * dependencies for classes that were explicitly compiled.
+ * @return
+ */
+ public Map<String,Set<String>> getDependencies() {
+ Map<String,Set<String>> new_deps = new HashMap<String,Set<String>>();
+ if (explicitPackages == null) return new_deps;
+ for (Name pkg : explicitPackages) {
+ Set<Name> set = deps.get(pkg);
+ if (set != null) {
+ Set<String> new_set = new_deps.get(pkg.toString());
+ if (new_set == null) {
+ new_set = new HashSet<String>();
+ // Modules beware....
+ new_deps.put(":"+pkg.toString(), new_set);
+ }
+ for (Name d : set) {
+ new_set.add(":"+d.toString());
+ }
+ }
+ }
+ return new_deps;
+ }
+
+ class CompareNames implements Comparator<Name> {
+ public int compare(Name a, Name b) {
+ return a.toString().compareTo(b.toString());
+ }
+
+ public boolean equals(Object obj) {
+ return super.equals(obj);
+ }
+ }
+
+ /**
+ * Convert the map from class names to their pubapi to a map
+ * from package names to their pubapi (which is the sorted concatenation
+ * of all the class pubapis)
+ */
+ public Map<String,String> getPubapis() {
+ Map<String,String> publicApiPerPackage = new HashMap<String,String>();
+ if (publicApiPerClass == null) return publicApiPerPackage;
+ Name[] keys = publicApiPerClass.keySet().toArray(new Name[0]);
+ Arrays.sort(keys, new CompareNames());
+ StringBuffer newPublicApi = new StringBuffer();
+ int i=0;
+ String prevPkg = "";
+ for (Name k : keys) {
+ String cn = k.toString();
+ String pn = "";
+ int dp = cn.lastIndexOf('.');
+ if (dp != -1) {
+ pn = cn.substring(0,dp);
+ }
+ if (!pn.equals(prevPkg)) {
+ if (!prevPkg.equals("")) {
+ // Add default module name ":"
+ publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
+ }
+ newPublicApi = new StringBuffer();
+ prevPkg = pn;
+ }
+ newPublicApi.append(publicApiPerClass.get(k));
+ i++;
+ }
+ if (!prevPkg.equals(""))
+ publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
+ return publicApiPerPackage;
+ }
+
+ /**
+ * Visit the api of a class and construct a pubapi string and
+ * store it into the pubapi_perclass map.
+ */
+ public void visitPubapi(Element e) {
+ Name n = ((ClassSymbol)e).fullname;
+ Name p = ((ClassSymbol)e).packge().fullname;
+ StringBuffer sb = publicApiPerClass.get(n);
+ assert(sb == null);
+ sb = new StringBuffer();
+ PubapiVisitor v = new PubapiVisitor(sb);
+ v.visit(e);
+ if (sb.length()>0) {
+ publicApiPerClass.put(n, sb);
+ }
+ explicitPackages.add(p);
+ }
+
+ /**
+ * Collect a dependency. curr_pkg is marked as depending on dep_pkg.
+ */
+ public void collect(Name currPkg, Name depPkg) {
+ if (!currPkg.equals(depPkg)) {
+ Set<Name> theset = deps.get(currPkg);
+ if (theset==null) {
+ theset = new HashSet<Name>();
+ deps.put(currPkg, theset);
+ }
+ theset.add(depPkg);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/JavaCompilerWithDeps.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.util.StringTokenizer;
+
+import com.sun.tools.javac.main.JavaCompiler;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.sjavac.server.CompilerThread;
+import java.io.File;
+
+/** Subclass to Resolve that overrides collect.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class JavaCompilerWithDeps extends JavaCompiler {
+
+ /** The dependency database
+ */
+ protected Dependencies deps;
+ protected CompilerThread compilerThread;
+
+ public JavaCompilerWithDeps(Context context, CompilerThread t) {
+ super(context);
+ deps = Dependencies.instance(context);
+ compilerThread = t;
+ needRootClasses = true;
+ }
+
+ public static void preRegister(Context context, final CompilerThread t) {
+ context.put(compilerKey, new Context.Factory<JavaCompiler>() {
+ public JavaCompiler make(Context c) {
+ JavaCompiler instance = new JavaCompilerWithDeps(c, t);
+ c.put(JavaCompiler.class, instance);
+ return instance;
+ }
+ });
+ }
+
+ /** Collect the public apis of classes supplied explicitly for compilation.
+ * @param sym The class to visit.
+ */
+ @Override
+ public void reportPublicApi(ClassSymbol sym) {
+ // The next test will catch when source files are located in the wrong directory!
+ // This ought to be moved into javac as a new warning, or perhaps as part
+ // of the auxiliary class warning.
+
+ // For example if sun.swing.BeanInfoUtils
+ // is in fact stored in: /mybuild/jdk/gensrc/javax/swing/beaninfo/BeanInfoUtils.java
+
+ // We do not need to test that BeanInfoUtils is stored in a file named BeanInfoUtils
+ // since this is checked earlier.
+ if (sym.sourcefile != null) {
+ // Rewrite sun.swing.BeanInfoUtils into /sun/swing/
+ StringBuilder pathb = new StringBuilder();
+ StringTokenizer qn = new StringTokenizer(sym.packge().toString(), ".");
+ boolean first = true;
+ while (qn.hasMoreTokens()) {
+ String o = qn.nextToken();
+ pathb.append("/");
+ pathb.append(o);
+ first = false;
+ }
+ pathb.append("/");
+ String path = pathb.toString();
+
+ // Now cut the uri to be: file:///mybuild/jdk/gensrc/javax/swing/beaninfo/
+ String p = sym.sourcefile.toUri().getPath();
+ // Do not use File.separatorChar here, a URI always uses slashes /.
+ int i = p.lastIndexOf("/");
+ String pp = p.substring(0,i+1);
+
+ // Now check if the truncated uri ends with the path. (It does not == failure!)
+ if (path.length() > 0 && !path.equals("/unnamed package/") && !pp.endsWith(path)) {
+ compilerThread.logError("Error: The source file "+sym.sourcefile.getName()+
+ " is located in the wrong package directory, because it contains the class "+
+ sym.getQualifiedName());
+ }
+ }
+ deps.visitPubapi(sym);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/PubapiVisitor.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import java.util.Iterator;
+import java.util.List;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementScanner6;
+
+/** Utility class that constructs a textual representation
+ * of the public api of a class.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class PubapiVisitor extends ElementScanner6<Void, Void> {
+
+ StringBuffer sb;
+ // Important that it is 1! Part of protocol over wire, silly yes.
+ // Fix please.
+ int indent = 1;
+
+ public PubapiVisitor(StringBuffer sb) {
+ this.sb = sb;
+ }
+
+ String depth(int l) {
+ return " ".substring(0, l);
+ }
+
+ @Override
+ public Void visitType(TypeElement e, Void p) {
+ if (e.getModifiers().contains(Modifier.PUBLIC)
+ || e.getModifiers().contains(Modifier.PROTECTED))
+ {
+ sb.append(depth(indent) + "TYPE " + e.getQualifiedName() + "\n");
+ indent += 2;
+ Void v = super.visitType(e, p);
+ indent -= 2;
+ return v;
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitVariable(VariableElement e, Void p) {
+ if (e.getModifiers().contains(Modifier.PUBLIC)
+ || e.getModifiers().contains(Modifier.PROTECTED)) {
+ sb.append(depth(indent)).append("VAR ")
+ .append(makeVariableString(e)).append("\n");
+ }
+ // Safe to not recurse here, because the only thing
+ // to visit here is the constructor of a variable declaration.
+ // If it happens to contain an anonymous inner class (which it might)
+ // then this class is never visible outside of the package anyway, so
+ // we are allowed to ignore it here.
+ return null;
+ }
+
+ @Override
+ public Void visitExecutable(ExecutableElement e, Void p) {
+ if (e.getModifiers().contains(Modifier.PUBLIC)
+ || e.getModifiers().contains(Modifier.PROTECTED)) {
+ sb.append(depth(indent)).append("METHOD ")
+ .append(makeMethodString(e)).append("\n");
+ }
+ return null;
+ }
+
+ /**
+ * Creates a String representation of a method element with everything
+ * necessary to track all public aspects of it in an API.
+ * @param e Element to create String for.
+ * @return String representation of element.
+ */
+ protected String makeMethodString(ExecutableElement e) {
+ StringBuilder result = new StringBuilder();
+ for (Modifier modifier : e.getModifiers()) {
+ result.append(modifier.toString());
+ result.append(" ");
+ }
+ result.append(e.getReturnType().toString());
+ result.append(" ");
+ result.append(e.toString());
+
+ List<? extends TypeMirror> thrownTypes = e.getThrownTypes();
+ if (!thrownTypes.isEmpty()) {
+ result.append(" throws ");
+ for (Iterator<? extends TypeMirror> iterator = thrownTypes
+ .iterator(); iterator.hasNext();) {
+ TypeMirror typeMirror = iterator.next();
+ result.append(typeMirror.toString());
+ if (iterator.hasNext()) {
+ result.append(", ");
+ }
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Creates a String representation of a variable element with everything
+ * necessary to track all public aspects of it in an API.
+ * @param e Element to create String for.
+ * @return String representation of element.
+ */
+ protected String makeVariableString(VariableElement e) {
+ StringBuilder result = new StringBuilder();
+ for (Modifier modifier : e.getModifiers()) {
+ result.append(modifier.toString());
+ result.append(" ");
+ }
+ result.append(e.asType().toString());
+ result.append(" ");
+ result.append(e.toString());
+ Object value = e.getConstantValue();
+ if (value != null) {
+ result.append(" = ");
+ if (e.asType().toString().equals("char")) {
+ int v = (int)value.toString().charAt(0);
+ result.append("'\\u"+Integer.toString(v,16)+"'");
+ } else {
+ result.append(value.toString());
+ }
+ }
+ return result.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/ResolveWithDeps.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import com.sun.tools.javac.comp.Resolve;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.code.Symbol;
+
+/** Subclass to Resolve that overrides collect.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class ResolveWithDeps extends Resolve {
+
+ /** The dependency database
+ */
+ protected Dependencies deps;
+
+ protected ResolveWithDeps(Context context) {
+ super(context);
+ deps = Dependencies.instance(context);
+ }
+
+ public static void preRegister(Context context) {
+ context.put(resolveKey, new Context.Factory<Resolve>() {
+ public Resolve make(Context c) {
+ Resolve instance = new ResolveWithDeps(c);
+ c.put(Resolve.class, instance);
+ return instance;
+ }
+ });
+ }
+ /** Collect dependencies in the enclosing class
+ * @param from The enclosing class sym
+ * @param to The enclosing classes references this sym.
+ * */
+ @Override
+ public void reportDependence(Symbol from, Symbol to) {
+ // Capture dependencies between the packages.
+ deps.collect(from.packge().fullname, to.packge().fullname);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import com.sun.tools.javac.util.ListBuffer;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import javax.tools.*;
+import javax.tools.JavaFileObject.Kind;
+
+/**
+ * Intercepts reads and writes to the file system to gather
+ * information about what artifacts are generated.
+ *
+ * Traps writes to certain files, if the content written is identical
+ * to the existing file.
+ *
+ * Can also blind out the filemanager from seeing certain files in the file system.
+ * Necessary to prevent javac from seeing some sources where the source path points.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager> {
+
+ // Set of sources that can be seen by javac.
+ Set<URI> visibleSources = new HashSet<URI>();
+ // Map from modulename:packagename to artifacts.
+ Map<String,Set<URI>> packageArtifacts = new HashMap<String,Set<URI>>();
+ // Where to print informational messages.
+ PrintWriter stdout;
+
+ public SmartFileManager(JavaFileManager fileManager) {
+ super(fileManager);
+ }
+
+ public void setVisibleSources(Set<URI> s) {
+ visibleSources = s;
+ }
+
+ public void cleanArtifacts() {
+ packageArtifacts = new HashMap<String,Set<URI>>();
+ }
+
+ public void setLog(PrintWriter pw) {
+ stdout = pw;
+ }
+
+ public Map<String,Set<URI>> getPackageArtifacts() {
+ return packageArtifacts;
+ }
+
+ @Override
+ public Iterable<JavaFileObject> list(Location location,
+ String packageName,
+ Set<Kind> kinds,
+ boolean recurse)
+ throws IOException
+ {
+ // Acquire the list of files.
+ Iterable<JavaFileObject> files = super.list(location, packageName, kinds, recurse);
+ if (visibleSources.isEmpty()) {
+ return files;
+ }
+ // Now filter!
+ ListBuffer<JavaFileObject> filteredFiles = new ListBuffer<JavaFileObject>();
+ for (JavaFileObject f : files) {
+ URI uri = f.toUri();
+ String t = uri.toString();
+ if (t.startsWith("jar:")
+ || t.endsWith(".class")
+ || visibleSources.contains(uri))
+ {
+ filteredFiles.add(f);
+ }
+ }
+ return filteredFiles;
+ }
+
+ @Override
+ public boolean hasLocation(Location location) {
+ return super.hasLocation(location);
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForInput(Location location,
+ String className,
+ Kind kind)
+ throws IOException
+ {
+ JavaFileObject file = super.getJavaFileForInput(location, className, kind);
+ if (file == null || visibleSources.isEmpty()) {
+ return file;
+ }
+
+ if (visibleSources.contains(file.toUri())) {
+ return file;
+ }
+ return null;
+ }
+
+ @Override
+ public JavaFileObject getJavaFileForOutput(Location location,
+ String className,
+ Kind kind,
+ FileObject sibling)
+ throws IOException
+ {
+ JavaFileObject file = super.getJavaFileForOutput(location, className, kind, sibling);
+ if (file == null) return file;
+ int dp = className.lastIndexOf('.');
+ String pkg_name = "";
+ if (dp != -1) {
+ pkg_name = className.substring(0, dp);
+ }
+ // When modules are in use, then the mod_name might be something like "jdk_base"
+ String mod_name = "";
+ addArtifact(mod_name+":"+pkg_name, file.toUri());
+ return file;
+ }
+
+ @Override
+ public FileObject getFileForInput(Location location,
+ String packageName,
+ String relativeName)
+ throws IOException
+ {
+ FileObject file = super.getFileForInput(location, packageName, relativeName);
+ if (file == null || visibleSources.isEmpty()) {
+ return file;
+ }
+
+ if (visibleSources.contains(file.toUri())) {
+ return file;
+ }
+ return null;
+ }
+
+ @Override
+ public FileObject getFileForOutput(Location location,
+ String packageName,
+ String relativeName,
+ FileObject sibling)
+ throws IOException
+ {
+ FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
+ if (file == null) return file;
+ if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
+ file instanceof JavaFileObject) {
+ file = new SmartFileObject((JavaFileObject)file, stdout);
+ packageName = ":" + packageNameFromFileName(relativeName);
+ }
+ if (packageName.equals("")) {
+ packageName = ":";
+ }
+ addArtifact(packageName, file.toUri());
+ return file;
+ }
+
+ private String packageNameFromFileName(String fn) {
+ StringBuilder sb = new StringBuilder();
+ int p = fn.indexOf('_'), pp = 0;
+ while (p != -1) {
+ if (sb.length() > 0) sb.append('.');
+ sb.append(fn.substring(pp,p));
+ if (p == fn.length()-1) break;
+ pp = p+1;
+ p = fn.indexOf('_',pp);
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ super.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ }
+
+ void addArtifact(String pkgName, URI art) {
+ Set<URI> s = packageArtifacts.get(pkgName);
+ if (s == null) {
+ s = new HashSet<URI>();
+ packageArtifacts.put(pkgName, s);
+ }
+ s.add(art);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.comp;
+
+import java.io.*;
+import java.net.URI;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.NestingKind;
+import javax.tools.JavaFileObject;
+
+/**
+ * The SmartFileObject will return an outputstream that cache the written data
+ * and compare the new content with the old content on disk. Only if they differ,
+ * will the file be updated.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class SmartFileObject implements JavaFileObject {
+
+ JavaFileObject file;
+ PrintWriter stdout;
+
+ public SmartFileObject(JavaFileObject r, PrintWriter pw) {
+ file = r;
+ stdout = pw;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return file.equals(other);
+ }
+
+ @Override
+ public int hashCode() {
+ return file.hashCode();
+ }
+
+ public Kind getKind() {
+ return file.getKind();
+ }
+
+ public boolean isNameCompatible(String simpleName, Kind kind) {
+ return file.isNameCompatible(simpleName, kind);
+ }
+
+ public URI toUri() {
+ return file.toUri();
+ }
+
+ public String getName() {
+ return file.getName();
+ }
+
+ public InputStream openInputStream() throws IOException {
+ return file.openInputStream();
+ }
+
+ public OutputStream openOutputStream() throws IOException {
+ return file.openOutputStream();
+ }
+
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return file.getCharContent(ignoreEncodingErrors);
+ }
+
+ static String lineseparator = System.getProperty("line.separator");
+
+ public Writer openWriter() throws IOException {
+ StringBuilder s = new StringBuilder();
+ try (BufferedReader r = new BufferedReader(file.openReader(true))) {
+ while (r.ready()) {
+ s.append(r.readLine()+lineseparator);
+ }
+ } catch (FileNotFoundException e) {
+ // Perfectly ok.
+ }
+ return new SmartWriter(file, s.toString(), file.getName(), stdout);
+ }
+
+ public long getLastModified() {
+ return file.getLastModified();
+ }
+
+ public boolean delete() {
+ return file.delete();
+ }
+
+ public Modifier getAccessLevel() {
+ return file.getAccessLevel();
+ }
+
+ public NestingKind getNestingKind() {
+ return file.getNestingKind();
+ }
+
+ public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+ return file.openReader(ignoreEncodingErrors);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/comp/SmartWriter.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.comp;
+
+import java.io.*;
+import javax.tools.JavaFileObject;
+
+/**
+ * The SmartWriter will cache the written data and when the writer is closed,
+ * then it will compare the cached data with the old_content string.
+ * If different, then it will write all the new content to the file.
+ * If not, the file is not touched.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class SmartWriter extends Writer {
+
+ String name;
+ JavaFileObject file;
+ String oldContent;
+ StringWriter newContent = new StringWriter();
+ PrintWriter stdout;
+ boolean closed;
+ public SmartWriter(JavaFileObject f, String s, String n, PrintWriter pw) {
+ name = n;
+ file = f;
+ oldContent = s;
+ newContent = new StringWriter();
+ stdout = pw;
+ closed = false;
+ }
+
+ public void write(char[] chars, int i, int i1)
+ {
+ newContent.write(chars, i, i1);
+ }
+
+ public void close() throws IOException {
+ if (closed) return;
+ closed = true;
+ String s = newContent.toString();
+ if (!oldContent.equals(s)) {
+ int p = file.getName().lastIndexOf(File.separatorChar);
+ try (Writer writer = file.openWriter()) {
+ writer.write(s);
+ }
+ stdout.println("Writing "+file.getName().substring(p+1));
+ }
+ }
+
+ public void flush() throws IOException {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerPool.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.Stack;
+import java.util.concurrent.Future;
+
+/** The compiler pool maintains compiler threads.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompilerPool {
+ // The javac server that created this pool.
+ private JavacServer javacServer;
+ // A semaphore protecting the poolsize number of threads.
+ private Semaphore available;
+ // The stack of compiler threads.
+ private Stack<CompilerThread> compilers = new Stack<CompilerThread>();
+ // And the executor server to spawn threads.
+ private final ExecutorService executorPool;
+ // How many requests are active right now?
+ private int concurrentRequests = 0;
+ // When was the last request finished?
+ private long lastRequestFinished = 0;
+ // The total number of requests to this pool.
+ private int numRequests = 0;
+ // Protect access to the three above values.
+ private static final Object conc = new Object();
+
+ /**
+ * Return the javac server that this pool belongs to.
+ */
+ public JavacServer getJavacServer() {
+ return javacServer;
+ }
+
+ /**
+ * Return how many threads are running at this very moment.
+ */
+ public int numActiveRequests()
+ {
+ synchronized (conc) {
+ return concurrentRequests;
+ }
+ }
+
+ /**
+ * Return when the last request was finished.
+ * I.e. the pool has been idle since.
+ */
+ public long lastRequestFinished()
+ {
+ synchronized (conc) {
+ return lastRequestFinished;
+ }
+ }
+
+ /**
+ * Up the number of active requests.
+ */
+ public int startRequest() {
+ int n;
+ synchronized (conc) {
+ concurrentRequests++;
+ numRequests++;
+ n = numRequests;
+ }
+ return n;
+ }
+
+ /**
+ * Down the number of active requests. Return the current time.
+ */
+ public long stopRequest() {
+ synchronized (conc) {
+ concurrentRequests--;
+ lastRequestFinished = System.currentTimeMillis();
+ }
+ return lastRequestFinished;
+ }
+
+ /**
+ * Create a new compiler pool.
+ */
+ CompilerPool(int poolsize, JavacServer server) {
+ available = new Semaphore(poolsize, true);
+ javacServer = server;
+ executorPool = Executors.newFixedThreadPool(poolsize);
+ lastRequestFinished = System.currentTimeMillis();
+ }
+
+ /**
+ * Execute a compiler thread.
+ */
+ public void execute(CompilerThread ct) {
+ executorPool.execute(ct);
+ }
+
+ /**
+ * Execute a minor task, for example generating bytecodes and writing them to disk,
+ * that belong to a major compiler thread task.
+ */
+ public Future<?> executeSubtask(CompilerThread t, Runnable r) {
+ return executorPool.submit(r);
+ }
+
+ /**
+ * Shutdown the pool.
+ */
+ public void shutdown() {
+ executorPool.shutdown();
+ }
+
+ /**
+ * Acquire a compiler thread from the pool, or block until a thread is available.
+ * If the pools is empty, create a new thread, but never more than is "available".
+ */
+ public CompilerThread grabCompilerThread() throws InterruptedException {
+ available.acquire();
+ if (compilers.empty()) {
+ return new CompilerThread(this);
+ }
+ return compilers.pop();
+ }
+
+ /**
+ * Return the specified compiler thread to the pool.
+ */
+ public void returnCompilerThread(CompilerThread h) {
+ compilers.push(h);
+ available.release();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/CompilerThread.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.concurrent.Future;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.BaseFileManager;
+import com.sun.tools.sjavac.comp.Dependencies;
+import com.sun.tools.sjavac.comp.JavaCompilerWithDeps;
+import com.sun.tools.sjavac.comp.SmartFileManager;
+import com.sun.tools.sjavac.comp.ResolveWithDeps;
+
+/**
+ * The compiler thread maintains a JavaCompiler instance and
+ * can receive a request from the client, perform the compilation
+ * requested and report back the results.
+ *
+ * * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class CompilerThread implements Runnable {
+ private JavacServer javacServer;
+ private CompilerPool compilerPool;
+ private List<Future<?>> subTasks;
+
+ // Communicating over this socket.
+ private Socket socket;
+
+ // The necessary classes to do a compilation.
+ private com.sun.tools.javac.api.JavacTool compiler;
+ private StandardJavaFileManager fileManager;
+ private BaseFileManager fileManagerBase;
+ private SmartFileManager smartFileManager;
+ private Context context;
+
+ // If true, then this thread is serving a request.
+ private boolean inUse = false;
+
+ CompilerThread(CompilerPool cp) {
+ compilerPool = cp;
+ javacServer = cp.getJavacServer();
+ }
+
+ /**
+ * Execute a minor task, for example generating bytecodes and writing them to disk,
+ * that belong to a major compiler thread task.
+ */
+ public synchronized void executeSubtask(Runnable r) {
+ subTasks.add(compilerPool.executeSubtask(this, r));
+ }
+
+ /**
+ * Count the number of active sub tasks.
+ */
+ public synchronized int numActiveSubTasks() {
+ int c = 0;
+ for (Future<?> f : subTasks) {
+ if (!f.isDone() && !f.isCancelled()) {
+ c++;
+ }
+ }
+ return c;
+ }
+
+ /**
+ * Use this socket for the upcoming request.
+ */
+ public void setSocket(Socket s) {
+ socket = s;
+ }
+
+ /**
+ * Prepare the compiler thread for use. It is not yet started.
+ * It will be started by the executor service.
+ */
+ public synchronized void use() {
+ assert(!inUse);
+ inUse = true;
+ compiler = com.sun.tools.javac.api.JavacTool.create();
+ fileManager = compiler.getStandardFileManager(null, null, null);
+ fileManagerBase = (BaseFileManager)fileManager;
+ smartFileManager = new SmartFileManager(fileManager);
+ context = new Context();
+ context.put(JavaFileManager.class, smartFileManager);
+ ResolveWithDeps.preRegister(context);
+ JavaCompilerWithDeps.preRegister(context, this);
+ subTasks = new ArrayList<Future<?>>();
+ }
+
+ /**
+ * Prepare the compiler thread for idleness.
+ */
+ public synchronized void unuse() {
+ assert(inUse);
+ inUse = false;
+ compiler = null;
+ fileManager = null;
+ fileManagerBase = null;
+ smartFileManager = null;
+ context = null;
+ subTasks = null;
+ }
+
+ /**
+ * Expect this key on the next line read from the reader.
+ */
+ private static boolean expect(BufferedReader in, String key) throws IOException {
+ String s = in.readLine();
+ if (s != null && s.equals(key)) {
+ return true;
+ }
+ return false;
+ }
+
+ // The request identifier, for example GENERATE_NEWBYTECODE
+ String id = "";
+
+ public String currentRequestId() {
+ return id;
+ }
+
+ PrintWriter stdout;
+ PrintWriter stderr;
+ int forcedExitCode = 0;
+
+ public void logError(String msg) {
+ stderr.println(msg);
+ forcedExitCode = -1;
+ }
+
+ /**
+ * Invoked by the executor service.
+ */
+ public void run() {
+ // Unique nr that identifies this request.
+ int thisRequest = compilerPool.startRequest();
+ long start = System.currentTimeMillis();
+ int numClasses = 0;
+ StringBuilder compiledPkgs = new StringBuilder();
+ use();
+
+ PrintWriter out = null;
+ try {
+ javacServer.log("<"+thisRequest+"> Connect from "+socket.getRemoteSocketAddress()+" activethreads="+compilerPool.numActiveRequests());
+ BufferedReader in = new BufferedReader(new InputStreamReader(
+ socket.getInputStream()));
+ out = new PrintWriter(new OutputStreamWriter(
+ socket.getOutputStream()));
+ if (!expect(in, JavacServer.PROTOCOL_COOKIE_VERSION)) {
+ javacServer.log("<"+thisRequest+"> Bad protocol from ip "+socket.getRemoteSocketAddress());
+ return;
+ }
+
+ String cookie = in.readLine();
+ if (cookie == null || !cookie.equals(""+javacServer.getCookie())) {
+ javacServer.log("<"+thisRequest+"> Bad cookie from ip "+socket.getRemoteSocketAddress());
+ return;
+ }
+ if (!expect(in, JavacServer.PROTOCOL_CWD)) {
+ return;
+ }
+ String cwd = in.readLine();
+ if (cwd == null)
+ return;
+ if (!expect(in, JavacServer.PROTOCOL_ID)) {
+ return;
+ }
+ id = in.readLine();
+ if (id == null)
+ return;
+ if (!expect(in, JavacServer.PROTOCOL_ARGS)) {
+ return;
+ }
+ ArrayList<String> the_options = new ArrayList<String>();
+ ArrayList<File> the_classes = new ArrayList<File>();
+ Iterable<File> path = Arrays.<File> asList(new File(cwd));
+
+ for (;;) {
+ String l = in.readLine();
+ if (l == null)
+ return;
+ if (l.equals(JavacServer.PROTOCOL_SOURCES_TO_COMPILE))
+ break;
+ if (l.startsWith("--server:"))
+ continue;
+ if (!l.startsWith("-") && l.endsWith(".java")) {
+ the_classes.add(new File(l));
+ numClasses++;
+ } else {
+ the_options.add(l);
+ }
+ continue;
+ }
+
+ // Load sources to compile
+ Set<URI> sourcesToCompile = new HashSet<URI>();
+ for (;;) {
+ String l = in.readLine();
+ if (l == null)
+ return;
+ if (l.equals(JavacServer.PROTOCOL_VISIBLE_SOURCES))
+ break;
+ try {
+ sourcesToCompile.add(new URI(l));
+ numClasses++;
+ } catch (URISyntaxException e) {
+ return;
+ }
+ }
+ // Load visible sources
+ Set<URI> visibleSources = new HashSet<URI>();
+ boolean fix_drive_letter_case = System.getProperty("os.name").toLowerCase().equals("windows");
+ for (;;) {
+ String l = in.readLine();
+ if (l == null)
+ return;
+ if (l.equals(JavacServer.PROTOCOL_END))
+ break;
+ try {
+ URI u = new URI(l);
+ if (fix_drive_letter_case) {
+ // Make sure the driver letter is lower case.
+ String s = u.toString();
+ if (s.startsWith("file:/") &&
+ Character.isUpperCase(s.charAt(6))) {
+ u = new URI("file:/"+Character.toLowerCase(s.charAt(6))+s.substring(7));
+ }
+ }
+ visibleSources.add(u);
+ } catch (URISyntaxException e) {
+ return;
+ }
+ }
+
+ // A completed request has been received.
+
+ // Now setup the actual compilation....
+ // First deal with explicit source files on cmdline and in at file.
+ com.sun.tools.javac.util.ListBuffer<JavaFileObject> compilationUnits =
+ new com.sun.tools.javac.util.ListBuffer<JavaFileObject>();
+ for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(the_classes)) {
+ compilationUnits.append(i);
+ }
+ // Now deal with sources supplied as source_to_compile.
+ com.sun.tools.javac.util.ListBuffer<File> sourcesToCompileFiles =
+ new com.sun.tools.javac.util.ListBuffer<File>();
+ for (URI u : sourcesToCompile) {
+ sourcesToCompileFiles.append(new File(u));
+ }
+ for (JavaFileObject i : fileManager.getJavaFileObjectsFromFiles(sourcesToCompileFiles)) {
+ compilationUnits.append(i);
+ }
+ // Log the options to be used.
+ StringBuilder options = new StringBuilder();
+ for (String s : the_options) {
+ options.append(">").append(s).append("< ");
+ }
+ javacServer.log(id+" <"+thisRequest+"> options "+options.toString());
+
+ forcedExitCode = 0;
+ // Create a new logger.
+ StringWriter stdoutLog = new StringWriter();
+ StringWriter stderrLog = new StringWriter();
+ stdout = new PrintWriter(stdoutLog);
+ stderr = new PrintWriter(stderrLog);
+ com.sun.tools.javac.main.Main.Result rc = com.sun.tools.javac.main.Main.Result.OK;
+ try {
+ if (compilationUnits.size() > 0) {
+ // Bind the new logger to the existing context.
+ context.put(Log.outKey, stderr);
+ Log.instance(context).setWriter(Log.WriterKind.NOTICE, stdout);
+ Log.instance(context).setWriter(Log.WriterKind.WARNING, stderr);
+ Log.instance(context).setWriter(Log.WriterKind.ERROR, stderr);
+ // Process the options.
+ com.sun.tools.javac.api.JavacTool.processOptions(context, smartFileManager, the_options);
+ fileManagerBase.setContext(context);
+ smartFileManager.setVisibleSources(visibleSources);
+ smartFileManager.cleanArtifacts();
+ smartFileManager.setLog(stdout);
+ Dependencies.instance(context).reset();
+
+ com.sun.tools.javac.main.Main ccompiler = new com.sun.tools.javac.main.Main("javacTask", stderr);
+ String[] aa = the_options.toArray(new String[0]);
+
+ // Do the compilation!
+ rc = ccompiler.compile(aa, context, compilationUnits.toList(), null);
+
+ while (numActiveSubTasks()>0) {
+ try { Thread.sleep(1000); } catch (InterruptedException e) { }
+ }
+
+ smartFileManager.flush();
+ }
+ } catch (Exception e) {
+ stderr.println(e.getMessage());
+ forcedExitCode = -1;
+ }
+
+ // Send the response..
+ out.println(JavacServer.PROTOCOL_STDOUT);
+ out.print(stdoutLog);
+ out.println(JavacServer.PROTOCOL_STDERR);
+ out.print(stderrLog);
+ // The compilation is complete! And errors will have already been printed on out!
+ out.println(JavacServer.PROTOCOL_PACKAGE_ARTIFACTS);
+ Map<String,Set<URI>> pa = smartFileManager.getPackageArtifacts();
+ for (String aPkgName : pa.keySet()) {
+ out.println("+"+aPkgName);
+ Set<URI> as = pa.get(aPkgName);
+ for (URI a : as) {
+ out.println(" "+a.toString());
+ }
+ }
+ Dependencies deps = Dependencies.instance(context);
+ out.println(JavacServer.PROTOCOL_PACKAGE_DEPENDENCIES);
+ Map<String,Set<String>> pd = deps.getDependencies();
+ for (String aPkgName : pd.keySet()) {
+ out.println("+"+aPkgName);
+ Set<String> ds = pd.get(aPkgName);
+ // Everything depends on java.lang
+ if (!ds.contains(":java.lang")) ds.add(":java.lang");
+ for (String d : ds) {
+ out.println(" "+d);
+ }
+ }
+ out.println(JavacServer.PROTOCOL_PACKAGE_PUBLIC_APIS);
+ Map<String,String> pp = deps.getPubapis();
+ for (String aPkgName : pp.keySet()) {
+ out.println("+"+aPkgName);
+ String ps = pp.get(aPkgName);
+ // getPubapis added a space to each line!
+ out.println(ps);
+ compiledPkgs.append(aPkgName+" ");
+ }
+ out.println(JavacServer.PROTOCOL_SYSINFO);
+ out.println("num_cores=" + Runtime.getRuntime().availableProcessors());
+ out.println("max_memory=" + Runtime.getRuntime().maxMemory());
+ out.println(JavacServer.PROTOCOL_RETURN_CODE);
+
+ // Errors from sjavac that affect compilation status!
+ int rcv = rc.exitCode;
+ if (rcv == 0 && forcedExitCode != 0) {
+ rcv = forcedExitCode;
+ }
+ out.println("" + rcv);
+ out.println(JavacServer.PROTOCOL_END);
+ out.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (out != null) out.close();
+ if (!socket.isClosed()) {
+ socket.close();
+ }
+ socket = null;
+ } catch (Exception e) {
+ javacServer.log("ERROR "+e);
+ e.printStackTrace();
+ }
+ compilerPool.stopRequest();
+ long duration = System.currentTimeMillis()-start;
+ javacServer.addBuildTime(duration);
+ float classpersec = ((float)numClasses)*(((float)1000.0)/((float)duration));
+ javacServer.log(id+" <"+thisRequest+"> "+compiledPkgs+" duration " + duration+ " ms num_classes="+numClasses+
+ " classpersec="+classpersec+" subtasks="+subTasks.size());
+ javacServer.flushLog();
+ unuse();
+ compilerPool.returnCompilerThread(this);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,751 @@
+/*
+ * Copyright (c) 2011-2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.sjavac.server;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.Map;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Random;
+
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.ProblemException;
+import java.io.*;
+import java.util.*;
+
+/**
+ * The JavacServer class contains methods both to setup a server that responds to requests and methods to connect to this server.
+ *
+ * <p><b>This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are
+ * subject to change or deletion without notice.</b></p>
+ */
+public class JavacServer {
+ // Responding to this tcp/ip port on localhost.
+
+ private final ServerSocket serverSocket;
+ // The secret cookie shared between server and client through the port file.
+ private final long myCookie;
+ // When the server was started.
+ private long serverStart;
+ // Accumulated build time for all requests, not counting idle time.
+ private long totalBuildTime;
+ // The javac server specific log file.
+ PrintWriter theLog;
+ // The compiler pool that maintains the compiler threads.
+ CompilerPool compilerPool;
+ // For the client, all port files fetched, one per started javac server.
+ // Though usually only one javac server is started by a client.
+ private static Map<String, PortFile> allPortFiles;
+ private static Map<String, Long> maxServerMemory;
+ final static int ERROR_FATAL = -1;
+ final static int ERROR_BUT_TRY_AGAIN = -4712;
+ final static String PROTOCOL_COOKIE_VERSION = "----THE-COOKIE-V2----";
+ final static String PROTOCOL_CWD = "----THE-CWD----";
+ final static String PROTOCOL_ID = "----THE-ID----";
+ final static String PROTOCOL_ARGS = "----THE-ARGS----";
+ final static String PROTOCOL_SOURCES_TO_COMPILE = "----THE-SOURCES-TO-COMPILE----";
+ final static String PROTOCOL_VISIBLE_SOURCES = "----THE-VISIBLE-SOURCES----";
+ final static String PROTOCOL_END = "----THE-END----";
+ final static String PROTOCOL_STDOUT = "----THE-STDOUT----";
+ final static String PROTOCOL_STDERR = "----THE-STDERR----";
+ final static String PROTOCOL_PACKAGE_ARTIFACTS = "----THE-PACKAGE_ARTIFACTS----";
+ final static String PROTOCOL_PACKAGE_DEPENDENCIES = "----THE-PACKAGE_DEPENDENCIES----";
+ final static String PROTOCOL_PACKAGE_PUBLIC_APIS = "----THE-PACKAGE-PUBLIC-APIS----";
+ final static String PROTOCOL_SYSINFO = "----THE-SYSINFO----";
+ final static String PROTOCOL_RETURN_CODE = "----THE-RETURN-CODE----";
+ // Check if the portfile is gone, every 5 seconds.
+ static int CHECK_PORTFILE_INTERVAL = 5;
+ // Wait 2 seconds for response, before giving up on javac server.
+ static int CONNECTION_TIMEOUT = 2;
+ static int WAIT_BETWEEN_CONNECT_ATTEMPTS = 1;
+ static int MAX_NUM_CONNECT_ATTEMPTS = 3;
+
+ /**
+ * Acquire the port file. Synchronized since several threads inside an smart javac wrapper client acquires the same port file at the same time.
+ */
+ private static synchronized PortFile getPortFile(String filename) throws FileNotFoundException {
+ if (allPortFiles == null) {
+ allPortFiles = new HashMap<String, PortFile>();
+ }
+ PortFile pf = allPortFiles.get(filename);
+ if (pf == null) {
+ pf = new PortFile(filename);
+ allPortFiles.put(filename, pf);
+ }
+ return pf;
+ }
+
+ /**
+ * Get the cookie used for this server.
+ */
+ long getCookie() {
+ return myCookie;
+ }
+
+ /**
+ * Get the port used for this server.
+ */
+ int getPort() {
+ return serverSocket.getLocalPort();
+ }
+
+ /**
+ * Sum up the total build time for this javac server.
+ */
+ public void addBuildTime(long inc) {
+ totalBuildTime += inc;
+ }
+
+ /**
+ * Log this message.
+ */
+ public void log(String msg) {
+ if (theLog != null) {
+ theLog.println(msg);
+ } else {
+ System.err.println(msg);
+ }
+ }
+
+ /**
+ * Make sure the log is flushed.
+ */
+ public void flushLog() {
+ if (theLog != null) {
+ theLog.flush();
+ }
+ }
+
+ /**
+ * Start a server using a settings string. Typically: "--startserver:portfile=/tmp/myserver,poolsize=3" and the string "portfile=/tmp/myserver,poolsize=3"
+ * is sent as the settings parameter. Returns 0 on success, -1 on failure.
+ */
+ public static int startServer(String settings, PrintStream err) {
+ try {
+ String portfile = Util.extractStringOption("portfile", settings);
+ // The log file collects more javac server specific log information.
+ String logfile = Util.extractStringOption("logfile", settings);
+ // The stdouterr file collects all the System.out and System.err writes to disk.
+ String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+ // We could perhaps use System.setOut and setErr here.
+ // But for the moment we rely on the client to spawn a shell where stdout
+ // and stderr are redirected already.
+ // The pool size is a limit the number of concurrent compiler threads used.
+ // The server might use less than these to avoid memory problems.
+ int poolsize = Util.extractIntOption("poolsize", settings);
+ if (poolsize <= 0) {
+ // If not set, default to the number of cores.
+ poolsize = Runtime.getRuntime().availableProcessors();
+ }
+
+ // How many seconds of inactivity will the server accept before quitting?
+ int keepalive = Util.extractIntOption("keepalive", settings);
+ if (keepalive <= 0) {
+ keepalive = 120;
+ }
+ // The port file is locked and the server port and cookie is written into it.
+ PortFile portFile = getPortFile(portfile);
+ JavacServer s;
+
+ synchronized (portFile) {
+ portFile.lock();
+ portFile.getValues();
+ if (portFile.containsPortInfo()) {
+ err.println("Javac server not started because portfile exists!");
+ portFile.unlock();
+ return -1;
+ }
+ s = new JavacServer(poolsize, logfile);
+ portFile.setValues(s.getPort(), s.getCookie());
+ portFile.unlock();
+ }
+
+ // Run the server. Will delete the port file when shutting down.
+ // It will shut down automatically when no new requests have come in
+ // during the last 125 seconds.
+ s.run(portFile, err, keepalive);
+ // The run loop for the server has exited.
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ return -1;
+ }
+ }
+
+ /**
+ * Dispatch a compilation request to a javac server.
+ *
+ * @param args are the command line args to javac and is allowed to contain source files, @file and other command line options to javac.
+ *
+ * The generated classes, h files and other artifacts from the javac invocation are stored by the javac server to disk.
+ *
+ * @param sources_to_compile The sources to compile.
+ *
+ * @param visibleSources If visible sources has a non zero size, then visible_sources are the only files in the file system that the javac server can see!
+ * (Sources to compile are always visible.) The visible sources are those supplied by the (filtered) -sourcepath
+ *
+ * @param visibleClasses If visible classes for a specific root/jar has a non zero size, then visible_classes are the only class files that the javac server
+ * can see, in that root/jar. It maps from a classpath root or a jar file to the set of visible classes for that root/jar.
+ *
+ * The server return meta data about the build in the following parameters.
+ * @param package_artifacts, map from package name to set of created artifacts for that package.
+ * @param package_dependencies, map from package name to set of packages that it depends upon.
+ * @param package_pubapis, map from package name to unique string identifying its pub api.
+ */
+ public static int useServer(String settings, String[] args,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources,
+ Map<URI, Set<String>> visibleClasses,
+ Map<String, Set<URI>> packageArtifacts,
+ Map<String, Set<String>> packageDependencies,
+ Map<String, String> packagePubapis,
+ SysInfo sysinfo,
+ PrintStream out,
+ PrintStream err) {
+ try {
+ // The id can perhaps be used in the future by the javac server to reuse the
+ // JavaCompiler instance for several compiles using the same id.
+ String id = Util.extractStringOption("id", settings);
+ String portfile = Util.extractStringOption("portfile", settings);
+ String logfile = Util.extractStringOption("logfile", settings);
+ String stdouterrfile = Util.extractStringOption("stdouterrfile", settings);
+ String background = Util.extractStringOption("background", settings);
+ if (background == null || !background.equals("false")) {
+ background = "true";
+ }
+ // The sjavac option specifies how the server part of sjavac is spawned.
+ // If you have the experimental sjavac in your path, you are done. If not, you have
+ // to point to a com.sun.tools.sjavac.Main that supports --startserver
+ // for example by setting: sjavac=java%20-jar%20...javac.jar%com.sun.tools.sjavac.Main
+ String sjavac = Util.extractStringOption("sjavac", settings);
+ int poolsize = Util.extractIntOption("poolsize", settings);
+ int keepalive = Util.extractIntOption("keepalive", settings);
+
+ if (keepalive <= 0) {
+ // Default keepalive for server is 120 seconds.
+ // I.e. it will accept 120 seconds of inactivity before quitting.
+ keepalive = 120;
+ }
+ if (portfile == null) {
+ err.println("No portfile was specified!");
+ return -1;
+ }
+ if (logfile == null) {
+ logfile = portfile + ".javaclog";
+ }
+ if (stdouterrfile == null) {
+ stdouterrfile = portfile + ".stdouterr";
+ }
+ // Default to sjavac and hope it is in the path.
+ if (sjavac == null) {
+ sjavac = "sjavac";
+ }
+
+ int attempts = 0;
+ int rc = -1;
+ do {
+ PortFile port_file = getPortFile(portfile);
+ synchronized (port_file) {
+ port_file.lock();
+ port_file.getValues();
+ port_file.unlock();
+ }
+ if (!port_file.containsPortInfo()) {
+ String cmd = fork(sjavac, port_file.getFilename(), logfile, poolsize, keepalive, err, stdouterrfile, background);
+
+ if (background.equals("true") && !port_file.waitForValidValues()) {
+ // Ouch the server did not start! Lets print its stdouterrfile and the command used.
+ printFailedAttempt(cmd, stdouterrfile, err);
+ // And give up.
+ return -1;
+ }
+ }
+ rc = connectAndCompile(port_file, id, args, sourcesToCompile, visibleSources,
+ packageArtifacts, packageDependencies, packagePubapis, sysinfo,
+ out, err);
+ // Try again until we manage to connect. Any error after that
+ // will cause the compilation to fail.
+ if (rc == ERROR_BUT_TRY_AGAIN) {
+ // We could not connect to the server. Try again.
+ attempts++;
+ try {
+ Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
+ } catch (InterruptedException e) {
+ }
+ }
+ } while (rc == ERROR_BUT_TRY_AGAIN && attempts < MAX_NUM_CONNECT_ATTEMPTS);
+ return rc;
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ return -1;
+ }
+ }
+
+ private static void printFailedAttempt(String cmd, String f, PrintStream err) {
+ err.println("---- Failed to start javac server with this command -----");
+ err.println(cmd);
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(f));
+ err.println("---- stdout/stderr output from attempt to start javac server -----");
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ break;
+ }
+ err.println(l);
+ }
+ err.println("------------------------------------------------------------------");
+ } catch (Exception e) {
+ err.println("The stdout/stderr output in file " + f + " does not exist and the server did not start.");
+ }
+ }
+
+ /**
+ * Spawn the server instance.
+ */
+
+ private JavacServer(int poolSize, String logfile) throws IOException {
+ serverStart = System.currentTimeMillis();
+ // Create a server socket on a random port that is bound to the localhost/127.0.0.1 interface.
+ // I.e only local processes can connect to this port.
+ serverSocket = new ServerSocket(0, 128, InetAddress.getByName(null));
+ compilerPool = new CompilerPool(poolSize, this);
+ Random rnd = new Random();
+ myCookie = rnd.nextLong();
+ theLog = new PrintWriter(logfile);
+ log("Javac server started. port=" + getPort() + " date=" + (new java.util.Date()) + " with poolsize=" + poolSize);
+ flushLog();
+ }
+
+ /**
+ * Fork a background process. Returns the command line used that can be printed if something failed.
+ */
+ private static String fork(String sjavac, String portfile, String logfile, int poolsize, int keepalive,
+ final PrintStream err, String stdouterrfile, String background)
+ throws IOException, ProblemException {
+ if (stdouterrfile != null && stdouterrfile.trim().equals("")) {
+ stdouterrfile = null;
+ }
+ final String startserver = "--startserver:portfile=" + portfile + ",logfile=" + logfile + ",stdouterrfile=" + stdouterrfile + ",poolsize=" + poolsize + ",keepalive="+ keepalive;
+
+ if (background.equals("true")) {
+ sjavac += "%20" + startserver;
+ sjavac = sjavac.replaceAll("%20", " ");
+ sjavac = sjavac.replaceAll("%2C", ",");
+ // If the java/sh/cmd launcher fails the failure will be captured by stdouterr because of the redirection here.
+ String[] cmd = {"/bin/sh", "-c", sjavac + " >> " + stdouterrfile + " 2>&1"};
+ if (!(new File("/bin/sh")).canExecute()) {
+ ArrayList<String> wincmd = new ArrayList<String>();
+ wincmd.add("cmd");
+ wincmd.add("/c");
+ wincmd.add("start");
+ wincmd.add("cmd");
+ wincmd.add("/c");
+ wincmd.add(sjavac + " >> " + stdouterrfile + " 2>&1");
+ cmd = wincmd.toArray(new String[wincmd.size()]);
+ }
+ Process pp = null;
+ try {
+ pp = Runtime.getRuntime().exec(cmd);
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ e.printStackTrace(new PrintWriter(stdouterrfile));
+ }
+ StringBuilder rs = new StringBuilder();
+ for (String s : cmd) {
+ rs.append(s + " ");
+ }
+ return rs.toString();
+ }
+
+ // Do not spawn a background server, instead run it within the same JVM.
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ JavacServer.startServer(startserver, err);
+ } catch (Throwable t) {
+ t.printStackTrace(err);
+ }
+ }
+ };
+ t.start();
+ return "";
+ }
+
+ /**
+ * Expect this key on the next line read from the reader.
+ */
+ private static boolean expect(BufferedReader in, String key) throws IOException {
+ String s = in.readLine();
+ if (s != null && s.equals(key)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Make a request to the server only to get the maximum possible heap size to use for compilations.
+ *
+ * @param port_file The port file used to synchronize creation of this server.
+ * @param id The identify of the compilation.
+ * @param out Standard out information.
+ * @param err Standard err information.
+ * @return The maximum heap size in bytes.
+ */
+ public static SysInfo connectGetSysInfo(String serverSettings, PrintStream out, PrintStream err) {
+ SysInfo sysinfo = new SysInfo(-1, -1);
+ String id = Util.extractStringOption("id", serverSettings);
+ String portfile = Util.extractStringOption("portfile", serverSettings);
+ try {
+ PortFile pf = getPortFile(portfile);
+ useServer(serverSettings, new String[0],
+ new HashSet<URI>(),
+ new HashSet<URI>(),
+ new HashMap<URI, Set<String>>(),
+ new HashMap<String, Set<URI>>(),
+ new HashMap<String, Set<String>>(),
+ new HashMap<String, String>(),
+ sysinfo, out, err);
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ }
+ return sysinfo;
+ }
+
+ /**
+ * Connect and compile using the javac server settings and the args. When using more advanced features, the sources_to_compile and visible_sources are
+ * supplied to the server and meta data is returned in package_artifacts, package_dependencies and package_pubapis.
+ */
+ private static int connectAndCompile(PortFile portFile, String id, String[] args,
+ Set<URI> sourcesToCompile,
+ Set<URI> visibleSources,
+ Map<String, Set<URI>> packageArtifacts,
+ Map<String, Set<String>> packageDependencies,
+ Map<String, String> packagePublicApis,
+ SysInfo sysinfo,
+ PrintStream out,
+ PrintStream err) {
+ int rc = -3;
+ try {
+ int port = portFile.getPort();
+ if (port == 0) {
+ return ERROR_BUT_TRY_AGAIN;
+ }
+ long cookie = portFile.getCookie();
+
+ // Acquire the localhost/127.0.0.1 address.
+ InetAddress addr = InetAddress.getByName(null);
+ SocketAddress sockaddr = new InetSocketAddress(addr, port);
+ Socket sock = new Socket();
+ int timeoutMs = CONNECTION_TIMEOUT * 1000;
+ try {
+ sock.connect(sockaddr, timeoutMs);
+ } catch (java.net.ConnectException e) {
+ err.println("Could not connect to javac server found in portfile: " + portFile.getFilename() + " " + e);
+ return ERROR_BUT_TRY_AGAIN;
+ }
+ if (!sock.isConnected()) {
+ err.println("Could not connect to javac server found in portfile: " + portFile.getFilename());
+ return ERROR_BUT_TRY_AGAIN;
+ }
+ BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ PrintWriter sockout = new PrintWriter(sock.getOutputStream());
+
+ sockout.println(PROTOCOL_COOKIE_VERSION);
+ sockout.println("" + cookie);
+ sockout.println(PROTOCOL_CWD);
+ sockout.println(System.getProperty("user.dir"));
+ sockout.println(PROTOCOL_ID);
+ sockout.println(id);
+ sockout.println(PROTOCOL_ARGS);
+ for (String s : args) {
+ StringBuffer buf = new StringBuffer();
+ String[] paths = s.split(File.pathSeparator);
+ int c = 0;
+ for (String path : paths) {
+ File f = new File(path);
+ if (f.isFile() || f.isDirectory()) {
+ buf.append(f.getAbsolutePath());
+ c++;
+ if (c < paths.length) {
+ buf.append(File.pathSeparator);
+ }
+ } else {
+ buf = new StringBuffer(s);
+ break;
+ }
+ }
+ sockout.println(buf.toString());
+ }
+ sockout.println(PROTOCOL_SOURCES_TO_COMPILE);
+ for (URI uri : sourcesToCompile) {
+ sockout.println(uri.toString());
+ }
+ sockout.println(PROTOCOL_VISIBLE_SOURCES);
+ for (URI uri : visibleSources) {
+ sockout.println(uri.toString());
+ }
+ sockout.println(PROTOCOL_END);
+ sockout.flush();
+
+ StringBuffer stdout = new StringBuffer();
+ StringBuffer stderr = new StringBuffer();
+
+ if (!expect(in, PROTOCOL_STDOUT)) {
+ return ERROR_FATAL;
+ }
+ // Load stdout
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_STDERR)) {
+ break;
+ }
+ stdout.append(l);
+ stdout.append('\n');
+ }
+ // Load stderr
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_PACKAGE_ARTIFACTS)) {
+ break;
+ }
+ stderr.append(l);
+ stderr.append('\n');
+ }
+ // Load the package artifacts
+ Set<URI> lastUriSet = null;
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_PACKAGE_DEPENDENCIES)) {
+ break;
+ }
+ if (l.length() > 1 && l.charAt(0) == '+') {
+ String pkg = l.substring(1);
+ lastUriSet = new HashSet<URI>();
+ packageArtifacts.put(pkg, lastUriSet);
+ } else if (l.length() > 1 && lastUriSet != null) {
+ lastUriSet.add(new URI(l.substring(1)));
+ }
+ }
+ // Load package dependencies
+ Set<String> lastPackageSet = null;
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_PACKAGE_PUBLIC_APIS)) {
+ break;
+ }
+ if (l.length() > 1 && l.charAt(0) == '+') {
+ String pkg = l.substring(1);
+ lastPackageSet = new HashSet<String>();
+ packageDependencies.put(pkg, lastPackageSet);
+ } else if (l.length() > 1 && lastPackageSet != null) {
+ lastPackageSet.add(l.substring(1));
+ }
+ }
+ // Load package pubapis
+ Map<String, StringBuffer> tmp = new HashMap<String, StringBuffer>();
+ StringBuffer lastPublicApi = null;
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_SYSINFO)) {
+ break;
+ }
+ if (l.length() > 1 && l.charAt(0) == '+') {
+ String pkg = l.substring(1);
+ lastPublicApi = new StringBuffer();
+ tmp.put(pkg, lastPublicApi);
+ } else if (l.length() > 1 && lastPublicApi != null) {
+ lastPublicApi.append(l.substring(1));
+ lastPublicApi.append("\n");
+ }
+ }
+ for (String p : tmp.keySet()) {
+ assert (packagePublicApis.get(p) == null);
+ String api = tmp.get(p).toString();
+ packagePublicApis.put(p, api);
+ }
+ // Now reading the max memory possible.
+ for (;;) {
+ String l = in.readLine();
+ if (l == null) {
+ return ERROR_FATAL;
+ }
+ if (l.equals(PROTOCOL_RETURN_CODE)) {
+ break;
+ }
+ if (l.startsWith("num_cores=") && sysinfo != null) {
+ sysinfo.numCores = Integer.parseInt(l.substring(10));
+ }
+ if (l.startsWith("max_memory=") && sysinfo != null) {
+ sysinfo.maxMemory = Long.parseLong(l.substring(11));
+ }
+ }
+ String l = in.readLine();
+ if (l == null) {
+ err.println("No return value from the server!");
+ return ERROR_FATAL;
+ }
+ rc = Integer.parseInt(l);
+ out.print(stdout);
+ err.print(stderr);
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ }
+ return rc;
+ }
+
+ /**
+ * Run the server thread until it exits. Either because of inactivity or because the port file has been deleted by someone else, or overtaken by some other
+ * javac server.
+ */
+ private void run(PortFile portFile, PrintStream err, int keepalive) {
+ boolean fileDeleted = false;
+ long timeSinceLastCompile;
+ try {
+ // Every 5 second (check_portfile_interval) we test if the portfile has disappeared => quit
+ // Or if the last request was finished more than 125 seconds ago => quit
+ // 125 = seconds_of_inactivity_before_shutdown+check_portfile_interval
+ serverSocket.setSoTimeout(CHECK_PORTFILE_INTERVAL*1000);
+ for (;;) {
+ try {
+ Socket s = serverSocket.accept();
+ CompilerThread ct = compilerPool.grabCompilerThread();
+ ct.setSocket(s);
+ compilerPool.execute(ct);
+ flushLog();
+ } catch (java.net.SocketTimeoutException e) {
+ if (compilerPool.numActiveRequests() > 0) {
+ // Never quit while there are active requests!
+ continue;
+ }
+ // If this is the timeout after the portfile
+ // has been deleted by us. Then we truly stop.
+ if (fileDeleted) {
+ log("Quitting because of "+(keepalive+CHECK_PORTFILE_INTERVAL)+" seconds of inactivity!");
+ break;
+ }
+ // Check if the portfile is still there.
+ if (!portFile.exists()) {
+ // Time to quit because the portfile was deleted by another
+ // process, probably by the makefile that is done building.
+ log("Quitting because portfile was deleted!");
+ flushLog();
+ break;
+ }
+ // Check if portfile.stop is still there.
+ if (portFile.markedForStop()) {
+ // Time to quit because another process touched the file
+ // server.port.stop to signal that the server should stop.
+ // This is necessary on some operating systems that lock
+ // the port file hard!
+ log("Quitting because a portfile.stop file was found!");
+ portFile.delete();
+ flushLog();
+ break;
+ }
+ // Does the portfile still point to me?
+ if (!portFile.stillMyValues()) {
+ // Time to quit because another build has started.
+ log("Quitting because portfile is now owned by another javac server!");
+ flushLog();
+ break;
+ }
+
+ // Check how long since the last request finished.
+ long diff = System.currentTimeMillis() - compilerPool.lastRequestFinished();
+ if (diff < keepalive * 1000) {
+ // Do not quit if we have waited less than 120 seconds.
+ continue;
+ }
+ // Ok, time to quit because of inactivity. Perhaps the build
+ // was killed and the portfile not cleaned up properly.
+ portFile.delete();
+ fileDeleted = true;
+ log("" + keepalive + " seconds of inactivity quitting in "
+ + CHECK_PORTFILE_INTERVAL + " seconds!");
+ flushLog();
+ // Now we have a second 5 second grace
+ // period where javac remote requests
+ // that have loaded the data from the
+ // recently deleted portfile can connect
+ // and complete their requests.
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace(err);
+ e.printStackTrace(theLog);
+ flushLog();
+ } finally {
+ compilerPool.shutdown();
+ }
+ long realTime = System.currentTimeMillis() - serverStart;
+ log("Shutting down.");
+ log("Total wall clock time " + realTime + "ms build time " + totalBuildTime + "ms");
+ flushLog();
+ }
+
+ public static void cleanup(String... args) {
+ String settings = Util.findServerSettings(args);
+ if (settings == null) return;
+ String portfile = Util.extractStringOption("portfile", settings);
+ String background = Util.extractStringOption("background", settings);
+ if (background != null && background.equals("false")) {
+ // If the server runs within this jvm, then delete the portfile,
+ // since this jvm is about to exit soon.
+ File f = new File(portfile);
+ f.delete();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.server;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.FileLockInterruptionException;
+import com.sun.tools.sjavac.Log;
+
+/**
+ * The PortFile class mediates access to a short binary file containing the tcp/ip port (for the localhost)
+ * and a cookie necessary for the server answering on that port. The file can be locked using file system
+ * primitives to avoid race conditions when several javac clients are started at the same. Note that file
+ * system locking is not always supported on a all operating systems and/or file systems.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+class PortFile {
+
+ // Port file format:
+ // byte ordering: high byte first = big endian
+ // Magic nr, 4 byte int, first in file.
+ private final static int magicNr = 0x1174;
+ // Followed by a 4 byte int, with the port nr.
+ // Followed by a 8 byte long, with cookie nr.
+
+ private String filename;
+ private File file;
+ private File stopFile;
+ private RandomAccessFile rwfile;
+ private FileChannel channel;
+ private FileLock lock;
+
+ private boolean containsPortInfo;
+ private int serverPort;
+ private long serverCookie;
+ private int myServerPort;
+ private long myServerCookie;
+
+ /**
+ * Create a new portfile.
+ * @param filename is the path to the file.
+ */
+ public PortFile(String fn) throws FileNotFoundException
+ {
+ filename = fn;
+ file = new File(filename);
+ stopFile = new File(filename+".stop");
+ rwfile = new RandomAccessFile(file, "rw");
+ // The rwfile should only be readable by the owner of the process
+ // and no other! How do we do that on a RandomAccessFile?
+ channel = rwfile.getChannel();
+ containsPortInfo = false;
+ lock = null;
+ }
+
+ /**
+ * Lock the port file.
+ */
+ void lock() throws IOException {
+ lock = channel.lock();
+ }
+
+ /**
+ * Read the values from the port file in the file system.
+ * Expects the port file to be locked.
+ */
+ public void getValues() {
+ containsPortInfo = false;
+ if (lock == null) {
+ // Not locked, remain ignorant about port file contents.
+ return;
+ }
+ try {
+ if (rwfile.length()>0) {
+ rwfile.seek(0);
+ int nr = rwfile.readInt();
+ serverPort = rwfile.readInt();
+ serverCookie = rwfile.readLong();
+
+ if (nr == magicNr) {
+ containsPortInfo = true;
+ } else {
+ containsPortInfo = false;
+ }
+ }
+ } catch (Exception e) {
+ containsPortInfo = false;
+ }
+ }
+
+ /**
+ * Did the locking and getValues succeed?
+ */
+ public boolean containsPortInfo() {
+ return containsPortInfo;
+ }
+
+ /**
+ * If so, then we can acquire the tcp/ip port on localhost.
+ */
+ public int getPort() {
+ assert(containsPortInfo);
+ return serverPort;
+ }
+
+ /**
+ * If so, then we can acquire the server cookie.
+ */
+ public long getCookie() {
+ assert(containsPortInfo);
+ return serverCookie;
+ }
+
+ /**
+ * Store the values into the locked port file.
+ */
+ public void setValues(int port, long cookie) throws IOException {
+ assert(lock != null);
+ rwfile.seek(0);
+ // Write the magic nr that identifes a port file.
+ rwfile.writeInt(magicNr);
+ rwfile.writeInt(port);
+ rwfile.writeLong(cookie);
+ myServerPort = port;
+ myServerCookie = cookie;
+ }
+
+ /**
+ * Delete the port file.
+ */
+ public void delete() throws IOException {
+ // Access to file must be closed before deleting.
+ rwfile.close();
+ // Now delete.
+ file.delete();
+ }
+
+ /**
+ * Is the port file still there?
+ */
+ public boolean exists() throws IOException {
+ return file.exists();
+ }
+
+ /**
+ * Is a stop file there?
+ */
+ public boolean markedForStop() throws IOException {
+ if (stopFile.exists()) {
+ try {
+ stopFile.delete();
+ } catch (Exception e)
+ {}
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Unlock the port file.
+ */
+ public void unlock() throws IOException {
+ assert(lock != null);
+ lock.release();
+ lock = null;
+ }
+
+ /**
+ * Wait for the port file to contain values that look valid.
+ * Return true, if a-ok, false if the valid values did not materialize within 5 seconds.
+ */
+ public synchronized boolean waitForValidValues() throws IOException, FileNotFoundException {
+ for (int tries = 0; tries < 50; tries++) {
+ lock();
+ getValues();
+ unlock();
+ if (containsPortInfo) {
+ Log.debug("Found valid values in port file after waiting "+(tries*100)+"ms");
+ return true;
+ }
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e)
+ {}
+ }
+ Log.debug("Gave up waiting for valid values in port file");
+ return false;
+ }
+
+ /**
+ * Check if the portfile still contains my values, assuming that I am the server.
+ */
+ public synchronized boolean stillMyValues() throws IOException, FileNotFoundException {
+ for (;;) {
+ try {
+ lock();
+ getValues();
+ unlock();
+ if (containsPortInfo) {
+ if (serverPort == myServerPort &&
+ serverCookie == myServerCookie) {
+ // Everything is ok.
+ return true;
+ }
+ // Someone has overwritten the port file.
+ // Probably another javac server, lets quit.
+ return false;
+ }
+ // Something else is wrong with the portfile. Lets quit.
+ return false;
+ } catch (FileLockInterruptionException e) {
+ continue;
+ }
+ catch (ClosedChannelException e) {
+ // The channel has been closed since sjavac is exiting.
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Return the name of the port file.
+ */
+ public String getFilename() {
+ return filename;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/SysInfo.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * A utility class used to report information about the system
+ * where the javac server is running.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+package com.sun.tools.sjavac.server;
+
+public class SysInfo {
+ public int numCores;
+ public long maxMemory;
+
+ public SysInfo(int nc, long mm) {
+ numCores = nc;
+ maxMemory = mm;
+ }
+}
--- a/langtools/src/share/classes/javax/lang/model/element/Element.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/src/share/classes/javax/lang/model/element/Element.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -149,6 +149,56 @@
<A extends Annotation> A getAnnotation(Class<A> annotationType);
/**
+ * Returns an array of all of this element's annotation for the
+ * specified type if such annotations are present, else an empty
+ * array. The annotation may be either inherited or directly
+ * present on this element. This method will look through a container
+ * annotation (if present) if the supplied annotation type is
+ * repeatable.
+ *
+ * <p> The annotations returned by this method could contain an element
+ * whose value is of type {@code Class}.
+ * This value cannot be returned directly: information necessary to
+ * locate and load a class (such as the class loader to use) is
+ * not available, and the class might not be loadable at all.
+ * Attempting to read a {@code Class} object by invoking the relevant
+ * method on the returned annotation
+ * will result in a {@link MirroredTypeException},
+ * from which the corresponding {@link TypeMirror} may be extracted.
+ * Similarly, attempting to read a {@code Class[]}-valued element
+ * will result in a {@link MirroredTypesException}.
+ *
+ * <blockquote>
+ * <i>Note:</i> This method is unlike others in this and related
+ * interfaces. It operates on runtime reflective information —
+ * representations of annotation types currently loaded into the
+ * VM — rather than on the representations defined by and used
+ * throughout these interfaces. Consequently, calling methods on
+ * the returned annotation object can throw many of the exceptions
+ * that can be thrown when calling methods on an annotation object
+ * returned by core reflection. This method is intended for
+ * callers that are written to operate on a known, fixed set of
+ * annotation types.
+ * </blockquote>
+ *
+ * @param <A> the annotation type
+ * @param annotationType the {@code Class} object corresponding to
+ * the annotation type
+ * @return this element's annotations for the specified annotation
+ * type if present on this element, else an empty array
+ *
+ * @see #getAnnotationMirrors()
+ * @see #getAnnotation(java.lang.Class)
+ * @see java.lang.reflect.AnnotatedElement#getAnnotations
+ * @see EnumConstantNotPresentException
+ * @see AnnotationTypeMismatchException
+ * @see IncompleteAnnotationException
+ * @see MirroredTypeException
+ * @see MirroredTypesException
+ */
+ <A extends Annotation> A[] getAnnotations(Class<A> annotationType);
+
+ /**
* Returns the modifiers of this element, excluding annotations.
* Implicit modifiers, such as the {@code public} and {@code static}
* modifiers of interface members, are included.
--- a/langtools/test/com/sun/javadoc/5093723/T5093723.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/5093723/T5093723.java Sun Jan 20 23:39:11 2013 -0800
@@ -36,7 +36,7 @@
private static final String BUG_ID = "5093723";
private static final String[] ARGS = new String[] {
- "-d", BUG_ID + ".out", "-source", "5",
+ "-d", BUG_ID + ".out", "-source", "5", "-Xdoclint:none",
SRC_DIR + "/DocumentedClass.java",
SRC_DIR + "/UndocumentedClass.java"
};
--- a/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/DocRootSlash/DocRootSlash.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, 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
@@ -60,6 +60,7 @@
String srcdir = System.getProperty("test.src", ".");
runJavadoc(new String[] {"-d", TMPDIR_STRING1,
+ "-Xdoclint:none",
"-overview", (srcdir + FS + "overview.html"),
"-header", "<A HREF=\"{@docroot}/package-list\">{@docroot}</A> <A HREF=\"{@docRoot}/help-doc\">{@docRoot}</A>",
"-sourcepath", srcdir,
--- a/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testBadSourceFile/TestBadSourceFile.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -40,7 +40,7 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, SRC_DIR + FS + "C2.java"
+ "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C2.java"
};
//Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testHtmlDefinitionListTag/TestHtmlDefinitionListTag.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, 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
@@ -222,19 +222,19 @@
private static final String[] ARGS1 =
new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS2 =
new String[] {
- "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS3 =
new String[] {
- "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
private static final String[] ARGS4 =
new String[] {
- "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
+ "-Xdoclint:none", "-d", BUG_ID, "-nocomment", "-nodeprecated", "-sourcepath", SRC_DIR, "pkg1"};
/**
* The entry point of the test.
--- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -40,7 +40,7 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2"
+ "-Xdoclint:none", "-d", BUG_ID, "-use", "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", "pkg1", "pkg2"
};
//Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -32,6 +32,6 @@
* @author Bhavesh Patel
*/
@Documented
-@ContainedBy(ContainerSynthDoc.class)
+@Repeatable(ContainerSynthDoc.class)
public @interface ContaineeSynthDoc {
}
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -32,7 +32,6 @@
* @author Bhavesh Patel
*/
@Documented
-@ContainerFor(ContaineeSynthDoc.class)
public @interface ContainerSynthDoc {
ContaineeSynthDoc[] value();
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -32,6 +32,6 @@
* @author Bhavesh Patel
*/
@Documented
-@ContainedBy(ContainerSynthNotDoc.class)
+@Repeatable(ContainerSynthNotDoc.class)
public @interface ContaineeSynthDoc {
}
--- a/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -31,7 +31,6 @@
*
* @author Bhavesh Patel
*/
-@ContainerFor(ContaineeSynthDoc.class)
public @interface ContainerSynthNotDoc {
ContaineeSynthDoc[] value();
--- a/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testReturnTag/TestReturnTag.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -39,7 +39,7 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java"
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, SRC_DIR + FS + "TestReturnTag.java"
};
//Input for string search tests.
--- a/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testTagInheritence/TestTagInheritence.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
private static final String BUG_ID = "4496223-4496270-4618686-4720974-4812240-6253614-6253604";
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
};
/**
--- a/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, 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
@@ -42,7 +42,7 @@
};
private static final String[][] NEGATED_TEST = NO_TEST;
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java"
+ "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "TestTagMisuse.java"
};
/**
--- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -41,6 +41,7 @@
//Javadoc arguments.
private static final String[] ARGS =
new String[] {
+ "-Xdoclint:none",
"-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag",
"todo", "pkg1", "pkg2"
};
--- a/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testWarnBadParamNames/TestWarnBadParamNames.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, 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
@@ -43,7 +43,7 @@
};
private static final String[][] NEGATED_TEST = NO_TEST;
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, SRC_DIR + FS + "C.java"
+ "-Xdoclint:none", "-d", BUG_ID, SRC_DIR + FS + "C.java"
};
/**
--- a/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testWarnings/TestWarnings.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, 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
@@ -43,11 +43,11 @@
//Javadoc arguments.
private static final String[] ARGS = new String[] {
- "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
+ "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
};
private static final String[] ARGS2 = new String[] {
- "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg"
+ "-Xdoclint:none", "-d", BUG_ID, "-private", "-sourcepath", SRC_DIR, "pkg"
};
//Input for string search tests.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AnchorTest.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,93 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8004832
+ * @summary Add new doclint package
+ * @build DocLintTester
+ * @run main DocLintTester -ref AnchorTest.out AnchorTest.java
+ */
+
+/** */
+public class AnchorTest {
+ // tests for <a name=value>
+
+ /**
+ * <a name=foo></a>
+ */
+ public void a_name_foo() { }
+
+ /**
+ * <a name=foo></a>
+ */
+ public void a_name_already_defined() { }
+
+ /**
+ * <a name=></a>
+ */
+ public void a_name_empty() { }
+
+ /**
+ * <a name=123 ></a>
+ */
+ public void a_name_invalid() { }
+
+ /**
+ * <a name ></a>
+ */
+ public void a_name_missing() { }
+
+ // tests for <a id=value>
+
+ /**
+ * <a id=a_id_foo></a>
+ */
+ public void a_id_foo() { }
+
+ /**
+ * <a id=foo></a>
+ */
+ public void a_id_already_defined() { }
+
+ /**
+ * <a id=></a>
+ */
+ public void a_id_empty() { }
+
+ /**
+ * <a id=123 ></a>
+ */
+ public void a_id_invalid() { }
+
+ /**
+ * <a id ></a>
+ */
+ public void a_id_missing() { }
+
+ // tests for id=value on non-<a> tags
+
+ /**
+ * <p id=p_id_foo>text</p>
+ */
+ public void p_id_foo() { }
+
+ /**
+ * <p id=foo>text</p>
+ */
+ public void p_id_already_defined() { }
+
+ /**
+ * <p id=>text</p>
+ */
+ public void p_id_empty() { }
+
+ /**
+ * <p id=123 >text</p>
+ */
+ public void p_id_invalid() { }
+
+ /**
+ * <p id >text</p>
+ */
+ public void p_id_missing() { }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/AnchorTest.out Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,37 @@
+AnchorTest.java:19: error: anchor already defined: foo
+ * <a name=foo></a>
+ ^
+AnchorTest.java:24: error: invalid name for anchor: ""
+ * <a name=></a>
+ ^
+AnchorTest.java:29: error: invalid name for anchor: "123"
+ * <a name=123 ></a>
+ ^
+AnchorTest.java:34: error: no value given for anchor
+ * <a name ></a>
+ ^
+AnchorTest.java:46: error: anchor already defined: foo
+ * <a id=foo></a>
+ ^
+AnchorTest.java:51: error: invalid name for anchor: ""
+ * <a id=></a>
+ ^
+AnchorTest.java:56: error: invalid name for anchor: "123"
+ * <a id=123 ></a>
+ ^
+AnchorTest.java:61: error: no value given for anchor
+ * <a id ></a>
+ ^
+AnchorTest.java:73: error: anchor already defined: foo
+ * <p id=foo>text</p>
+ ^
+AnchorTest.java:78: error: invalid name for anchor: ""
+ * <p id=>text</p>
+ ^
+AnchorTest.java:83: error: invalid name for anchor: "123"
+ * <p id=123 >text</p>
+ ^
+AnchorTest.java:88: error: no value given for anchor
+ * <p id >text</p>
+ ^
+12 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndTagsTest.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006236
+ * @summary doclint: structural issue hidden
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html EndTagsTest.java
+ * @run main DocLintTester -ref EndTagsTest.out EndTagsTest.java
+ */
+
+/** */
+public class EndTagsTest {
+ /** <p> <a name="a1"> text <img alt="image" src="image.png"> </a> </p> */
+ public void valid_all() { }
+
+ /** <p> <a name="a2"> text <img alt="image" src="image.png"> </a> */
+ public void valid_omit_optional_close() { }
+
+ /** </a> */
+ public void invalid_missing_start() { }
+
+ /** <p> </a> */
+ public void invalid_missing_start_2() { }
+
+ /** <p> text </p> </a> */
+ public void invalid_missing_start_3() { }
+
+ /** <img alt="image" src="image.png"> </img> */
+ public void invalid_end() { }
+
+ /** <invalid> </invalid> */
+ public void unknown_start_end() { }
+
+ /** <invalid> */
+ public void unknown_start() { }
+
+ /** </invalid> */
+ public void unknown_end() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/EndTagsTest.out Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,25 @@
+EndTagsTest.java:18: error: unexpected end tag: </a>
+ /** </a> */
+ ^
+EndTagsTest.java:21: error: unexpected end tag: </a>
+ /** <p> </a> */
+ ^
+EndTagsTest.java:24: error: unexpected end tag: </a>
+ /** <p> text </p> </a> */
+ ^
+EndTagsTest.java:27: error: invalid end tag: </img>
+ /** <img alt="image" src="image.png"> </img> */
+ ^
+EndTagsTest.java:30: error: unknown tag: invalid
+ /** <invalid> </invalid> */
+ ^
+EndTagsTest.java:30: error: unknown tag: invalid
+ /** <invalid> </invalid> */
+ ^
+EndTagsTest.java:33: error: unknown tag: invalid
+ /** <invalid> */
+ ^
+EndTagsTest.java:36: error: unknown tag: invalid
+ /** </invalid> */
+ ^
+8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/LiteralTest.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8006228
+ * @summary Doclint doesn't detect <code> {@code nested inline} </code>
+ * @build DocLintTester
+ * @run main DocLintTester -ref LiteralTest.out LiteralTest.java
+ */
+
+/** */
+public class LiteralTest {
+ /** <code> abc {@literal < & > } def </code> */
+ public void ok_literal_in_code() { }
+
+ /** <code> abc {@code < & > } def </code> */
+ public void bad_code_in_code() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/doclint/LiteralTest.out Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,4 @@
+LiteralTest.java:14: warning: {@code} within <code>
+ /** <code> abc {@code < & > } def </code> */
+ ^
+1 warning
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,11 +6,9 @@
* @compile/fail/ref=BaseAnnoAsContainerAnno.out -XDrawDiagnostics BaseAnnoAsContainerAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(Foo.class)
-@ContainerFor(Foo.class)
+@Repeatable(Foo.class)
@interface Foo {
Foo[] value() default {};
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BaseAnnoAsContainerAnno.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-BaseAnnoAsContainerAnno.java:15:11: compiler.err.cyclic.annotation.element
+BaseAnnoAsContainerAnno.java:13:11: compiler.err.cyclic.annotation.element
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,9 @@
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Foos {
Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -32,32 +32,29 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@Target(ElementType.TYPE)
@interface Foo {}
-@ContainerFor(Foo.class)
@Target(ElementType.ANNOTATION_TYPE)
@interface Foos {
Foo[] value();
}
-@ContainedBy(Bars.class)
+@Repeatable(Bars.class)
@Target(ElementType.TYPE)
@interface Bar {}
-@ContainerFor(Bar.class)
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
@interface Bars {
Bar[] value();
}
-@ContainedBy(Bazs.class)
+@Repeatable(Bazs.class)
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@interface Baz {}
-@ContainerFor(Baz.class)
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
@interface Bazs {
Baz[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ClassReaderDefault.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -30,17 +30,15 @@
* @compile ClassReaderDefault.java
* @compile SeparateCompile.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
public class ClassReaderDefault {
}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
int f() default 0;
}
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -30,15 +30,13 @@
* @run compile ContainerHasRepeatedContained.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
@interface Bar {}
@Bar
@Bar
-@ContainerFor(Bar.class)
@interface BarContainer {
Bar[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,17 +6,14 @@
* @compile/fail/ref=CyclicAnnotation.out -XDrawDiagnostics CyclicAnnotation.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(Foo.class)
-@ContainerFor(Baz.class)
+@Repeatable(Foo.class)
@interface Baz {
Foo[] value() default {};
}
-@ContainedBy(Baz.class)
-@ContainerFor(Foo.class)
+@Repeatable(Baz.class)
@interface Foo{
Baz[] value() default {};
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CyclicAnnotation.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,6 +1,2 @@
-CyclicAnnotation.java:12:1: compiler.err.invalid.container.wrong.containerfor: Foo, Baz
-CyclicAnnotation.java:13:1: compiler.err.invalid.container.wrong.containedby: Foo, Baz
-CyclicAnnotation.java:15:11: compiler.err.cyclic.annotation.element
-CyclicAnnotation.java:18:1: compiler.err.invalid.container.wrong.containerfor: Baz, Foo
-CyclicAnnotation.java:19:1: compiler.err.invalid.container.wrong.containedby: Baz, Foo
-5 errors
+CyclicAnnotation.java:13:11: compiler.err.cyclic.annotation.element
+1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultCasePresent.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,13 +29,11 @@
* @compile DefaultCasePresent.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
String other() default "other-method";
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -39,12 +39,11 @@
@Bar("katt")
@Bar("lol")
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
@interface Bar {
String value();
}
-@ContainerFor(Bar.class)
@interface BarContainer {
Bar[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,15 +6,13 @@
* @compile/fail/ref=DocumentedContainerAnno.out -XDrawDiagnostics DocumentedContainerAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
import java.lang.annotation.Documented;
@Documented
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DocumentedContainerAnno.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-DocumentedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.documented: FooContainer, Foo
+DocumentedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.documented: FooContainer, Foo
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,15 +6,13 @@
* @compile/fail/ref=InheritedContainerAnno.out -XDrawDiagnostics InheritedContainerAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
import java.lang.annotation.Inherited;
@Inherited
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InheritedContainerAnno.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-InheritedContainerAnno.java:14:1: compiler.err.invalid.containedby.annotation.not.inherited: FooContainer, Foo
+InheritedContainerAnno.java:13:1: compiler.err.invalid.repeatable.annotation.not.inherited: FooContainer, Foo
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -32,11 +32,10 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@Target(ElementType.ANNOTATION_TYPE)
@interface Foo {}
-@ContainerFor(Foo.class)
@Target(ElementType.TYPE)
@interface Foos {
Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @summary Smoke test for repeating annotations
- * @compile/fail MissingContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-
-@ContainerFor(MissingContainedBy.class)
-@interface Foos {
- MissingContainedBy[] value();
-}
-
-public @interface MissingContainedBy {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingContainer.out -XDrawDiagnostics MissingContainer.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy()
+@Repeatable()
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainer.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,4 @@
-MissingContainer.java:20:1: compiler.err.invalid.containedby.annotation: Foo
-MissingContainer.java:20:6: compiler.err.invalid.containedby.annotation: Foo
-MissingContainer.java:12:1: compiler.err.annotation.missing.default.value: java.lang.annotation.ContainedBy, value
-MissingContainer.java:15:1: compiler.err.invalid.container.wrong.containedby: Foo, FooContainer
-4 errors
+MissingContainer.java:18:1: compiler.err.invalid.repeatable.annotation: Foo
+MissingContainer.java:18:6: compiler.err.invalid.repeatable.annotation: Foo
+MissingContainer.java:11:1: compiler.err.annotation.missing.default.value: java.lang.annotation.Repeatable, value
+3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @summary Smoke test for repeating annotations
- * @compile/fail MissingContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@interface Foos {
- MissingContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface MissingContainerFor {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingDefaultCase1.out -XDrawDiagnostics MissingDefaultCase1.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
String other(); // missing default clause
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase1.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-MissingDefaultCase1.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
-MissingDefaultCase1.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other()
+MissingDefaultCase1.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
+MissingDefaultCase1.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other()
2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingDefaultCase2.out -XDrawDiagnostics MissingDefaultCase2.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
Foo other(); // missing default clause and return type is an annotation
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingDefaultCase2.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-MissingDefaultCase2.java:21:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
-MissingDefaultCase2.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, other()
+MissingDefaultCase2.java:19:1: compiler.err.duplicate.annotation.invalid.repeated: Foo
+MissingDefaultCase2.java:11:1: compiler.err.invalid.repeatable.annotation.elem.nondefault: FooContainer, other()
2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,13 +6,11 @@
* @compile/fail/ref=MissingValueMethod.out -XDrawDiagnostics MissingValueMethod.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo[] values(); // wrong method name
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingValueMethod.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,4 +1,4 @@
-MissingValueMethod.java:20:1: compiler.err.invalid.containedby.annotation.no.value: FooContainer
-MissingValueMethod.java:20:6: compiler.err.invalid.containedby.annotation.no.value: FooContainer
-MissingValueMethod.java:12:1: compiler.err.invalid.containedby.annotation.elem.nondefault: FooContainer, values()
+MissingValueMethod.java:18:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
+MissingValueMethod.java:18:6: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
+MissingValueMethod.java:11:1: compiler.err.invalid.repeatable.annotation.no.value: FooContainer
3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultiLevelRepeatableAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,19 +29,16 @@
* @compile MultiLevelRepeatableAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {}
-@ContainedBy(FooContainerContainer.class)
-@ContainerFor(Foo.class)
+@Repeatable(FooContainerContainer.class)
@interface FooContainer {
Foo[] value();
}
-@ContainerFor(FooContainer.class)
@interface FooContainerContainer {
FooContainer[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MultipleAnnoMixedOrder.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,25 +29,22 @@
* @compile MultipleAnnoMixedOrder.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {
int getNumbers();
}
-@ContainerFor(Foo.class)
@interface FooContainer {
Foo[] value();
}
-@ContainedBy(BazContainer.class)
+@Repeatable(BazContainer.class)
@interface Baz {
String getStr();
}
-@ContainerFor(Baz.class)
@interface BazContainer {
Baz[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,17 +34,15 @@
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(FoosFoos.class)
-@ContainerFor(Foo.class)
+@Repeatable(FoosFoos.class)
@interface Foos {
Foo[] value();
}
-@ContainerFor(Foos.class)
@Retention(RetentionPolicy.RUNTIME)
@interface FoosFoos {
Foos[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NoRepeatableAnno.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy
-NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.ContainedBy
+NoRepeatableAnno.java:11:1: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable
+NoRepeatableAnno.java:11:6: compiler.err.duplicate.annotation.missing.container: Foo, java.lang.annotation.Repeatable
2 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -30,20 +30,18 @@
* @run compile RepMemberAnno.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
public class RepMemberAnno {
@Bar("Apa") @Bar("Banan")
public void meh() {}
}
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
@interface Bar {
String value();
}
-@ContainerFor(Bar.class)
@interface BarContainer {
Bar[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,21 +34,19 @@
@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(BarContainer.class)
+@Repeatable(BarContainer.class)
public @interface RepSelfMemberAnno {
@RepSelfMemberAnno @RepSelfMemberAnno
String meh() default "banan";
}
-@ContainedBy(BarContainerContainer.class)
+@Repeatable(BarContainerContainer.class)
@Retention(RetentionPolicy.RUNTIME)
-@ContainerFor(RepSelfMemberAnno.class)
@interface BarContainer {
RepSelfMemberAnno[] value();
}
-@ContainerFor(BarContainer.class)
@Retention(RetentionPolicy.RUNTIME)
@interface BarContainerContainer {
BarContainer[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -30,7 +30,7 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
@interface Foos {
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -31,10 +31,9 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@Target(ElementType.ANNOTATION_TYPE)
@interface Foos {
Foo[] value();
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingTargetNotAllowed.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-RepeatingTargetNotAllowed.java:44:5: compiler.err.invalid.containedby.annotation.incompatible.target: Foos, Foo
+RepeatingTargetNotAllowed.java:43:5: compiler.err.invalid.repeatable.annotation.incompatible.target: Foos, Foo
1 error
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -33,7 +33,6 @@
import java.lang.annotation.*;
-@ContainerFor(SelfRepeatingAnno.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Foos {
SelfRepeatingAnno[] value();
@@ -42,7 +41,7 @@
@SelfRepeatingAnno
@Retention(RetentionPolicy.RUNTIME)
@SelfRepeatingAnno
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface SelfRepeatingAnno {}
public class SelfRepeatingAnnotations {
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -30,10 +30,9 @@
import java.lang.annotation.*;
-@ContainedBy(Foos.class)
+@Repeatable(Foos.class)
@interface Foo {}
-@ContainerFor(Foo.class)
@interface Foos {
Foo[] value();
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @summary Smoke test for repeating annotations
- * @compile/fail UseWrongContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(UseWrongContainedBy.class)
-@interface Foos {
- UseWrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface UseWrongContainedBy {}
-
-@UseWrongContainedBy @UseWrongContainedBy
-@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @summary Smoke test for repeating annotations
- * @compile/fail UseWrongContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
- UseWrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface UseWrongContainerFor {}
-
-@UseWrongContainerFor @UseWrongContainerFor
-@interface Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongRepeatable.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2013, 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
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongRepeatable.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@interface Foos {
+ UseWrongRepeatable[] value();
+}
+
+@Repeatable(Target.class)
+public @interface UseWrongRepeatable {}
+
+@UseWrongRepeatable @UseWrongRepeatable
+@interface Foo {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @summary Smoke test for repeating annotations
- * @compile/fail WrongContainedBy.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(WrongContainedBy.class)
-@interface Foos {
- WrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface WrongContainedBy {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, 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
- * @summary Smoke test for repeating annotations
- * @compile/fail WrongContainerFor.java
- * @bug 7151010
- */
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
- WrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.java Sun Jan 20 23:39:11 2013 -0800
@@ -6,15 +6,13 @@
* @compile/fail/ref=WrongReturnTypeForValue.out -XDrawDiagnostics WrongReturnTypeForValue.java
*/
-import java.lang.annotation.ContainedBy;
-import java.lang.annotation.ContainerFor;
+import java.lang.annotation.Repeatable;
-@ContainedBy(FooContainer.class)
+@Repeatable(FooContainer.class)
@interface Foo {
int getNumbers();
}
-@ContainerFor(Foo.class)
@interface FooContainer{
Foo value(); // wrong return type
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongReturnTypeForValue.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,4 @@
-WrongReturnTypeForValue.java:22:1: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[]
-WrongReturnTypeForValue.java:22:6: compiler.err.invalid.containedby.annotation.value.return: FooContainer, Foo, Foo[]
-2 errors
+WrongReturnTypeForValue.java:20:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+WrongReturnTypeForValue.java:20:6: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+WrongReturnTypeForValue.java:11:1: compiler.err.invalid.repeatable.annotation.value.return: FooContainer, Foo, Foo[]
+3 errors
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -163,9 +163,8 @@
String replaceStr = "/*"+type+"*/";
StringBuilder annoData = new StringBuilder();
annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
JavaFileObject pkgInfoFile = null;
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -115,24 +115,21 @@
switch(className) {
case "DeprecatedonBoth":
annoData.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DeprecatedonBase":
- annoData.append(Helper.ContentVars.CONTAINERFOR.getVal())
- .append(Helper.ContentVars.CONTAINER.getVal())
+ annoData.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DeprecatedonContainer":
annoData.append(Helper.ContentVars.DEPRECATED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -93,17 +93,15 @@
switch(className) {
case "DocumentedonBothAnno":
annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DOCUMENTED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DocumentedonContainer":
annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,15 +34,13 @@
public class Helper {
enum ContentVars {
- IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.ContainedBy;\n" +
- "\nimport java.lang.annotation.ContainerFor;\n"),
+ IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.Repeatable;\n"),
IMPORTDEPRECATED("import java.lang.Deprecated;\n"),
IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"),
IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
IMPORTRETENTION("import java.lang.annotation.Retention;\n" +
"\nimport java.lang.annotation.RetentionPolicy;\n"),
- CONTAINEDBY("\n@ContainedBy(FooContainer.class)\n"),
- CONTAINERFOR("@ContainerFor(Foo.class)\n"),
+ REPEATABLE("\n@Repeatable(FooContainer.class)\n"),
CONTAINER("@interface FooContainer {\n" +" Foo[] value();\n}\n"),
BASE("@interface Foo {}\n"),
REPEATABLEANNO("\n@Foo() @Foo()"),
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -94,17 +94,15 @@
switch(className) {
case "InheritedonBothAnno":
annoData.append(Helper.ContentVars.INHERITED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.INHERITED.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "InheritedonBase":
annoData.append(Helper.ContentVars.INHERITED.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
--- a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -120,7 +120,7 @@
new DiagnosticCollector<JavaFileObject>();
boolean ok = compileCode(className, contents, diagnostics);
- String expectedErrKey = "compiler.err.invalid.containedby" +
+ String expectedErrKey = "compiler.err.invalid.repeatable" +
".annotation.retention";
if (!shouldCompile && !ok) {
for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
@@ -175,10 +175,9 @@
StringBuilder annoData = new StringBuilder();
annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
.append(Helper.ContentVars.IMPORTRETENTION.getVal())
- .append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(replacedRetCAVal)
.append(Helper.ContentVars.CONTAINER.getVal())
- .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.REPEATABLE.getVal())
.append(replacedRetBaseVal)
.append(Helper.ContentVars.BASE.getVal());
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Sun Jan 20 23:39:11 2013 -0800
@@ -1,13 +1,14 @@
compiler.err.already.annotated # internal compiler error?
compiler.err.already.defined.this.unit # seems to be masked by compiler.err.duplicate.class
compiler.err.annotation.value.not.allowable.type # cannot happen: precluded by complete type-specific tests
+compiler.err.bad.functional.intf.anno # seems to be masked by compiler.err.annotation.type.not.applicable
compiler.err.cant.read.file # (apt.JavaCompiler?)
compiler.err.cant.select.static.class.from.param.type
compiler.err.dc.unterminated.string # cannot happen
compiler.err.illegal.char.for.encoding
-compiler.err.invalid.containedby.annotation # should not happen
-compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen
-compiler.err.invalid.containedby.annotation.multiple.values # can't happen
+compiler.err.invalid.repeatable.annotation # should not happen
+compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen
+compiler.err.invalid.repeatable.annotation.multiple.values # can't happen
compiler.err.io.exception # (javah.JavahTask?)
compiler.err.limit.code # Code
compiler.err.limit.code.too.large.for.try.stmt # Gen
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadFunctionalIntfAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.bad.functional.intf.anno.1
+// key: compiler.misc.not.a.functional.intf
+
+@FunctionalInterface
+class BadFunctionalIntfAnno { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.not.documented
-
-import java.lang.annotation.*;
-
-@Documented
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByDocumentedMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.not.inherited
-
-import java.lang.annotation.*;
-
-@Inherited
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByInheritedMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.no.value
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos {}
-
-@Anno
-@Anno
-class ContainedByNoValue { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.elem.nondefault
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); String foo(); }
-
-class ContainedByNonDefault { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.retention
-
-import java.lang.annotation.*;
-
-@Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-@Anno
-@Anno
-class ContainedByRetentionMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.incompatible.target
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@Target(ElementType.METHOD)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { Anno[] value(); }
-
-class ContainedByTargetMismatch { }
--- a/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.containedby.annotation.value.return
-
-import java.lang.annotation.*;
-
-@ContainedBy(Annos.class)
-@interface Anno { }
-
-@ContainerFor(Anno.class)
-@interface Annos { String value(); }
-
-@Anno
-@Anno
-class ContainedByWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/InvalidDuplicateAnnotation.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -22,17 +22,16 @@
*/
// key: compiler.err.duplicate.annotation.invalid.repeated
-// key: compiler.err.invalid.containedby.annotation.elem.nondefault
-//
+// key: compiler.err.invalid.repeatable.annotation.elem.nondefault
+
// We need an almost valid containing annotation. The easiest way to get
// one close enough to valid is by forgetting a default.
import java.lang.annotation.*;
-@ContainedBy(Annos.class)
+@Repeatable(Annos.class)
@interface Anno { }
-@ContainerFor(Anno.class)
@interface Annos { Anno[] value(); String foo(); }
@Anno
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableDocumentedMismatch.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.not.documented
+
+import java.lang.annotation.*;
+
+@Documented
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableDocumentedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableInheritedMismatch.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.not.inherited
+
+import java.lang.annotation.*;
+
+@Inherited
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableInheritedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableNoValue.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.no.value
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos {}
+
+@Anno
+@Anno
+class RepeatableNoValue { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableNonDefault.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.elem.nondefault
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); String foo(); }
+
+class RepeatableNonDefault { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableRetentionMismatch.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.retention
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class RepeatableRetentionMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableTargetMismatch.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.incompatible.target
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@Target(ElementType.METHOD)
+@interface Anno { }
+
+@interface Annos { Anno[] value(); }
+
+class RepeatableTargetMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatableWrongValueType.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.repeatable.annotation.value.return
+
+import java.lang.annotation.*;
+
+@Repeatable(Annos.class)
+@interface Anno { }
+
+@interface Annos { String value(); }
+
+@Anno
+@Anno
+class RepeatableWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,14 +21,13 @@
* questions.
*/
-// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present
+// key: compiler.err.invalid.repeatable.annotation.repeated.and.container.present
import java.lang.annotation.*;
-@ContainedBy(Annos.class)
+@Repeatable(Annos.class)
@interface Anno { }
-@ContainerFor(Anno.class)
@interface Annos { Anno[] value(); }
@Anno
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnderscoreAsIdentifier.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.underscore.as.identifier
+
+class UnderscoreAsIdentifier {
+ String _ = null;
+}
--- a/langtools/test/tools/javac/diags/examples/WrongContainedBy.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.container.no.containerfor
-// key: compiler.err.invalid.container.wrong.containedby
-
-import java.lang.annotation.*;
-
-@ContainerFor(WrongContainedBy.class)
-@interface Foos {
- WrongContainedBy[] value();
-}
-
-@ContainedBy(Target.class)
-public @interface WrongContainedBy {}
--- a/langtools/test/tools/javac/diags/examples/WrongContainerFor.java Wed Jul 05 18:37:13 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.container.wrong.containerfor
-// key: compiler.err.invalid.container.no.containedby
-
-import java.lang.annotation.*;
-
-@ContainerFor(Retention.class)
-@interface Foos {
- WrongContainerFor[] value();
-}
-
-@ContainedBy(Foos.class)
-public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/lambda/BadConv03.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/BadConv03.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B))
+BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: BadConv03.B, (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B))
1 error
--- a/langtools/test/tools/javac/lambda/BadLambdaPos.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/BadLambdaPos.out Sun Jan 20 23:39:11 2013 -0800
@@ -4,6 +4,6 @@
BadLambdaPos.java:23:18: compiler.err.unexpected.lambda
BadLambdaPos.java:23:34: compiler.err.unexpected.lambda
BadLambdaPos.java:24:21: compiler.err.unexpected.lambda
-BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
8 errors
--- a/langtools/test/tools/javac/lambda/BadTargetType.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/BadTargetType.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
-BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
-BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
+BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary smoke test for functional interface annotation
+ * @compile/fail/ref=FunctionalInterfaceAnno.out -XDrawDiagnostics FunctionalInterfaceAnno.java
+ */
+class FunctionalInterfaceAnno {
+ @FunctionalInterface
+ static class A { } //not an interface
+
+ @FunctionalInterface
+ static abstract class B { } //not an interface
+
+ @FunctionalInterface
+ enum C { } //not an interface
+
+ @FunctionalInterface
+ @interface D { } //not an interface
+
+ @FunctionalInterface
+ interface E { } //no abstracts
+
+ @FunctionalInterface
+ interface F { default void m() { } } //no abstracts
+
+ @FunctionalInterface
+ interface G { String toString(); } //no abstracts
+
+ @FunctionalInterface
+ interface H { void m(); void n(); } //incompatible abstracts
+
+ @FunctionalInterface
+ interface I { void m(); } //ok
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceAnno.out Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,9 @@
+FunctionalInterfaceAnno.java:7:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.A)
+FunctionalInterfaceAnno.java:10:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.B)
+FunctionalInterfaceAnno.java:13:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.C)
+FunctionalInterfaceAnno.java:16:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf: FunctionalInterfaceAnno.D)
+FunctionalInterfaceAnno.java:19:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.E, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.E))
+FunctionalInterfaceAnno.java:22:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.F, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.F))
+FunctionalInterfaceAnno.java:25:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.G, (compiler.misc.no.abstracts: kindname.interface, FunctionalInterfaceAnno.G))
+FunctionalInterfaceAnno.java:28:5: compiler.err.bad.functional.intf.anno.1: (compiler.misc.not.a.functional.intf.1: FunctionalInterfaceAnno.H, (compiler.misc.incompatible.abstracts: kindname.interface, FunctionalInterfaceAnno.H))
+8 errors
--- a/langtools/test/tools/javac/lambda/Intersection01.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/Intersection01.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,3 +1,3 @@
-Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
-Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
2 errors
--- a/langtools/test/tools/javac/lambda/LambdaConv09.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/LambdaConv09.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
-LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1))
-LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2))
-LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3))
-LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5))
+LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo1, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1))
+LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo2, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2))
+LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo3, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3))
+LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: LambdaConv09.Foo5, (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5))
4 errors
--- a/langtools/test/tools/javac/lambda/LambdaExpr10.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/LambdaExpr10.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,9 +1,9 @@
-LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
+LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
LambdaExpr10.java:33:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
LambdaExpr10.java:34:49: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
8 errors
--- a/langtools/test/tools/javac/lambda/LambdaParserTest.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/LambdaParserTest.java Sun Jan 20 23:39:11 2013 -0800
@@ -23,8 +23,7 @@
/*
* @test
- * @bug 7115050
- * @bug 8003280
+ * @bug 7115050 8003280 8005852
* @summary Add lambda tests
* Add parser support for lambda expressions
* @library ../lib
@@ -46,12 +45,12 @@
enum LambdaKind {
NILARY_EXPR("()->x"),
NILARY_STMT("()->{ return x; }"),
- ONEARY_SHORT_EXPR("x->x"),
- ONEARY_SHORT_STMT("x->{ return x; }"),
- ONEARY_EXPR("(#M1 #T1 x)->x"),
- ONEARY_STMT("(#M1 #T1 x)->{ return x; }"),
- TWOARY_EXPR("(#M1 #T1 x, #M2 #T2 y)->x"),
- TWOARY_STMT("(#M1 #T1 x, #M2 #T2 y)->{ return x; }");
+ ONEARY_SHORT_EXPR("#PN->x"),
+ ONEARY_SHORT_STMT("#PN->{ return x; }"),
+ ONEARY_EXPR("(#M1 #T1 #PN)->x"),
+ ONEARY_STMT("(#M1 #T1 #PN)->{ return x; }"),
+ TWOARY_EXPR("(#M1 #T1 #PN, #M2 #T2 y)->x"),
+ TWOARY_STMT("(#M1 #T1 #PN, #M2 #T2 y)->{ return x; }");
String lambdaTemplate;
@@ -60,11 +59,12 @@
}
String getLambdaString(LambdaParameterKind pk1, LambdaParameterKind pk2,
- ModifierKind mk1, ModifierKind mk2) {
+ ModifierKind mk1, ModifierKind mk2, LambdaParameterName pn) {
return lambdaTemplate.replaceAll("#M1", mk1.modifier)
.replaceAll("#M2", mk2.modifier)
.replaceAll("#T1", pk1.parameterType)
- .replaceAll("#T2", pk2.parameterType);
+ .replaceAll("#T2", pk2.parameterType)
+ .replaceAll("#PN", pn.nameStr);
}
int arity() {
@@ -87,6 +87,17 @@
}
}
+ enum LambdaParameterName {
+ IDENT("x"),
+ UNDERSCORE("_");
+
+ String nameStr;
+
+ LambdaParameterName(String nameStr) {
+ this.nameStr = nameStr;
+ }
+ }
+
enum LambdaParameterKind {
IMPLICIT(""),
EXPLIICT_SIMPLE("A"),
@@ -151,8 +162,8 @@
}
String expressionString(LambdaParameterKind pk1, LambdaParameterKind pk2,
- ModifierKind mk1, ModifierKind mk2, LambdaKind lk, SubExprKind sk) {
- return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2))
+ ModifierKind mk1, ModifierKind mk2, LambdaKind lk, LambdaParameterName pn, SubExprKind sk) {
+ return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2, pn))
.replaceAll("#S", sk.subExpression);
}
}
@@ -174,25 +185,27 @@
public static void main(String... args) throws Exception {
for (LambdaKind lk : LambdaKind.values()) {
- for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
- if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
- continue;
- for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
- if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
+ for (LambdaParameterName pn : LambdaParameterName.values()) {
+ for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
+ if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
continue;
- for (ModifierKind mk1 : ModifierKind.values()) {
- if (mk1 != ModifierKind.NONE && lk.isShort())
+ for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
+ if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
continue;
- if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
- continue;
- for (ModifierKind mk2 : ModifierKind.values()) {
- if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
+ for (ModifierKind mk1 : ModifierKind.values()) {
+ if (mk1 != ModifierKind.NONE && lk.isShort())
+ continue;
+ if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
continue;
- for (SubExprKind sk : SubExprKind.values()) {
- for (ExprKind ek : ExprKind.values()) {
- pool.execute(
- new LambdaParserTest(pk1, pk2, mk1,
- mk2, lk, sk, ek));
+ for (ModifierKind mk2 : ModifierKind.values()) {
+ if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
+ continue;
+ for (SubExprKind sk : SubExprKind.values()) {
+ for (ExprKind ek : ExprKind.values()) {
+ pool.execute(
+ new LambdaParserTest(pk1, pk2, mk1,
+ mk2, lk, sk, ek, pn));
+ }
}
}
}
@@ -209,6 +222,7 @@
ModifierKind mk1;
ModifierKind mk2;
LambdaKind lk;
+ LambdaParameterName pn;
SubExprKind sk;
ExprKind ek;
JavaSource source;
@@ -216,12 +230,13 @@
LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2,
ModifierKind mk1, ModifierKind mk2, LambdaKind lk,
- SubExprKind sk, ExprKind ek) {
+ SubExprKind sk, ExprKind ek, LambdaParameterName pn) {
this.pk1 = pk1;
this.pk2 = pk2;
this.mk1 = mk1;
this.mk2 = mk2;
this.lk = lk;
+ this.pn = pn;
this.sk = sk;
this.ek = ek;
this.source = new JavaSource();
@@ -239,7 +254,7 @@
public JavaSource() {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
source = template.replaceAll("#E",
- ek.expressionString(pk1, pk2, mk1, mk2, lk, sk));
+ ek.expressionString(pk1, pk2, mk1, mk2, lk, pn, sk));
}
@Override
@@ -272,6 +287,9 @@
errorExpected = true;
}
+ errorExpected |= pn == LambdaParameterName.UNDERSCORE &&
+ lk.arity() > 0;
+
if (errorExpected != diagChecker.errorFound) {
throw new Error("invalid diagnostics for source:\n" +
source.getCharContent(true) +
--- a/langtools/test/tools/javac/lambda/MethodReference04.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/MethodReference04.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference59.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 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 8004102
+ * @summary Add support for array constructor references
+ */
+public class MethodReference59 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface ArrayFactory<X> {
+ X make(int size);
+ }
+
+ public static void main(String[] args) {
+ ArrayFactory<int[]> factory1 = int[]::new;
+ int[] i1 = factory1.make(5);
+ assertTrue(i1.length == 5);
+ ArrayFactory<int[][]> factory2 = int[][]::new;
+ int[][] i2 = factory2.make(5);
+ assertTrue(i2.length == 5);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference60.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 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 8004102
+ * @summary Add support for array constructor references
+ * @compile/fail/ref=MethodReference60.out -XDrawDiagnostics MethodReference60.java
+ */
+public class MethodReference60 {
+
+ interface ArrayFactory<X> {
+ X make(int size);
+ }
+
+ interface BadArrayFactory1<X> {
+ X make();
+ }
+
+ interface BadArrayFactory2<X> {
+ X make(int i1, int i2);
+ }
+
+ interface BadArrayFactory3<X> {
+ X make(String s);
+ }
+
+ public static void main(String[] args) {
+ BadArrayFactory1<int[]> factory1 = int[]::new; //param mismatch
+ BadArrayFactory2<int[]> factory2 = int[]::new; //param mismatch
+ BadArrayFactory3<int[]> factory3 = int[]::new; //param mismatch
+ ArrayFactory<Integer> factory4 = int[]::new; //return type mismatch
+ ArrayFactory<Integer[]> factory5 = int[]::new; //return type mismatch
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference60.out Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,6 @@
+MethodReference60.java:49:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, compiler.misc.no.args, kindname.class, Array, (compiler.misc.arg.length.mismatch)))
+MethodReference60.java:50:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, int,int, kindname.class, Array, (compiler.misc.arg.length.mismatch)))
+MethodReference60.java:51:44: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Array, int, java.lang.String, kindname.class, Array, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, int))))
+MethodReference60.java:52:42: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer))
+MethodReference60.java:53:44: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], java.lang.Integer[]))
+5 errors
--- a/langtools/test/tools/javac/lambda/TargetType17.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/TargetType17.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,9 +1,9 @@
-TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
-TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: byte)
+TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: short)
+TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: int)
+TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: long)
+TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: float)
+TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: double)
+TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: char)
+TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: boolean)
8 errors
--- a/langtools/test/tools/javac/lambda/TargetType43.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/TargetType43.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
-TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
-TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/WarnUnderscoreAsIdent.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, 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
+ * @summary Check usages of underscore as identifier generate warnings
+ * @compile/fail/ref=WarnUnderscoreAsIdent.out -XDrawDiagnostics -Werror WarnUnderscoreAsIdent.java
+ */
+package _._;
+
+import _._;
+
+class _ {
+ String _ = null;
+ void _(String _) { }
+ void testLocal() {
+ String _ = null;
+ }
+ void testFor() {
+ for (int _ = 0; _ < 10; _++);
+ }
+ void testTry() {
+ try { } catch (Throwable _) { }
+ }
+ void testLabel() {
+ _:
+ for (;;) {
+ break _;
+ }
+ _:
+ for (;;) {
+ continue _;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/WarnUnderscoreAsIdent.out Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,20 @@
+WarnUnderscoreAsIdent.java:29:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:29:11: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:31:8: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:31:10: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:33:7: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:34:12: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:10: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:35:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:37:16: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:18: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:25: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:40:33: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:43:34: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:46:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:48:19: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:50:9: compiler.warn.underscore.as.identifier
+WarnUnderscoreAsIdent.java:52:22: compiler.warn.underscore.as.identifier
+- compiler.err.warnings.and.werror
+1 error
+17 warnings
--- a/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo)))
+LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: QooRoo, (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo)))
1 error
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, Planet))
+NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: Planet, (compiler.misc.no.abstracts: kindname.interface, Planet))
1 error
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,9 +1,9 @@
-NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
-NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
-NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
-NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: FooBar, (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: DE, (compiler.misc.incompatible.abstracts: kindname.interface, DE))
8 errors
--- a/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: AbstractClass_neg.SAM)
1 error
--- a/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out Sun Jan 20 23:39:11 2013 -0800
@@ -1,2 +1,2 @@
-InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
1 error
--- a/langtools/test/tools/javadoc/6958836/Test.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/6958836/Test.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, 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
@@ -61,6 +61,7 @@
// Force en_US locale in lieu of something like -XDrawDiagnostics.
// For some reason, this must be the first option when used.
opts.addAll(list("-locale", "en_US"));
+ opts.add("-Xdoclint:none");
opts.addAll(list("-classpath", System.getProperty("test.src")));
opts.addAll(list("-d", testOutDir.getPath()));
opts.addAll(testOpts);
--- a/langtools/test/tools/javadoc/6964914/Test.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/6964914/Test.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, 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
@@ -45,6 +45,7 @@
void javadoc(String path, String expect) {
File testSrc = new File(System.getProperty("test.src"));
String[] args = {
+ "-Xdoclint:none",
"-source", "1.4", // enables certain Parser warnings
"-bootclasspath", System.getProperty("sun.boot.class.path"),
"-classpath", ".",
--- a/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/6964914/TestStdDoclet.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -57,6 +57,7 @@
Process p = new ProcessBuilder()
.command(javadoc.getPath(),
"-J-Xbootclasspath:" + System.getProperty("sun.boot.class.path"),
+ "-Xdoclint:none",
"-package",
new File(testSrc, thisClassName + ".java").getPath())
.redirectErrorStream(true)
--- a/langtools/test/tools/javadoc/MaxWarns.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/MaxWarns.java Sun Jan 20 23:39:11 2013 -0800
@@ -74,7 +74,7 @@
String javadoc(File f) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
- String[] args = { "-d", "api", f.getPath() };
+ String[] args = { "-Xdoclint:none", "-d", "api", f.getPath() };
int rc = com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw,
com.sun.tools.doclets.standard.Standard.class.getName(), args);
pw.flush();
--- a/langtools/test/tools/javadoc/T6551367.java Wed Jul 05 18:37:13 2017 +0200
+++ b/langtools/test/tools/javadoc/T6551367.java Sun Jan 20 23:39:11 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, 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
@@ -46,7 +46,7 @@
File source = new File(testSrc, file);
int rc = execute("javadoc", "T6551367",
T6551367.class.getClassLoader(),
- new String[]{source.getPath(), "-d", destDir.getAbsolutePath()});
+ new String[]{"-Xdoclint:none", source.getPath(), "-d", destDir.getAbsolutePath()});
if (rc != 0)
throw new Error("unexpected exit from javadoc: " + rc);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/doclint/DocLintTest.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012, 2013, 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 8004834
+ * @summary Add doclint support into javadoc
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.tools.Diagnostic;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import static javax.tools.Diagnostic.Kind.*;
+
+import com.sun.tools.javac.main.Main;
+
+public class DocLintTest {
+ public static void main(String... args) throws Exception {
+ new DocLintTest().run();
+ }
+
+ DocumentationTool javadoc;
+ StandardJavaFileManager fm;
+ JavaFileObject file;
+
+ final String code =
+ /* 01 */ "/** Class comment. */\n" +
+ /* 02 */ "public class Test {\n" +
+ /* 03 */ " /** Method comment. */\n" +
+ /* 04 */ " public void method() { }\n" +
+ /* 05 */ "\n" +
+ /* 06 */ " /** Syntax < error. */\n" +
+ /* 07 */ " private void syntaxError() { }\n" +
+ /* 08 */ "\n" +
+ /* 09 */ " /** @see DoesNotExist */\n" +
+ /* 10 */ " protected void referenceError() { }\n" +
+ /* 11 */ "\n" +
+ /* 12 */ " /** @return */\n" +
+ /* 13 */ " public int emptyReturn() { return 0; }\n" +
+ /* 14 */ "}\n";
+
+ private final String rawDiags = "-XDrawDiagnostics";
+
+ private enum Message {
+ // doclint messages
+ DL_ERR6(ERROR, "Test.java:6:16: compiler.err.proc.messager: malformed HTML"),
+ DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"),
+ DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"),
+
+ // doclint messages when -XDrawDiagnostics is not in effect
+ DL_ERR9A(ERROR, "Test.java:9: error: reference not found"),
+ DL_WRN12A(WARNING, "Test.java:12: warning: no description for @return"),
+
+ // javadoc messages about bad content: these should only appear when doclint is disabled
+ JD_WRN10(WARNING, "Test.java:10: warning - Tag @see: reference not found: DoesNotExist"),
+ JD_WRN13(WARNING, "Test.java:13: warning - @return tag has no arguments."),
+
+ // javadoc messages for bad options
+ OPT_BADARG(ERROR, "javadoc: error - Invalid argument for -Xdoclint option"),
+ OPT_BADQUAL(ERROR, "javadoc: error - Access qualifiers not permitted for -Xdoclint arguments");
+
+ final Diagnostic.Kind kind;
+ final String text;
+
+ static Message get(String text) {
+ for (Message m: values()) {
+ if (m.text.equals(text))
+ return m;
+ }
+ return null;
+ }
+
+ Message(Diagnostic.Kind kind, String text) {
+ this.kind = kind;
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + kind + ",\"" + text + "\"]";
+ }
+ }
+
+ void run() throws Exception {
+ javadoc = ToolProvider.getSystemDocumentationTool();
+ fm = javadoc.getStandardFileManager(null, null, null);
+ fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
+ file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) {
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncoding) {
+ return code;
+ }
+ };
+
+ test(Collections.<String>emptyList(),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9A, Message.DL_WRN12A));
+
+ test(Arrays.asList(rawDiags),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));
+
+ test(Arrays.asList("-Xdoclint:none"),
+ Main.Result.OK,
+ EnumSet.of(Message.JD_WRN10, Message.JD_WRN13));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9, Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:all/public"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.OPT_BADQUAL));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:all", "-public"),
+ Main.Result.OK,
+ EnumSet.of(Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:syntax"),
+ Main.Result.OK,
+ EnumSet.of(Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:syntax", "-private"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR6, Message.DL_WRN12));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:reference"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.DL_ERR9));
+
+ test(Arrays.asList(rawDiags, "-Xdoclint:badarg"),
+ Main.Result.ERROR,
+ EnumSet.of(Message.OPT_BADARG));
+
+ if (errors > 0)
+ throw new Exception(errors + " errors occurred");
+ }
+
+ void test(List<String> opts, Main.Result expectResult, Set<Message> expectMessages) {
+ System.err.println("test: " + opts);
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ List<JavaFileObject> files = Arrays.asList(file);
+ try {
+ DocumentationTask t = javadoc.getTask(pw, fm, null, null, opts, files);
+ boolean ok = t.call();
+ pw.close();
+ String out = sw.toString().replaceAll("[\r\n]+", "\n");
+ if (!out.isEmpty())
+ System.err.println(out);
+ if (ok && expectResult != Main.Result.OK) {
+ error("Compilation succeeded unexpectedly");
+ } else if (!ok && expectResult != Main.Result.ERROR) {
+ error("Compilation failed unexpectedly");
+ } else
+ check(out, expectMessages);
+ } catch (IllegalArgumentException e) {
+ System.err.println(e);
+ String expectOut = expectMessages.iterator().next().text;
+ if (expectResult != Main.Result.CMDERR)
+ error("unexpected exception caught");
+ else if (!e.getMessage().equals(expectOut)) {
+ error("unexpected exception message: "
+ + e.getMessage()
+ + " expected: " + expectOut);
+ }
+ }
+
+// if (errors > 0)
+// throw new Error("stop");
+ }
+
+ private void check(String out, Set<Message> expect) {
+ Pattern ignore = Pattern.compile("^(Building|Constructing|Generating|Loading|Standard|Starting| ) .*");
+ Pattern stats = Pattern.compile("^([1-9]+) (error|warning)(s?)");
+ Set<Message> found = EnumSet.noneOf(Message.class);
+ int e = 0, w = 0;
+ for (String line: out.split("[\r\n]+")) {
+ if (ignore.matcher(line).matches())
+ continue;
+
+ Matcher s = stats.matcher(line);
+ if (s.matches()) {
+ int i = Integer.valueOf(s.group(1));
+ if (s.group(2).equals("error"))
+ e++;
+ else
+ w++;
+ continue;
+ }
+
+ Message m = Message.get(line);
+ if (m == null)
+ error("Unexpected line: " + line);
+ else
+ found.add(m);
+ }
+ for (Message m: expect) {
+ if (!found.contains(m))
+ error("expected message not found: " + m.text);
+ }
+ for (Message m: found) {
+ if (!expect.contains(m))
+ error("unexpected message found: " + m.text);
+ }
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/SJavac.java Sun Jan 20 23:39:11 2013 -0800
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2013, 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
+ * @summary Test all aspects of sjavac.
+ *
+ * @bug 8004658
+ * @summary Add internal smart javac wrapper to solve JEP 139
+ *
+ * @run main SJavac
+ */
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.charset.*;
+
+import com.sun.tools.sjavac.Main;
+
+public
+class SJavac {
+
+ public static void main(String... args) throws Exception {
+ URL url = SJavac.class.getClassLoader().getResource("com/sun/tools/sjavac/Main.class");
+ if (url == null) {
+ // No sjavac in the classpath.
+ System.out.println("pass by default");
+ return;
+ }
+
+ SJavac s = new SJavac();
+ s.test();
+ }
+
+ FileSystem defaultfs = FileSystems.getDefault();
+
+ // Where to put generated sources that will
+ // test aspects of sjavac, ie JTWork/scratch/gensrc
+ Path gensrc;
+ // More gensrc dirs are used to test merging of serveral source roots.
+ Path gensrc2;
+ Path gensrc3;
+
+ // Where to put compiled classes.
+ Path bin;
+ // Where to put c-header files.
+ Path headers;
+
+ // The sjavac compiler.
+ Main main = new Main();
+
+ // Remember the previous bin and headers state here.
+ Map<String,Long> previous_bin_state;
+ Map<String,Long> previous_headers_state;
+
+ public void test() throws Exception {
+ gensrc = defaultfs.getPath("gensrc");
+ gensrc2 = defaultfs.getPath("gensrc2");
+ gensrc3 = defaultfs.getPath("gensrc3");
+ bin = defaultfs.getPath("bin");
+ headers = defaultfs.getPath("headers");
+
+ Files.createDirectory(gensrc);
+ Files.createDirectory(gensrc2);
+ Files.createDirectory(gensrc3);
+ Files.createDirectory(bin);
+ Files.createDirectory(headers);
+
+ initialCompile();
+ incrementalCompileNoChanges();
+ incrementalCompileDroppingClasses();
+ incrementalCompileWithChange();
+ incrementalCompileDropAllNatives();
+ incrementalCompileAddNative();
+ incrementalCompileChangeNative();
+ compileWithOverrideSource();
+ compileWithInvisibleSources();
+ compileCircularSources();
+
+ delete(gensrc);
+ delete(gensrc2);
+ delete(gensrc3);
+ delete(bin);
+ }
+
+ void initialCompile() throws Exception {
+ System.out.println("\nInitial compile of gensrc.");
+ System.out.println("----------------------------");
+ populate(gensrc,
+ "alfa/AINT.java",
+ "package alfa; public interface AINT { void aint(); }",
+
+ "alfa/A.java",
+ "package alfa; public class A implements AINT { "+
+ "public final static int DEFINITION = 17; public void aint() { } }",
+
+ "alfa/AA.java",
+ "package alfa;"+
+ "// A package private class, not contributing to the public api.\n"+
+ "class AA {"+
+ " // A properly nested static inner class.\n"+
+ " static class AAA { }\n"+
+ " // A properly nested inner class.\n"+
+ " class AAAA { }\n"+
+ " Runnable foo() {\n"+
+ " // A proper anonymous class.\n"+
+ " return new Runnable() { public void run() { } };\n"+
+ " }\n"+
+ " AAA aaa;\n"+
+ " AAAA aaaa;\n"+
+ " AAAAA aaaaa;\n"+
+ "}\n"+
+ "class AAAAA {\n"+
+ " // A bad auxiliary class, but no one is referencing it\n"+
+ " // from outside of this source file, therefore it is ok.\n"+
+ "}\n",
+
+ "beta/BINT.java",
+ "package beta;public interface BINT { void foo(); }",
+
+ "beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } native void foo(); }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ previous_bin_state = collectState(bin);
+ previous_headers_state = collectState(headers);
+ }
+
+ void incrementalCompileNoChanges() throws Exception {
+ System.out.println("\nTesting that no change in sources implies no change in binaries.");
+ System.out.println("------------------------------------------------------------------");
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyEqual(new_bin_state, previous_bin_state);
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyEqual(previous_headers_state, new_headers_state);
+ }
+
+ void incrementalCompileDroppingClasses() throws Exception {
+ System.out.println("\nTesting that deleting AA.java deletes all");
+ System.out.println("generated inner class as well as AA.class");
+ System.out.println("-----------------------------------------");
+ removeFrom(gensrc, "alfa/AA.java");
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state,
+ "bin/alfa/AA$1.class",
+ "bin/alfa/AA$AAAA.class",
+ "bin/alfa/AA$AAA.class",
+ "bin/alfa/AAAAA.class",
+ "bin/alfa/AA.class");
+
+ previous_bin_state = new_bin_state;
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyEqual(previous_headers_state, new_headers_state);
+ }
+
+ void incrementalCompileWithChange() throws Exception {
+ System.out.println("\nNow update the A.java file with a new timestamps and");
+ System.out.println("new final static definition. This should trigger a recompile,");
+ System.out.println("not only of alfa, but also beta.");
+ System.out.println("But check that the generated native header was not updated!");
+ System.out.println("Since we did not modify the native api of B.");
+ System.out.println("-------------------------------------------------------------");
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; public class A implements AINT { "+
+ "public final static int DEFINITION = 18; public void aint() { } private void foo() { } }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/alfa/AINT.class",
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyEqual(new_headers_state, previous_headers_state);
+ }
+
+ void incrementalCompileDropAllNatives() throws Exception {
+ System.out.println("\nNow update the B.java file with one less native method,");
+ System.out.println("ie it has no longer any methods!");
+ System.out.println("Verify that beta_B.h is removed!");
+ System.out.println("---------------------------------------------------------");
+
+ populate(gensrc,"beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyThatFilesHaveBeenRemoved(previous_headers_state, new_headers_state,
+ "headers/beta_B.h");
+ previous_headers_state = new_headers_state;
+ }
+
+ void incrementalCompileAddNative() throws Exception {
+ System.out.println("\nNow update the B.java file with a final static annotated with @Native.");
+ System.out.println("Verify that beta_B.h is added again!");
+ System.out.println("------------------------------------------------------------------------");
+
+ populate(gensrc,"beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } "+
+ "@java.lang.annotation.Native final static int alfa = 42; }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyThatFilesHaveBeenAdded(previous_headers_state, new_headers_state,
+ "headers/beta_B.h");
+ previous_headers_state = new_headers_state;
+ }
+
+ void incrementalCompileChangeNative() throws Exception {
+ System.out.println("\nNow update the B.java file with a new value for the final static"+
+ " annotated with @Native.");
+ System.out.println("Verify that beta_B.h is rewritten again!");
+ System.out.println("-------------------------------------------------------------------");
+
+ populate(gensrc,"beta/B.java",
+ "package beta; import alfa.A; public class B {"+
+ "private int b() { return A.DEFINITION; } "+
+ "@java.lang.annotation.Native final static int alfa = 43; }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false", "--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyNewerFiles(previous_bin_state, new_bin_state,
+ "bin/beta/B.class",
+ "bin/beta/BINT.class",
+ "bin/javac_state");
+ previous_bin_state = new_bin_state;
+
+ Map<String,Long> new_headers_state = collectState(headers);
+ verifyNewerFiles(previous_headers_state, new_headers_state,
+ "headers/beta_B.h");
+ previous_headers_state = new_headers_state;
+ }
+
+ void compileWithOverrideSource() throws Exception {
+ System.out.println("\nNow verify that we can override sources to be compiled.");
+ System.out.println("Compile gensrc and gensrc2. However do not compile broken beta.B in gensrc,");
+ System.out.println("only compile ok beta.B in gensrc2.");
+ System.out.println("---------------------------------------------------------------------------");
+
+ delete(gensrc);
+ delete(gensrc2);
+ delete(bin);
+ previous_bin_state = collectState(bin);
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; import beta.B; import gamma.C; public class A { B b; C c; }",
+ "beta/B.java",
+ "package beta; public class B { broken",
+ "gamma/C.java",
+ "package gamma; public class C { }");
+
+ populate(gensrc2,
+ "beta/B.java",
+ "package beta; public class B { }");
+
+ compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/beta/B.class",
+ "bin/gamma/C.class",
+ "bin/javac_state");
+
+ System.out.println("----- Compile with exluded beta went well!");
+ delete(bin);
+ compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+
+ System.out.println("----- Compile without exluded beta failed, as expected! Good!");
+ delete(bin);
+ }
+
+ void compileWithInvisibleSources() throws Exception {
+ System.out.println("\nNow verify that we can make sources invisible to linking (sourcepath).");
+ System.out.println("Compile gensrc and link against gensrc2 and gensrc3, however");
+ System.out.println("gensrc2 contains broken code in beta.B, thus we must exclude that package");
+ System.out.println("fortunately gensrc3 contains a proper beta.B.");
+ System.out.println("------------------------------------------------------------------------");
+
+ // Start with a fresh gensrcs and bin.
+ delete(gensrc);
+ delete(gensrc2);
+ delete(gensrc3);
+ delete(bin);
+ previous_bin_state = collectState(bin);
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; import beta.B; import gamma.C; public class A { B b; C c; }");
+ populate(gensrc2,"beta/B.java",
+ "package beta; public class B { broken",
+ "gamma/C.java",
+ "package gamma; public class C { }");
+ populate(gensrc3, "beta/B.java",
+ "package beta; public class B { }");
+
+ compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2",
+ "-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+
+ System.out.println("The first compile went well!");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/javac_state");
+
+ System.out.println("----- Compile with exluded beta went well!");
+ delete(bin);
+ compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3",
+ "-d", "bin", "-h", "headers", "-j", "1",
+ "--server:portfile=testserver,background=false");
+
+ System.out.println("----- Compile without exluded beta failed, as expected! Good!");
+ delete(bin);
+ }
+
+ void compileCircularSources() throws Exception {
+ System.out.println("\nNow verify that circular sources split on multiple cores can be compiled.");
+ System.out.println("---------------------------------------------------------------------------");
+
+ // Start with a fresh gensrcs and bin.
+ delete(gensrc);
+ delete(gensrc2);
+ delete(gensrc3);
+ delete(bin);
+ previous_bin_state = collectState(bin);
+
+ populate(gensrc,"alfa/A.java",
+ "package alfa; public class A { beta.B b; }",
+ "beta/B.java",
+ "package beta; public class B { gamma.C c; }",
+ "gamma/C.java",
+ "package gamma; public class C { alfa.A a; }");
+
+ compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3",
+ "--server:portfile=testserver,background=false","--log=debug");
+ Map<String,Long> new_bin_state = collectState(bin);
+ verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+ "bin/alfa/A.class",
+ "bin/beta/B.class",
+ "bin/gamma/C.class",
+ "bin/javac_state");
+ delete(bin);
+ }
+
+ void removeFrom(Path dir, String... args) throws IOException {
+ for (String filename : args) {
+ Path p = dir.resolve(filename);
+ Files.delete(p);
+ }
+ }
+
+ void populate(Path src, String... args) throws IOException {
+ if (!Files.exists(src)) {
+ Files.createDirectory(src);
+ }
+ String[] a = args;
+ for (int i = 0; i<a.length; i+=2) {
+ String filename = a[i];
+ String content = a[i+1];
+ Path p = src.resolve(filename);
+ Files.createDirectories(p.getParent());
+ PrintWriter out = new PrintWriter(Files.newBufferedWriter(p,
+ Charset.defaultCharset()));
+ out.println(content);
+ out.close();
+ }
+ }
+
+ void delete(Path root) throws IOException {
+ if (!Files.exists(root)) return;
+ Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
+ {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException
+ {
+ if (e == null) {
+ if (!dir.equals(root)) Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ } else {
+ // directory iteration failed
+ throw e;
+ }
+ }
+ });
+ }
+
+ void compile(String... args) throws Exception {
+ int rc = main.go(args, System.out, System.err);
+ if (rc != 0) throw new Exception("Error during compile!");
+
+ // Wait a second, to get around the (temporary) problem with
+ // second resolution in the Java file api. But do not do this
+ // on windows where the timestamps work.
+ long in_a_sec = System.currentTimeMillis()+1000;
+ while (in_a_sec > System.currentTimeMillis()) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ void compileExpectFailure(String... args) throws Exception {
+ int rc = main.go(args, System.out, System.err);
+ if (rc == 0) throw new Exception("Expected error during compile! Did not fail!");
+ }
+
+ Map<String,Long> collectState(Path dir) throws IOException
+ {
+ final Map<String,Long> files = new HashMap<>();
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ files.put(file.toString(),new Long(Files.getLastModifiedTime(file).toMillis()));
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ return files;
+ }
+
+ void verifyThatFilesHaveBeenRemoved(Map<String,Long> from,
+ Map<String,Long> to,
+ String... args) throws Exception {
+
+ Set<String> froms = from.keySet();
+ Set<String> tos = to.keySet();
+
+ if (froms.equals(tos)) {
+ throw new Exception("Expected new state to have fewer files than previous state!");
+ }
+
+ for (String t : tos) {
+ if (!froms.contains(t)) {
+ throw new Exception("Expected "+t+" to exist in previous state!");
+ }
+ }
+
+ for (String f : args) {
+ f = f.replace("/", File.separator);
+ if (!froms.contains(f)) {
+ throw new Exception("Expected "+f+" to exist in previous state!");
+ }
+ if (tos.contains(f)) {
+ throw new Exception("Expected "+f+" to have been removed from the new state!");
+ }
+ }
+
+ if (froms.size() - args.length != tos.size()) {
+ throw new Exception("There are more removed files than the expected list!");
+ }
+ }
+
+ void verifyThatFilesHaveBeenAdded(Map<String,Long> from,
+ Map<String,Long> to,
+ String... args) throws Exception {
+
+ Set<String> froms = from.keySet();
+ Set<String> tos = to.keySet();
+
+ if (froms.equals(tos)) {
+ throw new Exception("Expected new state to have more files than previous state!");
+ }
+
+ for (String t : froms) {
+ if (!tos.contains(t)) {
+ throw new Exception("Expected "+t+" to exist in new state!");
+ }
+ }
+
+ for (String f : args) {
+ f = f.replace("/", File.separator);
+ if (!tos.contains(f)) {
+ throw new Exception("Expected "+f+" to have been added to new state!");
+ }
+ if (froms.contains(f)) {
+ throw new Exception("Expected "+f+" to not exist in previous state!");
+ }
+ }
+
+ if (froms.size() + args.length != tos.size()) {
+ throw new Exception("There are more added files than the expected list!");
+ }
+ }
+
+ void verifyNewerFiles(Map<String,Long> from,
+ Map<String,Long> to,
+ String... args) throws Exception {
+ if (!from.keySet().equals(to.keySet())) {
+ throw new Exception("Expected the set of files to be identical!");
+ }
+ Set<String> files = new HashSet<String>();
+ for (String s : args) {
+ files.add(s.replace("/", File.separator));
+ }
+ for (String fn : from.keySet()) {
+ long f = from.get(fn);
+ long t = to.get(fn);
+ if (files.contains(fn)) {
+ if (t <= f) {
+ throw new Exception("Expected "+fn+" to have a more recent timestamp!");
+ }
+ } else {
+ if (t != f) {
+ throw new Exception("Expected "+fn+" to have the same timestamp!");
+ }
+ }
+ }
+ }
+
+ String print(Map<String,Long> m) {
+ StringBuilder b = new StringBuilder();
+ Set<String> keys = m.keySet();
+ for (String k : keys) {
+ b.append(k+" "+m.get(k)+"\n");
+ }
+ return b.toString();
+ }
+
+ void verifyEqual(Map<String,Long> from, Map<String,Long> to) throws Exception {
+ if (!from.equals(to)) {
+ System.out.println("FROM---"+print(from));
+ System.out.println("TO-----"+print(to));
+ throw new Exception("The dir should not differ! But it does!");
+ }
+ }
+}