Skip to content

Commit 8ada5b6

Browse files
committed
Add null checks for tree.getParameters(), unit test for eclipse-archived#7441
1 parent 7e653a1 commit 8ada5b6

File tree

5 files changed

+133
-113
lines changed

5 files changed

+133
-113
lines changed

compiler-java/src/org/eclipse/ceylon/compiler/java/codegen/CeylonTransformer.java

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -222,29 +222,32 @@ private List<JCTree> makeClassBody(Declaration decl, WantedDeclaration wantedDec
222222
// only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
223223
if(wantedDeclaration == WantedDeclaration.Annotation){
224224
ListBuffer<JCTree> body = new ListBuffer<JCTree>();
225-
for(Tree.Parameter param : ((Tree.ClassDefinition)decl).getParameterList().getParameters()){
226-
String name;
227-
228-
JCExpression type = make().TypeArray(make().Type(syms().stringType));
229-
if(param instanceof Tree.InitializerParameter)
230-
name = ((Tree.InitializerParameter)param).getIdentifier().getText();
231-
else if(param instanceof Tree.ParameterDeclaration){
232-
Tree.TypedDeclaration typedDeclaration = ((Tree.ParameterDeclaration)param).getTypedDeclaration();
233-
name = typedDeclaration.getIdentifier().getText();
234-
type = getAnnotationTypeFor(typedDeclaration.getType());
235-
}else
236-
name = "ERROR";
237-
JCMethodDecl method
238-
= make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString(name),
239-
type,
240-
List.<JCTypeParameter>nil(),
241-
List.<JCVariableDecl>nil(),
242-
List.<JCExpression>nil(),
243-
null,
244-
null);
245-
body.append(method);
246-
}
247-
return body.toList();
225+
Tree.ClassDefinition classDefiniton=(Tree.ClassDefinition)decl;
226+
if(classDefiniton.getParameterList()!=null) {
227+
for(Tree.Parameter param : classDefiniton.getParameterList().getParameters()){
228+
String name;
229+
230+
JCExpression type = make().TypeArray(make().Type(syms().stringType));
231+
if(param instanceof Tree.InitializerParameter)
232+
name = ((Tree.InitializerParameter)param).getIdentifier().getText();
233+
else if(param instanceof Tree.ParameterDeclaration){
234+
Tree.TypedDeclaration typedDeclaration = ((Tree.ParameterDeclaration)param).getTypedDeclaration();
235+
name = typedDeclaration.getIdentifier().getText();
236+
type = getAnnotationTypeFor(typedDeclaration.getType());
237+
}else
238+
name = "ERROR";
239+
JCMethodDecl method
240+
= make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString(name),
241+
type,
242+
List.<JCTypeParameter>nil(),
243+
List.<JCVariableDecl>nil(),
244+
List.<JCExpression>nil(),
245+
null,
246+
null);
247+
body.append(method);
248+
}
249+
return body.toList();
250+
}
248251
}
249252
if(wantedDeclaration == WantedDeclaration.AnnotationSequence){
250253
String name = Naming.toplevelClassName("", decl);

compiler-java/src/org/eclipse/ceylon/compiler/java/codegen/ClassTransformer.java

Lines changed: 94 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -841,96 +841,99 @@ private void transformAnnotationClassConstructor(
841841
// annotation
842842

843843
ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
844-
if (!klass.getUnit().getPackage().isLanguagePackage()
845-
|| !classBuilder.getClassName().equals("RestrictedAnnotation")) { //ignore argument to restricted()
846-
for (Tree.Parameter parameter : def.getParameterList().getParameters()) {
847-
at(parameter);
848-
Parameter parameterModel = parameter.getParameterModel();
849-
JCExpression annoAttr = make().Apply(null, naming.makeQuotedQualIdent(naming.makeUnquotedIdent("anno"),
850-
parameter.getParameterModel().getName()),
851-
List.<JCExpression>nil());
852-
Type parameterType = parameterModel.getType();
853-
JCExpression argExpr;
854-
if (typeFact().isIterableType(parameterType)
855-
&& !isCeylonString(parameterType)) {
856-
// Convert from array to Sequential
857-
Type iteratedType = typeFact().getIteratedType(parameterType);
858-
boolean nonEmpty = typeFact().isNonemptyIterableType(parameterType);
859-
if (isCeylonBasicType(iteratedType)) {
860-
argExpr = utilInvocation().sequentialWrapperBoxed(annoAttr);
861-
} else if (Decl.isAnnotationClass(iteratedType.getDeclaration())) {
862-
// Can't use Util.sequentialAnnotation becase we need to 'box'
863-
// the Java annotations in their Ceylon annotation class
864-
argExpr = make().Apply(null, naming.makeUnquotedIdent(naming.getAnnotationSequenceMethodName()), List.of(annoAttr));
865-
ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
866-
SyntheticName array = naming.synthetic(Unfix.$array$);
867-
SyntheticName sb = naming.synthetic(Unfix.$sb$);
868-
SyntheticName index = naming.synthetic(Unfix.$index$);
869-
SyntheticName element = naming.synthetic(Unfix.$element$);
870-
stmts.append(makeVar(FINAL, sb,
871-
make().TypeArray(make().Type(syms().objectType)),
872-
make().NewArray(make().Type(syms().objectType), List.of(naming.makeQualIdent(array.makeIdent(), "length")), null)));
873-
stmts.append(makeVar(index,
874-
make().Type(syms().intType),
875-
make().Literal(0)));
876-
stmts.append(make().ForeachLoop(
877-
makeVar(element, makeJavaType(iteratedType, JT_ANNOTATION), null),
878-
array.makeIdent(),
879-
make().Exec(make().Assign(
880-
make().Indexed(sb.makeIdent(),
881-
make().Unary(JCTree.Tag.POSTINC, index.makeIdent())),
882-
instantiateAnnotationClass(iteratedType, element.makeIdent())))));
883-
stmts.append(make().Return(
884-
make().NewClass(null,
885-
null,
886-
make().QualIdent(syms().ceylonTupleType.tsym),
887-
List.of(makeReifiedTypeArgument(iteratedType),
888-
sb.makeIdent(),
889-
makeEmpty(),
890-
make().Literal(false)),
891-
null)));
892-
classBuilder.method(
893-
systemMethod(this, naming.getAnnotationSequenceMethodName())
894-
.ignoreModelAnnotations()
895-
.modifiers(PRIVATE | STATIC)
896-
.resultType(new TransformedType(makeJavaType(typeFact().getSequentialType(iteratedType)), null, makeAtNonNull()))
897-
.parameter(systemParameter(this, array.getName())
898-
.type(new TransformedType(make().TypeArray(makeJavaType(iteratedType, JT_ANNOTATION)))))
899-
.body(stmts.toList()));
900-
} else if (isCeylonMetamodelDeclaration(iteratedType)) {
901-
argExpr = makeMetamodelInvocation("parseMetamodelReferences",
902-
List.<JCExpression>of(makeReifiedTypeArgument(iteratedType), annoAttr),
903-
List.<JCExpression>of(makeJavaType(iteratedType, JT_TYPE_ARGUMENT)));
904-
} else if (Decl.isEnumeratedTypeWithAnonCases(iteratedType)) {
905-
argExpr = makeMetamodelInvocation("parseEnumerationReferences",
906-
List.<JCExpression>of(makeReifiedTypeArgument(iteratedType), annoAttr),
907-
List.<JCExpression>of(makeJavaType(iteratedType, JT_TYPE_ARGUMENT)));
908-
} else {
909-
argExpr = makeErroneous(parameter, "compiler bug");
910-
}
911-
if (nonEmpty) {
912-
argExpr = make().TypeCast(makeJavaType(parameterType), argExpr);
913-
}
914-
} else if (Decl.isAnnotationClass(parameterType.getDeclaration())) {
915-
argExpr = instantiateAnnotationClass(parameterType, annoAttr);
916-
} else if (isCeylonMetamodelDeclaration(parameterType)) {
917-
argExpr = makeMetamodelInvocation("parseMetamodelReference",
918-
List.<JCExpression>of(annoAttr),
919-
List.<JCExpression>of(makeJavaType(parameterType, JT_TYPE_ARGUMENT)));
920-
} else if (Decl.isEnumeratedTypeWithAnonCases(parameterType)) {
921-
argExpr = makeMetamodelInvocation("parseEnumerationReference",
922-
List.<JCExpression>of(annoAttr),
923-
null);
924-
} else {
925-
argExpr = annoAttr;
926-
argExpr = expressionGen().applyErasureAndBoxing(annoAttr, parameterType.withoutUnderlyingType(), false, BoxingStrategy.UNBOXED, parameterType);
927-
}
928-
929-
args.add(argExpr);
930-
}
844+
if(def.getParameterList()!=null) {
845+
if (!klass.getUnit().getPackage().isLanguagePackage()
846+
|| !classBuilder.getClassName().equals("RestrictedAnnotation")) { //ignore argument to restricted()
847+
for (Tree.Parameter parameter : def.getParameterList().getParameters()) {
848+
at(parameter);
849+
Parameter parameterModel = parameter.getParameterModel();
850+
JCExpression annoAttr = make().Apply(null, naming.makeQuotedQualIdent(naming.makeUnquotedIdent("anno"),
851+
parameter.getParameterModel().getName()),
852+
List.<JCExpression>nil());
853+
Type parameterType = parameterModel.getType();
854+
JCExpression argExpr;
855+
if (typeFact().isIterableType(parameterType)
856+
&& !isCeylonString(parameterType)) {
857+
// Convert from array to Sequential
858+
Type iteratedType = typeFact().getIteratedType(parameterType);
859+
boolean nonEmpty = typeFact().isNonemptyIterableType(parameterType);
860+
if (isCeylonBasicType(iteratedType)) {
861+
argExpr = utilInvocation().sequentialWrapperBoxed(annoAttr);
862+
} else if (Decl.isAnnotationClass(iteratedType.getDeclaration())) {
863+
// Can't use Util.sequentialAnnotation becase we need to 'box'
864+
// the Java annotations in their Ceylon annotation class
865+
argExpr = make().Apply(null, naming.makeUnquotedIdent(naming.getAnnotationSequenceMethodName()), List.of(annoAttr));
866+
ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
867+
SyntheticName array = naming.synthetic(Unfix.$array$);
868+
SyntheticName sb = naming.synthetic(Unfix.$sb$);
869+
SyntheticName index = naming.synthetic(Unfix.$index$);
870+
SyntheticName element = naming.synthetic(Unfix.$element$);
871+
stmts.append(makeVar(FINAL, sb,
872+
make().TypeArray(make().Type(syms().objectType)),
873+
make().NewArray(make().Type(syms().objectType), List.of(naming.makeQualIdent(array.makeIdent(), "length")), null)));
874+
stmts.append(makeVar(index,
875+
make().Type(syms().intType),
876+
make().Literal(0)));
877+
stmts.append(make().ForeachLoop(
878+
makeVar(element, makeJavaType(iteratedType, JT_ANNOTATION), null),
879+
array.makeIdent(),
880+
make().Exec(make().Assign(
881+
make().Indexed(sb.makeIdent(),
882+
make().Unary(JCTree.Tag.POSTINC, index.makeIdent())),
883+
instantiateAnnotationClass(iteratedType, element.makeIdent())))));
884+
stmts.append(make().Return(
885+
make().NewClass(null,
886+
null,
887+
make().QualIdent(syms().ceylonTupleType.tsym),
888+
List.of(makeReifiedTypeArgument(iteratedType),
889+
sb.makeIdent(),
890+
makeEmpty(),
891+
make().Literal(false)),
892+
null)));
893+
classBuilder.method(
894+
systemMethod(this, naming.getAnnotationSequenceMethodName())
895+
.ignoreModelAnnotations()
896+
.modifiers(PRIVATE | STATIC)
897+
.resultType(new TransformedType(makeJavaType(typeFact().getSequentialType(iteratedType)), null, makeAtNonNull()))
898+
.parameter(systemParameter(this, array.getName())
899+
.type(new TransformedType(make().TypeArray(makeJavaType(iteratedType, JT_ANNOTATION)))))
900+
.body(stmts.toList()));
901+
} else if (isCeylonMetamodelDeclaration(iteratedType)) {
902+
argExpr = makeMetamodelInvocation("parseMetamodelReferences",
903+
List.<JCExpression>of(makeReifiedTypeArgument(iteratedType), annoAttr),
904+
List.<JCExpression>of(makeJavaType(iteratedType, JT_TYPE_ARGUMENT)));
905+
} else if (Decl.isEnumeratedTypeWithAnonCases(iteratedType)) {
906+
argExpr = makeMetamodelInvocation("parseEnumerationReferences",
907+
List.<JCExpression>of(makeReifiedTypeArgument(iteratedType), annoAttr),
908+
List.<JCExpression>of(makeJavaType(iteratedType, JT_TYPE_ARGUMENT)));
909+
} else {
910+
argExpr = makeErroneous(parameter, "compiler bug");
911+
}
912+
if (nonEmpty) {
913+
argExpr = make().TypeCast(makeJavaType(parameterType), argExpr);
914+
}
915+
} else if (Decl.isAnnotationClass(parameterType.getDeclaration())) {
916+
argExpr = instantiateAnnotationClass(parameterType, annoAttr);
917+
} else if (isCeylonMetamodelDeclaration(parameterType)) {
918+
argExpr = makeMetamodelInvocation("parseMetamodelReference",
919+
List.<JCExpression>of(annoAttr),
920+
List.<JCExpression>of(makeJavaType(parameterType, JT_TYPE_ARGUMENT)));
921+
} else if (Decl.isEnumeratedTypeWithAnonCases(parameterType)) {
922+
argExpr = makeMetamodelInvocation("parseEnumerationReference",
923+
List.<JCExpression>of(annoAttr),
924+
null);
925+
} else {
926+
argExpr = annoAttr;
927+
argExpr = expressionGen().applyErasureAndBoxing(annoAttr, parameterType.withoutUnderlyingType(), false, BoxingStrategy.UNBOXED, parameterType);
928+
}
929+
930+
args.add(argExpr);
931+
}
932+
}
931933
}
932934
annoCtor.body(at(def).Exec(
933935
make().Apply(null, naming.makeThis(), args.toList())));
936+
934937
}
935938

936939
private JCNewClass instantiateAnnotationClass(
@@ -983,9 +986,10 @@ private List<JCTree> transformAnnotationClass(Tree.AnyClass def) {
983986
} else {
984987
annoBuilder.annotations(transformAnnotationConstraints(klass));
985988
}
986-
987-
for (Tree.Parameter p : def.getParameterList().getParameters()) {
988-
annoBuilder.method(makeAnnotationMethod(p));
989+
if(def.getParameterList()!=null) {
990+
for (Tree.Parameter p : def.getParameterList().getParameters()) {
991+
annoBuilder.method(makeAnnotationMethod(p));
992+
}
989993
}
990994
List<JCTree> result;
991995
if (isSequencedAnnotation(klass)) {

compiler-java/test/src/org/eclipse/ceylon/compiler/java/test/issues/IssuesTests_7000_7499.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,8 @@ public void bug7263() throws Throwable{
146146
compile("bug72xx/bug7263/run.ceylon");
147147
runInJBossModules("run", "org.eclipse.ceylon.compiler.java.test.issues.bug72xx.bug7263/1", Collections.<String>emptyList());
148148
}
149+
@Test
150+
public void bug7441() {
151+
assertErrors("bug74xx/bug7441",Collections.emptyList(), null,new CompilerError(8, "illegal annotation parameter type: 'Anything'") );
152+
}
149153
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import ceylon.language.meta.declaration {
2+
ValueDeclaration
3+
}
4+
5+
shared final annotation class TestAnnotation satisfies OptionalAnnotation<TestAnnotation,ValueDeclaration> {
6+
shared new (Anything args) {}
7+
}
8+
shared annotation TestAnnotation testAnnotation(Anything args) => TestAnnotation(args);

typechecker/src/org/eclipse/ceylon/compiler/typechecker/analyzer/AnnotationVisitor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ private void checkAnnotationType(Tree.AnyClass that, Class c) {
429429
that.addError("annotation class must directly extend 'Basic'");
430430
}
431431
}
432+
if(that.getParameterList()!=null)
432433
for (Tree.Parameter pn:
433434
that.getParameterList().getParameters()) {
434435
checkAnnotationParameter(c, pn);

0 commit comments

Comments
 (0)