use of com.sun.tools.javac.tree.JCTree.JCStatement in project error-prone by google.
the class BlockTemplate method replace.
@Override
public Fix replace(BlockTemplateMatch match) {
checkNotNull(match);
SuggestedFix.Builder fix = SuggestedFix.builder();
Inliner inliner = match.createInliner();
Context context = inliner.getContext();
if (annotations().containsKey(UseImportPolicy.class)) {
ImportPolicy.bind(context, annotations().getInstance(UseImportPolicy.class).value());
} else {
ImportPolicy.bind(context, ImportPolicy.IMPORT_TOP_LEVEL);
}
ImmutableList<JCStatement> targetStatements = match.getStatements();
try {
ImmutableList.Builder<JCStatement> inlinedStatementsBuilder = ImmutableList.builder();
for (UStatement statement : templateStatements()) {
inlinedStatementsBuilder.addAll(statement.inlineStatements(inliner));
}
ImmutableList<JCStatement> inlinedStatements = inlinedStatementsBuilder.build();
int nInlined = inlinedStatements.size();
int nTargets = targetStatements.size();
if (nInlined <= nTargets) {
for (int i = 0; i < nInlined; i++) {
fix.replace(targetStatements.get(i), printStatement(context, inlinedStatements.get(i)));
}
for (int i = nInlined; i < nTargets; i++) {
fix.delete(targetStatements.get(i));
}
} else {
for (int i = 0; i < nTargets - 1; i++) {
fix.replace(targetStatements.get(i), printStatement(context, inlinedStatements.get(i)));
}
int last = nTargets - 1;
ImmutableList<JCStatement> remainingInlined = inlinedStatements.subList(last, nInlined);
fix.replace(targetStatements.get(last), CharMatcher.whitespace().trimTrailingFrom(printStatements(context, remainingInlined)));
}
} catch (CouldNotResolveImportException e) {
logger.log(SEVERE, "Failure to resolve import in replacement", e);
}
return addImports(inliner, fix);
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project error-prone by google.
the class BlockTemplate method match.
/**
* If the tree is a {@link JCBlock}, returns a list of disjoint matches corresponding to the exact
* list of template statements found consecutively; otherwise, returns an empty list.
*/
@Override
public Iterable<BlockTemplateMatch> match(JCTree tree, Context context) {
// TODO(lowasser): consider nonconsecutive matches?
if (tree instanceof JCBlock) {
JCBlock block = (JCBlock) tree;
ImmutableList<JCStatement> targetStatements = ImmutableList.copyOf(block.getStatements());
return matchesStartingAnywhere(block, 0, targetStatements, context).first().or(List.<BlockTemplateMatch>nil());
}
return ImmutableList.of();
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project error-prone by google.
the class BlockTemplate method matchesStartingAtBeginning.
private Choice<List<BlockTemplateMatch>> matchesStartingAtBeginning(final JCBlock block, final int offset, final ImmutableList<? extends StatementTree> statements, final Context context) {
if (statements.isEmpty()) {
return Choice.none();
}
final JCStatement firstStatement = (JCStatement) statements.get(0);
Choice<UnifierWithUnconsumedStatements> choice = Choice.of(UnifierWithUnconsumedStatements.create(new Unifier(context), statements));
for (UStatement templateStatement : templateStatements()) {
choice = choice.thenChoose(templateStatement);
}
return choice.thenChoose(new Function<UnifierWithUnconsumedStatements, Choice<List<BlockTemplateMatch>>>() {
@Override
public Choice<List<BlockTemplateMatch>> apply(UnifierWithUnconsumedStatements state) {
Unifier unifier = state.unifier();
Inliner inliner = unifier.createInliner();
try {
Optional<Unifier> checkedUnifier = typecheck(unifier, inliner, new Warner(firstStatement), expectedTypes(inliner), actualTypes(inliner));
if (checkedUnifier.isPresent()) {
int consumedStatements = statements.size() - state.unconsumedStatements().size();
BlockTemplateMatch match = new BlockTemplateMatch(block, checkedUnifier.get(), offset, offset + consumedStatements);
return matchesStartingAnywhere(block, offset + consumedStatements, statements.subList(consumedStatements, statements.size()), context).transform(prepend(match));
}
} catch (CouldNotResolveImportException e) {
// fall through
}
return Choice.none();
}
});
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project error-prone by google.
the class RefasterScanner method visitClass.
@Override
public Void visitClass(ClassTree node, Context context) {
Symbol sym = ASTHelpers.getSymbol(node);
if (sym == null || !sym.getQualifiedName().contentEquals(rule().qualifiedTemplateClass())) {
ListBuffer<JCStatement> statements = new ListBuffer<>();
for (Tree tree : node.getMembers()) {
if (tree instanceof JCStatement) {
statements.append((JCStatement) tree);
} else {
tree.accept(this, context);
}
}
scan(TreeMaker.instance(context).Block(0, statements.toList()), context);
}
return null;
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeLazyIterable.
/**
* Makes a lazy iterable literal, for a sequenced argument to a named invocation
* (<code>f{foo=""; expr1, expr2, *expr3}</code>) or
* for an iterable instantiation (<code>{expr1, expr2, *expr3}</code>)
*/
JCExpression makeLazyIterable(Tree.SequencedArgument sequencedArgument, Type seqElemType, Type absentType, int flags) {
java.util.List<PositionalArgument> list = sequencedArgument.getPositionalArguments();
int i = 0;
ListBuffer<JCStatement> returns = new ListBuffer<JCStatement>();
boolean spread = false;
boolean old = expressionGen().withinSyntheticClassBody(true);
try {
for (Tree.PositionalArgument arg : list) {
at(arg);
JCExpression jcExpression;
// last expression can be an Iterable<seqElemType>
if (arg instanceof Tree.SpreadArgument || arg instanceof Tree.Comprehension) {
// make sure we only have spread/comprehension as last
if (i != list.size() - 1) {
jcExpression = makeErroneous(arg, "compiler bug: spread or comprehension argument is not last in sequence literal");
} else {
Type type = typeFact().getIterableType(seqElemType);
spread = true;
if (arg instanceof Tree.SpreadArgument) {
Tree.Expression expr = ((Tree.SpreadArgument) arg).getExpression();
// always boxed since it is a sequence
jcExpression = expressionGen().transformExpression(expr, BoxingStrategy.BOXED, type);
} else {
jcExpression = expressionGen().transformComprehension((Comprehension) arg, type);
}
}
} else if (arg instanceof Tree.ListedArgument) {
Tree.Expression expr = ((Tree.ListedArgument) arg).getExpression();
// always boxed since we stuff them into a sequence
jcExpression = expressionGen().transformExpression(expr, BoxingStrategy.BOXED, seqElemType);
} else {
jcExpression = makeErroneous(arg, "compiler bug: " + arg.getNodeType() + " is not a supported sequenced argument");
}
at(arg);
// the last iterable goes first if spread
returns.add(make().Return(jcExpression));
i++;
}
at(sequencedArgument);
if (Strategy.preferLazySwitchingIterable(sequencedArgument.getPositionalArguments())) {
// use a LazySwitchingIterable
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$evaluate$.toString());
mdb.isOverride(true);
mdb.modifiers(PROTECTED | FINAL);
mdb.resultType(null, make().Type(syms().objectType));
mdb.parameter(ParameterDefinitionBuilder.systemParameter(this, Unfix.$index$.toString()).type(make().Type(syms().intType), null));
JCSwitch swtch;
try (SavedPosition sp = noPosition()) {
ListBuffer<JCCase> cases = ListBuffer.<JCCase>lb();
i = 0;
for (JCStatement e : returns) {
cases.add(make().Case(make().Literal(i++), List.<JCStatement>of(e)));
}
cases.add(make().Case(null, List.<JCStatement>of(make().Return(makeNull()))));
swtch = make().Switch(naming.makeUnquotedIdent(Unfix.$index$), cases.toList());
}
mdb.body(swtch);
return make().NewClass(null, //of(makeJavaType(seqElemType), makeJavaType(absentType)),
List.<JCExpression>nil(), make().TypeApply(make().QualIdent(syms.ceylonLazyIterableType.tsym), List.<JCExpression>of(makeJavaType(seqElemType, JT_TYPE_ARGUMENT), makeJavaType(absentType, JT_TYPE_ARGUMENT))), // td,
List.of(// td,
makeReifiedTypeArgument(seqElemType), //td
makeReifiedTypeArgument(absentType), // numMethods
make().Literal(list.size()), // spread),
make().Literal(spread)), make().AnonymousClassDef(make().Modifiers(FINAL), List.<JCTree>of(mdb.build())));
} else {
// use a LazyInvokingIterable
ListBuffer<JCTree> methods = new ListBuffer<JCTree>();
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$lookup$.toString());
mdb.isOverride(true);
mdb.modifiers(PROTECTED | FINAL);
mdb.resultType(null, naming.makeQualIdent(make().Type(syms().methodHandlesType), "Lookup"));
mdb.body(make().Return(make().Apply(List.<JCExpression>nil(), naming.makeQualIdent(make().Type(syms().methodHandlesType), "lookup"), List.<JCExpression>nil())));
methods.add(mdb.build());
mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$invoke$.toString());
mdb.isOverride(true);
mdb.modifiers(PROTECTED | FINAL);
mdb.resultType(null, make().Type(syms().objectType));
mdb.parameter(ParameterDefinitionBuilder.systemParameter(this, "handle").type(make().Type(syms().methodHandleType), null));
mdb.body(make().Return(make().Apply(List.<JCExpression>nil(), naming.makeQualIdent(naming.makeUnquotedIdent("handle"), "invokeExact"), List.<JCExpression>of(naming.makeThis()))));
methods.add(mdb.build());
i = 0;
for (JCStatement expr : returns) {
mdb = MethodDefinitionBuilder.systemMethod(this, "$" + i);
i++;
mdb.modifiers(PRIVATE | FINAL);
mdb.resultType(null, make().Type(syms().objectType));
mdb.body(expr);
methods.add(mdb.build());
}
return make().NewClass(null, //of(makeJavaType(seqElemType), makeJavaType(absentType)),
List.<JCExpression>nil(), make().TypeApply(make().QualIdent(syms.ceylonLazyInvokingIterableType.tsym), List.<JCExpression>of(makeJavaType(seqElemType, JT_TYPE_ARGUMENT), makeJavaType(absentType, JT_TYPE_ARGUMENT))), // td,
List.of(// td,
makeReifiedTypeArgument(seqElemType), //td
makeReifiedTypeArgument(absentType), // numMethods
make().Literal(list.size()), // spread),
make().Literal(spread)), make().AnonymousClassDef(make().Modifiers(FINAL), methods.toList()));
}
} finally {
expressionGen().withinSyntheticClassBody(old);
}
}
Aggregations