Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 55 additions & 16 deletions make/langtools/tools/propertiesparser/gen/ClassGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
Expand Down Expand Up @@ -87,9 +88,12 @@ enum StubKind {
FACTORY_METHOD_DECL("factory.decl.method"),
FACTORY_METHOD_ARG("factory.decl.method.arg"),
FACTORY_METHOD_BODY("factory.decl.method.body"),
FACTORY_METHOD_BODY_LINT("factory.decl.method.body.lint"),
FACTORY_FIELD("factory.decl.field"),
FACTORY_FIELD_LINT("factory.decl.field.lint"),
WILDCARDS_EXTENDS("wildcards.extends"),
SUPPRESS_WARNINGS("suppress.warnings");
SUPPRESS_WARNINGS("suppress.warnings"),
LINT_CATEGORY("lint.category");

/** stub key (as it appears in the property file) */
String key;
Expand All @@ -114,6 +118,7 @@ String format(Object... args) {
enum FactoryKind {
ERR("err", "Error", "Errors"),
WARN("warn", "Warning", "Warnings"),
LINT_WARN("warn", "LintWarning", "LintWarnings"),
NOTE("note", "Note", "Notes"),
MISC("misc", "Fragment", "Fragments"),
OTHER(null, null, null);
Expand All @@ -136,13 +141,24 @@ enum FactoryKind {
/**
* Utility method for parsing a factory kind from a resource key prefix.
*/
static FactoryKind parseFrom(String prefix) {
static FactoryKind of(Entry<String, Message> messageEntry) {
String prefix = messageEntry.getKey().split("\\.")[1];
FactoryKind selected = null;
for (FactoryKind k : FactoryKind.values()) {
if (k.prefix == null || k.prefix.equals(prefix)) {
return k;
selected = k;
break;
}
}
return null;
if (selected == WARN) {
for (MessageLine line : messageEntry.getValue().getLines(false)) {
if (line.isLint()) {
selected = LINT_WARN;
break;
}
}
}
return selected;
}
}

Expand All @@ -155,7 +171,7 @@ public void generateFactory(MessageFile messageFile, File outDir) {
messageFile.messages.entrySet().stream()
.collect(
Collectors.groupingBy(
e -> FactoryKind.parseFrom(e.getKey().split("\\.")[1]),
FactoryKind::of,
TreeMap::new,
toList()));
//generate nested classes
Expand All @@ -165,7 +181,7 @@ public void generateFactory(MessageFile messageFile, File outDir) {
if (entry.getKey() == FactoryKind.OTHER) continue;
//emit members
String members = entry.getValue().stream()
.flatMap(e -> generateFactoryMethodsAndFields(e.getKey(), e.getValue()).stream())
.flatMap(e -> generateFactoryMethodsAndFields(entry.getKey(), e.getKey(), e.getValue()).stream())
.collect(Collectors.joining("\n\n"));
//emit nested class
String factoryDecl =
Expand Down Expand Up @@ -230,22 +246,35 @@ List<String> generateImports(Set<String> importedTypes) {
/**
* Generate a list of factory methods/fields to be added to a given factory nested class.
*/
List<String> generateFactoryMethodsAndFields(String key, Message msg) {
List<String> generateFactoryMethodsAndFields(FactoryKind k, String key, Message msg) {
MessageInfo msgInfo = msg.getMessageInfo();
List<MessageLine> lines = msg.getLines(false);
String javadoc = lines.stream()
.filter(ml -> !ml.isInfo() && !ml.isEmptyOrComment())
.map(ml -> ml.text)
.collect(Collectors.joining("\n *"));
String[] keyParts = key.split("\\.");
FactoryKind k = FactoryKind.parseFrom(keyParts[1]);
String lintCategory = lines.stream()
.filter(MessageLine::isLint)
.map(MessageLine::lintCategory)
.findFirst().orElse(null);
//System.out.println("category for " + key + " = " + lintCategory);
String factoryName = factoryName(key);
if (msgInfo.getTypes().isEmpty()) {
//generate field
String factoryField = StubKind.FACTORY_FIELD.format(k.keyClazz, factoryName,
"\"" + keyParts[0] + "\"",
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
javadoc);
String factoryField;
if (lintCategory == null) {
factoryField = StubKind.FACTORY_FIELD.format(k.keyClazz, factoryName,
"\"" + keyParts[0] + "\"",
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
javadoc);
} else {
factoryField = StubKind.FACTORY_FIELD_LINT.format(k.keyClazz, factoryName,
StubKind.LINT_CATEGORY.format("\"" + lintCategory + "\""),
"\"" + keyParts[0] + "\"",
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
javadoc);
}
return Collections.singletonList(factoryField);
} else {
//generate method
Expand All @@ -255,12 +284,22 @@ List<String> generateFactoryMethodsAndFields(String key, Message msg) {
List<String> argNames = argNames(types.size());
String suppressionString = needsSuppressWarnings(msgTypes) ?
StubKind.SUPPRESS_WARNINGS.format() : "";
String methodBody;
if (lintCategory == null) {
methodBody = StubKind.FACTORY_METHOD_BODY.format(k.keyClazz,
"\"" + keyParts[0] + "\"",
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
argNames.stream().collect(Collectors.joining(", ")));
} else {
methodBody = StubKind.FACTORY_METHOD_BODY_LINT.format(k.keyClazz,
StubKind.LINT_CATEGORY.format("\"" + lintCategory + "\""),
"\"" + keyParts[0] + "\"",
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
argNames.stream().collect(Collectors.joining(", ")));
}
String factoryMethod = StubKind.FACTORY_METHOD_DECL.format(suppressionString, k.keyClazz,
factoryName, argDecls(types, argNames).stream().collect(Collectors.joining(", ")),
indent(StubKind.FACTORY_METHOD_BODY.format(k.keyClazz,
"\"" + keyParts[0] + "\"",
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
argNames.stream().collect(Collectors.joining(", "))), 1),
indent(methodBody, 1),
javadoc);
factoryMethods.add(factoryMethod);
}
Expand Down
5 changes: 4 additions & 1 deletion make/langtools/tools/propertiesparser/parser/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public final class Message {
public MessageInfo getMessageInfo() {
if (messageInfo == null) {
MessageLine l = firstLine.prev;
if (l != null && l.isLint()) {
l = l.prev;
}
if (l != null && l.isInfo())
messageInfo = new MessageInfo(l.text);
else
Expand All @@ -71,7 +74,7 @@ public List<MessageLine> getLines(boolean includeAllPrecedingComments) {
while (l.text.isEmpty())
l = l.next;
} else {
if (l.prev != null && l.prev.isInfo())
if (l.prev != null && (l.prev.isInfo() || l.prev.isLint()))
l = l.prev;
}

Expand Down
15 changes: 15 additions & 0 deletions make/langtools/tools/propertiesparser/parser/MessageLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

package propertiesparser.parser;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
Expand All @@ -37,6 +38,7 @@ public class MessageLine {
static final Pattern typePattern = Pattern.compile("[-\\\\'A-Z\\.a-z ]+( \\([-A-Za-z 0-9]+\\))?");
static final Pattern infoPattern = Pattern.compile(String.format("# ([0-9]+: %s, )*[0-9]+: %s",
typePattern.pattern(), typePattern.pattern()));
static final Pattern lintPattern = Pattern.compile("# lint: ([a-z\\-]+)");

public String text;
MessageLine prev;
Expand All @@ -54,6 +56,19 @@ public boolean isInfo() {
return infoPattern.matcher(text).matches();
}

public boolean isLint() {
return lintPattern.matcher(text).matches();
}

public String lintCategory() {
Matcher matcher = lintPattern.matcher(text);
if (matcher.matches()) {
return matcher.group(1);
} else {
return null;
}
}

boolean hasContinuation() {
return (next != null) && text.endsWith("\\");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ toplevel.decl=\
{1}\n\
import com.sun.tools.javac.util.JCDiagnostic.Error;\n\
import com.sun.tools.javac.util.JCDiagnostic.Warning;\n\
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;\n\
import com.sun.tools.javac.util.JCDiagnostic.Note;\n\
import com.sun.tools.javac.util.JCDiagnostic.Fragment;\n\
import com.sun.tools.javac.code.Lint.LintCategory;\n\
\n\
public class {2} '{'\n\
{3}\n\
Expand Down Expand Up @@ -58,16 +60,27 @@ factory.decl.method.arg=\
factory.decl.method.body=\
return new {0}({1}, {2}, {3});

factory.decl.method.body.lint=\
return new {0}({1}, {2}, {3}, {4});

factory.decl.field=\
/**\n\
' '* {4}\n\
' '*/\n\
public static final {0} {1} = new {0}({2}, {3});

factory.decl.field.lint=\
/**\n\
' '* {5}\n\
' '*/\n\
public static final {0} {1} = new {0}({2}, {3}, {4});

wildcards.extends=\
{0}<? extends {1}>

suppress.warnings=\
@SuppressWarnings("rawtypes")\n

lint.category=\
LintCategory.get({0})

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.Pair;

Expand Down Expand Up @@ -359,7 +362,7 @@ public enum LintCategory {
map.put(option, this);
}

static LintCategory get(String option) {
public static LintCategory get(String option) {
return map.get(option);
}

Expand All @@ -385,6 +388,15 @@ public boolean isSuppressed(LintCategory lc) {
return suppressedValues.contains(lc);
}

/**
* Helper method. Log a lint warning if its lint category is enabled.
*/
public void logIfEnabled(Log log, DiagnosticPosition pos, LintWarning warning) {
if (isEnabled(warning.getLintCategory())) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure about this method. On the one hand it makes clients simpler - but it does require Lint keeping track of a log. An alternative could be to add a method in AbstractLog, e.g.:

warningIfEnabled(DiagnosticPosition pos, Lint lint, LintWarning key)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elsewhere, @archiecobbs suggested to maybe make log a parameter of the method. I like the simplicity of the suggestion, and I will go with it.

log.warning(pos, warning);
}
}

protected static class AugmentVisitor implements Attribute.Visitor {
private final Context context;
private Symtab syms;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.Error;
import com.sun.tools.javac.util.JCDiagnostic.LintWarning;
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.Warning;
import com.sun.tools.javac.util.Log;
Expand Down Expand Up @@ -175,8 +177,8 @@ public void warnPreview(DiagnosticPosition pos, Feature feature) {
if (!lint.isSuppressed(LintCategory.PREVIEW)) {
sourcesWithPreviewFeatures.add(log.currentSourceFile());
previewHandler.report(pos, feature.isPlural() ?
Warnings.PreviewFeatureUsePlural(feature.nameFragment()) :
Warnings.PreviewFeatureUse(feature.nameFragment()));
LintWarnings.PreviewFeatureUsePlural(feature.nameFragment()) :
LintWarnings.PreviewFeatureUse(feature.nameFragment()));
}
}

Expand All @@ -188,16 +190,16 @@ public void warnPreview(DiagnosticPosition pos, Feature feature) {
public void warnPreview(JavaFileObject classfile, int majorVersion) {
Assert.check(isEnabled());
if (lint.isEnabled(LintCategory.PREVIEW)) {
log.mandatoryWarning(LintCategory.PREVIEW, null,
Warnings.PreviewFeatureUseClassfile(classfile, majorVersionToSource.get(majorVersion).name));
log.mandatoryWarning(null,
LintWarnings.PreviewFeatureUseClassfile(classfile, majorVersionToSource.get(majorVersion).name));
}
}

public void markUsesPreview(DiagnosticPosition pos) {
sourcesWithPreviewFeatures.add(log.currentSourceFile());
}

public void reportPreviewWarning(DiagnosticPosition pos, Warning warnKey) {
public void reportPreviewWarning(DiagnosticPosition pos, LintWarning warnKey) {
previewHandler.report(pos, warnKey);
}

Expand Down
Loading