[Git][java-team/qdox2][upstream] New upstream version 2.0.1
Emmanuel Bourg (@ebourg)
gitlab at salsa.debian.org
Mon Jun 20 16:52:44 BST 2022
Emmanuel Bourg pushed to branch upstream at Debian Java Maintainers / qdox2
Commits:
31ddd89a by Emmanuel Bourg at 2022-06-20T16:54:30+02:00
New upstream version 2.0.1
- - - - -
15 changed files:
- pom.xml
- src/grammar/lexer.flex
- src/grammar/parser.y
- src/main/java/com/thoughtworks/qdox/builder/impl/DefaultJavaAnnotationAssembler.java
- src/main/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitor.java
- src/main/java/com/thoughtworks/qdox/model/expression/ExpressionVisitor.java
- src/main/java/com/thoughtworks/qdox/model/expression/FieldRef.java
- + src/main/java/com/thoughtworks/qdox/model/expression/Lambda.java
- src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueTransformer.java
- + src/main/java/com/thoughtworks/qdox/parser/expression/LambdaDef.java
- src/test/java/com/thoughtworks/qdox/JavaProjectBuilderTest.java
- + src/test/java/com/thoughtworks/qdox/RecordsTest.java
- + src/test/java/com/thoughtworks/qdox/SealedClassesTest.java
- + src/test/java/com/thoughtworks/qdox/TextBlocksTest.java
- src/test/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitorTest.java
Changes:
=====================================
pom.xml
=====================================
@@ -10,7 +10,7 @@
<name>QDox</name>
<groupId>com.thoughtworks.qdox</groupId>
<artifactId>qdox</artifactId>
- <version>2.0.0</version>
+ <version>2.0.1</version>
<url>https://github.com/paul-hammant/qdox</url>
<description>
@@ -36,7 +36,7 @@
<connection>scm:git:https://github.com/paul-hammant/qdox.git</connection>
<developerConnection>scm:git:ssh://git@github.com/paul-hammant/qdox.git</developerConnection>
<url>https://github.com/paul-hammant/qdox</url>
- <tag>qdox-2.0.0</tag>
+ <tag>qdox-2.0.1</tag>
</scm>
<developers>
@@ -209,8 +209,8 @@
</plugin>
<plugin>
<groupId>de.jflex</groupId>
- <artifactId>maven-jflex-plugin</artifactId>
- <version>1.4.3</version>
+ <artifactId>jflex-maven-plugin</artifactId>
+ <version>1.8.2</version>
<executions>
<execution>
<goals>
=====================================
src/grammar/lexer.flex
=====================================
@@ -20,6 +20,7 @@ package com.thoughtworks.qdox.parser.impl;
*/
import com.thoughtworks.qdox.parser.*;
+import java.io.InputStreamReader;
import java.util.*;
%%
@@ -167,6 +168,10 @@ import java.util.*;
this.writer = writer;
}
+ public JFlexLexer( java.io.InputStream stream ) {
+ this( new InputStreamReader(stream) );
+ }
+
public JFlexLexer( java.io.InputStream stream, java.io.Writer writer ) {
this( stream );
this.writer = writer;
@@ -199,7 +204,7 @@ Id = ([:jletter:]|{UnicodeChar}) ([:jletterdigit:]|{UnicodeChar})*
JavadocEnd = "*"+ "/"
%state JAVADOC JAVADOCTAG JAVADOCLINE CODEBLOCK PARENBLOCK ASSIGNMENT STRING CHAR SINGLELINECOMMENT MULTILINECOMMENT ANNOTATION ANNOSTRING ANNOCHAR ARGUMENTS NAME
-%state ANNOTATIONTYPE ENUM MODULE TYPE ANNOTATIONNOARG ATANNOTATION
+%state ANNOTATIONTYPE ENUM MODULE RECORD TYPE ANNOTATIONNOARG ATANNOTATION
%state NAME_OR_MODIFIER
%%
@@ -234,7 +239,7 @@ JavadocEnd = "*"+ "/"
<ANNOTATIONNOARG> {
{WhiteSpace} { popState(); }
}
-<YYINITIAL, ANNOTATIONNOARG, ANNOTATIONTYPE, ENUM, NAME, TYPE> {
+<YYINITIAL, ANNOTATIONNOARG, ANNOTATIONTYPE, ENUM, NAME, RECORD, TYPE> {
"." { return Parser.DOT; }
"..." { return Parser.DOTDOTDOT; }
"," { return Parser.COMMA; }
@@ -260,6 +265,10 @@ JavadocEnd = "*"+ "/"
"implements" { return Parser.IMPLEMENTS; }
"super" { return Parser.SUPER; }
"new" { return Parser.NEW; }
+ "record" { return Parser.RECORD; }
+ "sealed" { return Parser.SEALED; }
+ "non-sealed" { return Parser.NON_SEALED; }
+ "permits" { return Parser.PERMITS; }
"[" { nestingDepth++; return Parser.SQUAREOPEN; }
"]" { nestingDepth--; return Parser.SQUARECLOSE; }
@@ -421,7 +430,7 @@ JavadocEnd = "*"+ "/"
}
}
}
-<ENUM, TYPE> {
+<ENUM, RECORD, TYPE> {
"default" { return Parser.DEFAULT; }
}
<ANNOTATIONTYPE> {
@@ -432,7 +441,7 @@ JavadocEnd = "*"+ "/"
{Id} / {WhiteSpace}* [;{(] { resetAnnotatedElementLine(); popState(); return Parser.IDENTIFIER; }
{Id} { popState(); return Parser.IDENTIFIER; }
}
-<YYINITIAL, ANNOTATIONNOARG, ANNOTATIONTYPE, ENUM, MODULE, TYPE> {
+<YYINITIAL, ANNOTATIONNOARG, ANNOTATIONTYPE, ENUM, MODULE, RECORD, TYPE> {
{Id} { return Parser.IDENTIFIER;
}
}
@@ -471,6 +480,8 @@ JavadocEnd = "*"+ "/"
"[" { return Parser.SQUAREOPEN; }
"]" { return Parser.SQUARECLOSE; }
+ "->" { return Parser.ARROW; }
+
"," { return Parser.COMMA; }
"=" { return Parser.EQUALS; }
"*=" { return Parser.STAREQUALS; }
@@ -646,12 +657,12 @@ JavadocEnd = "*"+ "/"
}
}
-<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE, TYPE> {
+<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE, RECORD, TYPE> {
"\"" { if (appendingToCodeBody) { codeBody.append('"'); } pushState(STRING); }
\' { if (appendingToCodeBody) { codeBody.append('\''); } pushState(CHAR); }
}
-<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE, ANNOTATION, ATANNOTATION, ARGUMENTS, TYPE, NAME, MODULE > {
+<ASSIGNMENT, YYINITIAL, CODEBLOCK, PARENBLOCK, ENUM, ANNOTATIONTYPE, ANNOTATION, ATANNOTATION, ARGUMENTS, RECORD, TYPE, NAME, MODULE > {
"//" { if (appendingToCodeBody) { codeBody.append("//"); } pushState(SINGLELINECOMMENT); }
"/*" { if (appendingToCodeBody) { codeBody.append("/*"); } pushState(MULTILINECOMMENT); }
"/**/" { if (appendingToCodeBody) { codeBody.append("/**/"); } }
=====================================
src/grammar/parser.y
=====================================
@@ -28,11 +28,11 @@ import java.util.List;
import java.util.Stack;
%}
-%token SEMI DOT DOTDOTDOT COMMA STAR PERCENT EQUALS ANNOSTRING ANNOCHAR SLASH PLUS MINUS
+%token SEMI DOT DOTDOTDOT COMMA STAR PERCENT EQUALS ANNOSTRING ANNOCHAR SLASH PLUS MINUS ARROW
%token STAREQUALS SLASHEQUALS PERCENTEQUALS PLUSEQUALS MINUSEQUALS LESSTHAN2EQUALS GREATERTHAN2EQUALS GREATERTHAN3EQUALS AMPERSANDEQUALS CIRCUMFLEXEQUALS VERTLINEEQUALS
-%token PACKAGE IMPORT PUBLIC PROTECTED PRIVATE STATIC FINAL ABSTRACT NATIVE STRICTFP SYNCHRONIZED TRANSIENT VOLATILE DEFAULT
+%token PACKAGE IMPORT PUBLIC PROTECTED PRIVATE STATIC FINAL ABSTRACT NATIVE STRICTFP SYNCHRONIZED TRANSIENT VOLATILE DEFAULT SEALED NON_SEALED
%token OPEN MODULE REQUIRES TRANSITIVE EXPORTS OPENS TO USES PROVIDES WITH
-%token CLASS INTERFACE ENUM ANNOINTERFACE THROWS EXTENDS IMPLEMENTS SUPER DEFAULT NEW
+%token CLASS INTERFACE ENUM RECORD ANNOINTERFACE THROWS EXTENDS IMPLEMENTS SUPER DEFAULT NEW PERMITS
%token BRACEOPEN BRACECLOSE SQUAREOPEN SQUARECLOSE PARENOPEN PARENCLOSE
%token LESSTHAN GREATERTHAN LESSEQUALS GREATEREQUALS
%token LESSTHAN2 GREATERTHAN2 GREATERTHAN3
@@ -57,10 +57,10 @@ import java.util.Stack;
%token <sval> SUPER
%token <sval> EQUALS STAREQUALS SLASHEQUALS PERCENTEQUALS PLUSEQUALS MINUSEQUALS LESSTHAN2EQUALS GREATERTHAN2EQUALS GREATERTHAN3EQUALS AMPERSANDEQUALS CIRCUMFLEXEQUALS VERTLINEEQUALS
%type <type> PrimitiveType ReferenceType ArrayType ClassOrInterfaceType TypeVariable
-%type <annoval> Expression Literal Annotation ElementValue ElementValueArrayInitializer
+%type <annoval> Expression Literal Annotation ElementValue ElementValueArrayInitializer LambdaExpression
%type <annoval> ConditionalExpression ConditionalOrExpression ConditionalAndExpression InclusiveOrExpression ExclusiveOrExpression AndExpression
%type <annoval> EqualityExpression RelationalExpression ShiftExpression AdditiveExpression MultiplicativeExpression
-%type <annoval> UnaryExpression UnaryExpressionNotPlusMinus PreIncrementExpression PreDecrementExpression Primary PrimaryNoNewArray ArrayCreationExpression MethodInvocation MethodReference ClassInstanceCreationExpression
+%type <annoval> UnaryExpression UnaryExpressionNotPlusMinus PreIncrementExpression PreDecrementExpression Primary PrimaryNoNewArray ArrayCreationExpression MethodInvocation MethodReference ClassInstanceCreationExpression UnqualifiedClassInstanceCreationExpression
%type <annoval> PostfixExpression PostIncrementExpression PostDecrementExpression CastExpression Assignment LeftHandSide AssignmentExpression
%type <ival> Dims Dims_opt
%type <sval> QualifiedIdentifier TypeDeclSpecifier MethodBody AssignmentOperator ModuleName
@@ -68,7 +68,37 @@ import java.util.Stack;
%%
// Source: Java Language Specification - Third Edition
-// The Java(TM) Language Specification - Java SE 8 Edition ( Chapter 19. Syntax )
+// The Java(TM) Language Specification - Java SE 17 Edition ( Chapter 19. Syntax )
+//
+// Grammar Notation (Chapter 2.4)
+// The syntax {x} on the right-hand side of a production denotes zero or more occurrences of x.
+//
+// The syntax [x] on the right-hand side of a production denotes zero or one occurrences of x.
+// That is, x is an optional symbol. The alternative which contains the optional symbol actually defines two alternatives: one that omits the optional symbol and one that includes it.
+//
+// ** Transforming **
+// // Statement: {Key}
+// Statement: Keys_opt
+// ;
+//
+// // Key: value
+// Key: value
+// ;
+// Keys_opt:
+// | Keys_opt Key
+// ;
+//
+//
+// // Statement: [Key]
+// Statement: Key_opt
+// ;
+//
+// // Key: value
+// Key: value
+// ;
+// Key_opt:
+// | Key
+// ;
// ------------------------------
// Productions from �7 (Packages)
@@ -256,12 +286,14 @@ TypeDeclaration: ClassDeclaration
// ClassDeclaration:
// NormalClassDeclaration
// EnumDeclaration
+// RecordDeclaration
ClassDeclaration: NormalClassDeclaration
| EnumDeclaration
+ | RecordDeclaration
;
-// NormalClassDeclaration:
-// {ClassModifier} class Identifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody
+// NormalClassDeclaration:
+// {ClassModifier} class TypeIdentifier [TypeParameters] [ClassExtends] [ClassImplements] [ClassPermits] ClassBody
NormalClassDeclaration: Modifiers_opt CLASS IDENTIFIER
{
cls.setType(ClassDef.CLASS);
@@ -269,7 +301,7 @@ NormalClassDeclaration: Modifiers_opt CLASS IDENTIFIER
cls.getModifiers().addAll(modifiers); modifiers.clear();
cls.setName( $3 );
}
- TypeParameters_opt Superclass_opt Superinterfaces_opt
+ TypeParameters_opt Superclass_opt ClassImplements_opt ClassPermits_opt
{
cls.setTypeParameters(typeParams);
builder.beginClass(cls);
@@ -308,9 +340,9 @@ Superclass_opt:
}
;
-// Superinterfaces:
+// ClassImplements:
// implements InterfaceTypeList
-Superinterfaces_opt:
+ClassImplements_opt:
| IMPLEMENTS TypeList
{
cls.getImplements().addAll( typeList );
@@ -322,6 +354,14 @@ Superinterfaces_opt:
// InterfaceType {, InterfaceType}
//// -> InterfaceTypeList is for QDox the same as TypeList
+// ClassPermits:
+// permits TypeName {, TypeName}
+ClassPermits: PERMITS TypeList
+ ;
+ClassPermits_opt:
+ | ClassPermits
+ ;
+
// ClassBody:
// { { ClassBodyDeclaration } }
ClassBody: BRACEOPEN ClassBodyDeclarations_opt BRACECLOSE
@@ -609,7 +649,7 @@ ConstructorDeclaration: Modifiers_opt IDENTIFIER
// Primary . [TypeArguments] super ( [ArgumentList] ) ;
// EnumDeclaration:
-// {ClassModifier} enum Identifier [Superinterfaces] EnumBody
+// {ClassModifier} enum Identifier [ClassImplements] EnumBody
EnumDeclaration: Modifiers_opt ENUM IDENTIFIER
{
cls.setLineNumber(lexer.getLine());
@@ -620,7 +660,7 @@ EnumDeclaration: Modifiers_opt ENUM IDENTIFIER
cls = new ClassDef();
fieldType = new TypeDef($3, 0);
}
- Superinterfaces_opt EnumBody
+ ClassImplements_opt EnumBody
;
// EnumBody:
@@ -669,6 +709,38 @@ EnumBodyDeclarations_opt:
| SEMI ClassBodyDeclarations_opt
;
+// RecordDeclaration:
+// {ClassModifier} record TypeIdentifier [TypeParameters] RecordHeader [ClassImplements] RecordBody
+RecordDeclaration: Modifiers_opt RECORD IDENTIFIER TypeParameters_opt RecordHeader ClassImplements_opt RecordBody
+
+// RecordHeader:
+// ( [RecordComponentList] )
+RecordHeader: PARENOPEN RecordComponentList_opt PARENCLOSE
+
+// RecordComponentList:
+// RecordComponent {, RecordComponent}
+RecordComponentList: RecordComponentList COMMA RecordComponent
+ | RecordComponent
+ ;
+RecordComponentList_opt:
+ | RecordComponentList
+ ;
+
+// RecordComponent:
+// {RecordComponentModifier} UnannType Identifier
+// VariableArityRecordComponent
+RecordComponent: Annotations_opt /* ={RecordComponentModifier} */ Type /* =UnannType */ IDENTIFIER
+ | VariableArityRecordComponent
+ ;
+
+// VariableArityRecordComponent:
+// {RecordComponentModifier} UnannType {Annotation} ... Identifier
+VariableArityRecordComponent: Annotations_opt /* ={RecordComponentModifier} */ Type /* =UnannType */ DOTDOTDOT IDENTIFIER
+
+// RecordBody:
+// { {RecordBodyDeclaration} }
+RecordBody: CODEBLOCK
+
// -----------------------------
// Productions from �9 (Interfaces)
// -----------------------------
@@ -680,15 +752,15 @@ InterfaceDeclaration: NormalInterfaceDeclaration
| AnnotationTypeDeclaration
;
-// NormalInterfaceDeclaration:
-// {InterfaceModifier} interface Identifier [TypeParameters] [ExtendsInterfaces] InterfaceBody
+// NormalInterfaceDeclaration:
+// {InterfaceModifier} interface TypeIdentifier [TypeParameters] [InterfaceExtends] [InterfacePermits] InterfaceBody
NormalInterfaceDeclaration: Modifiers_opt INTERFACE
{
cls.setType(ClassDef.INTERFACE);
cls.setLineNumber(lexer.getLine());
cls.getModifiers().addAll(modifiers); modifiers.clear();
}
- IDENTIFIER TypeParameters_opt ExtendsInterfaces_opt
+ IDENTIFIER TypeParameters_opt InterfaceExtends_opt InterfacePermits_opt
{
cls.setName( $4 );
cls.setTypeParameters(typeParams);
@@ -703,16 +775,24 @@ NormalInterfaceDeclaration: Modifiers_opt INTERFACE
// ExtendsInterfaces:
// extends InterfaceTypeList
-ExtendsInterfaces: EXTENDS TypeList
+InterfaceExtends: EXTENDS TypeList
{
cls.getExtends().addAll( typeList );
typeList.clear();
}
;
-ExtendsInterfaces_opt:
- | ExtendsInterfaces
+InterfaceExtends_opt:
+ | InterfaceExtends
;
+// InterfacePermits:
+// permits TypeName {, TypeName}
+InterfacePermits: PERMITS TypeList
+ ;
+InterfacePermits_opt :
+ | InterfacePermits
+ ;
+
// InterfaceBody:
// { {InterfaceMemberDeclaration} }
// InterfaceMemberDeclaration:
@@ -933,24 +1013,30 @@ PrimaryNoNewArray: Literal
;
// ClassInstanceCreationExpression:
-// new [TypeArguments] {Annotation} Identifier [TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody]
-// ExpressionName . new [TypeArguments] {Annotation} Identifier [TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody]
-// Primary . new [TypeArguments] {Annotation} Identifier [TypeArgumentsOrDiamond] ( [ArgumentList] ) [ClassBody]
-//// TypeArguments_opt confuses parser
-ClassInstanceCreationExpression: NEW TypeArguments IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE CODEBLOCK_opt
- {
- CreatorDef creator = new CreatorDef();
- creator.setCreatedName( $3 );
- $$ = creator;
- }
- | NEW IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE CODEBLOCK_opt
- {
- CreatorDef creator = new CreatorDef();
- creator.setCreatedName( $2 );
- $$ = creator;
- }
+// UnqualifiedClassInstanceCreationExpression
+// ExpressionName . UnqualifiedClassInstanceCreationExpression
+// Primary . UnqualifiedClassInstanceCreationExpression
+ClassInstanceCreationExpression: UnqualifiedClassInstanceCreationExpression
+ | Primary DOT UnqualifiedClassInstanceCreationExpression
;
+// UnqualifiedClassInstanceCreationExpression:
+// new [TypeArguments] ClassOrInterfaceTypeToInstantiate ( [ArgumentList] ) [ClassBody]
+//// TypeArguments_opt confuses parser
+UnqualifiedClassInstanceCreationExpression: NEW TypeArguments IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE CODEBLOCK_opt
+ {
+ CreatorDef creator = new CreatorDef();
+ creator.setCreatedName( $3 );
+ $$ = creator;
+ }
+ | NEW IDENTIFIER TypeArgumentsOrDiamond_opt PARENOPEN ArgumentList_opt PARENCLOSE CODEBLOCK_opt
+ {
+ CreatorDef creator = new CreatorDef();
+ creator.setCreatedName( $2 );
+ $$ = creator;
+ }
+ ;
+
CODEBLOCK_opt:
| CODEBLOCK
;
@@ -1095,20 +1181,36 @@ DimExpr: SQUAREOPEN Expression SQUARECLOSE
// Expression:
// LambdaExpression
// AssignmentExpression
-Expression: AssignmentExpression
+Expression: LambdaExpression
+ | AssignmentExpression
;
// LambdaExpression:
// LambdaParameters -> LambdaBody
+LambdaExpression: LambdaParameters ARROW LambdaBody { $$ = new LambdaDef(); }
+ ;
+
// LambdaParameters:
// Identifier
// ( [FormalParameterList] )
// ( InferredFormalParameterList )
+LambdaParameters: IDENTIFIER
+ | PARENOPEN FormalParameterList_opt PARENCLOSE
+ | PARENOPEN InferredFormalParameterList PARENCLOSE
+ ;
+
// InferredFormalParameterList:
// Identifier {, Identifier}
+InferredFormalParameterList: InferredFormalParameterList COMMA IDENTIFIER
+ | IDENTIFIER
+ ;
+
// LambdaBody:
// Expression
// Block
+LambdaBody: Expression
+ | CODEBLOCK
+ ;
// AssignmentExpression:
// ConditionalExpression
@@ -1708,19 +1810,44 @@ TypeList: ReferenceType
Modifiers_opt:
| Modifiers_opt Modifier;
-// Modifier:
-// Annotation
-// public
-// protected
-// private
-// static
-// abstract
-// final
-// native
-// synchronized
-// transient
-// volatile
-// strictfp
+// AnnotationInterfaceElementModifier:
+// (one of)
+// Annotation public
+// abstract
+// ClassModifier:
+// (one of)
+// Annotation public protected private
+// abstract static final sealed non-sealed strictfp
+// ConstantModifier:
+// (one of)
+// Annotation public
+// static final
+// ConstructorModifier:
+// (one of)
+// Annotation public protected private
+// EnumConstantModifier:
+// Annotation
+// FieldModifier:
+// (one of)
+// Annotation public protected private
+// static final transient volatile
+// InterfaceModifier:
+// (one of)
+// Annotation public protected private
+// abstract static sealed non-sealed strictfp
+// InterfaceMethodModifier:
+// (one of)
+// Annotation public private
+// abstract default static strictfp
+// MethodModifier:
+// (one of)
+// Annotation public protected private
+// abstract static final synchronized native strictfp
+// RecordComponentModifier:
+// Annotation
+// VariableModifier:
+// Annotation
+// final
Modifier: Annotation
| PUBLIC
{
@@ -1734,6 +1861,10 @@ Modifier: Annotation
{
modifiers.add("private");
}
+ | ABSTRACT
+ {
+ modifiers.add("abstract");
+ }
| STATIC
{
modifiers.add("static");
@@ -1742,9 +1873,17 @@ Modifier: Annotation
{
modifiers.add("final");
}
- | ABSTRACT
+ | SEALED
{
- modifiers.add("abstract");
+ modifiers.add("sealed");
+ }
+ | NON_SEALED
+ {
+ modifiers.add("non-sealed");
+ }
+ | STRICTFP
+ {
+ modifiers.add("strictfp");
}
| NATIVE
{
@@ -1762,14 +1901,11 @@ Modifier: Annotation
{
modifiers.add("transient");
}
- | STRICTFP
- {
- modifiers.add("strictfp");
- }
| DEFAULT
{
modifiers.add("default");
}
+ |
;
Arguments_opt:
=====================================
src/main/java/com/thoughtworks/qdox/builder/impl/DefaultJavaAnnotationAssembler.java
=====================================
@@ -80,6 +80,7 @@ import com.thoughtworks.qdox.parser.expression.ExclusiveOrDef;
import com.thoughtworks.qdox.parser.expression.FieldRefDef;
import com.thoughtworks.qdox.parser.expression.GreaterEqualsDef;
import com.thoughtworks.qdox.parser.expression.GreaterThanDef;
+import com.thoughtworks.qdox.parser.expression.LambdaDef;
import com.thoughtworks.qdox.parser.expression.LessEqualsDef;
import com.thoughtworks.qdox.parser.expression.LessThanDef;
import com.thoughtworks.qdox.parser.expression.LogicalAndDef;
@@ -466,4 +467,9 @@ public class DefaultJavaAnnotationAssembler
{
return null;
}
+ @Override
+ public AnnotationValue transform( LambdaDef lambdaDef )
+ {
+ return null;
+ }
}
\ No newline at end of file
=====================================
src/main/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitor.java
=====================================
@@ -41,6 +41,7 @@ import com.thoughtworks.qdox.model.expression.ExpressionVisitor;
import com.thoughtworks.qdox.model.expression.FieldRef;
import com.thoughtworks.qdox.model.expression.GreaterEquals;
import com.thoughtworks.qdox.model.expression.GreaterThan;
+import com.thoughtworks.qdox.model.expression.Lambda;
import com.thoughtworks.qdox.model.expression.LessEquals;
import com.thoughtworks.qdox.model.expression.LessThan;
import com.thoughtworks.qdox.model.expression.LogicalAnd;
@@ -1025,4 +1026,10 @@ public class EvaluatingVisitor
{
throw new IllegalArgumentException( "Cannot evaluate '" + methodInvocation + "'." );
}
+
+ @Override
+ public Object visit( Lambda lambda )
+ {
+ throw new IllegalArgumentException( "Cannot evaluate '" + lambda + "'." );
+ }
}
\ No newline at end of file
=====================================
src/main/java/com/thoughtworks/qdox/model/expression/ExpressionVisitor.java
=====================================
@@ -103,4 +103,6 @@ public interface ExpressionVisitor
Object visit( MethodInvocation methodInvocation );
+ Object visit( Lambda lambda );
+
}
\ No newline at end of file
=====================================
src/main/java/com/thoughtworks/qdox/model/expression/FieldRef.java
=====================================
@@ -1,5 +1,7 @@
package com.thoughtworks.qdox.model.expression;
+import java.util.List;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -94,7 +96,15 @@ public class FieldRef
@Override
public String toString()
{
- return getName();
+ JavaField field = getField();
+ if ( field != null && !getDeclaringClass().equals( field.getDeclaringClass() ) )
+ {
+ return field.getDeclaringClass().getCanonicalName() + "." + field.getName();
+ }
+ else
+ {
+ return name;
+ }
}
public void setDeclaringClass( JavaClass declaringClass )
@@ -139,7 +149,7 @@ public class FieldRef
{
field = javaClass.getFieldByName( getNamePart( i ) );
- if ( field == null )
+ if ( field != null )
{
break;
}
@@ -178,6 +188,33 @@ public class FieldRef
}
}
}
+
+ if ( field == null )
+ {
+ ClassLibrary classLibrary = getClassLibrary();
+ if ( classLibrary != null )
+ {
+ List<String> imports = getDeclaringClass().getSource().getImports();
+ for ( String i : imports )
+ {
+ if ( i.startsWith( "static" ) )
+ {
+ String member = i.substring( i.lastIndexOf( '.' ) + 1 );
+ if ( "*".equals( member ) || getNamePrefix( 0 ).equals( member ) )
+ {
+ String className = i.substring( 7, i.lastIndexOf( '.' ) ).trim();
+ JavaClass javaClass = classLibrary.getJavaClass( className );
+ JavaField tmpField = javaClass.getFieldByName( member );
+ if ( tmpField != null && ( javaClass.isInterface() || tmpField.isStatic() ) )
+ {
+ field = tmpField;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
}
return field;
}
=====================================
src/main/java/com/thoughtworks/qdox/model/expression/Lambda.java
=====================================
@@ -0,0 +1,17 @@
+package com.thoughtworks.qdox.model.expression;
+
+public class Lambda implements AnnotationValue
+{
+ @Override
+ public Object getParameterValue()
+ {
+ return "";
+ }
+
+ @Override
+ public Object accept( ExpressionVisitor visitor )
+ {
+ return visitor.visit( this );
+ }
+
+}
=====================================
src/main/java/com/thoughtworks/qdox/parser/expression/ElemValueTransformer.java
=====================================
@@ -101,4 +101,6 @@ public interface ElemValueTransformer<U>
U transform( CreatorDef newCreator );
+ U transform( LambdaDef lambdaDef );
+
}
\ No newline at end of file
=====================================
src/main/java/com/thoughtworks/qdox/parser/expression/LambdaDef.java
=====================================
@@ -0,0 +1,29 @@
+package com.thoughtworks.qdox.parser.expression;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class LambdaDef extends ExpressionDef
+{
+ @Override
+ public <U> U transform( ElemValueTransformer<U> transformer )
+ {
+ return transformer.transform( this );
+ }
+}
=====================================
src/test/java/com/thoughtworks/qdox/JavaProjectBuilderTest.java
=====================================
@@ -1,6 +1,5 @@
package com.thoughtworks.qdox;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
@@ -1658,6 +1657,67 @@ public class JavaProjectBuilderTest extends TestCase
assertTrue( classA.getImplements().equals( Arrays.asList( builder.getClassByName( "Itf2" ) ) ) );
}
+ // Github #64
+ public void testGetInterface()
+ {
+ JavaProjectBuilder javaProjectBuilder = new JavaProjectBuilder();
+ javaProjectBuilder.addSourceTree( new File( "src/main/java" ) );
+ JavaClass intrfc = javaProjectBuilder.getClassByName( "org.thoughtworks.qdox.Searcher" );
+ assertNotNull(intrfc);
+
+ JavaClass clss = javaProjectBuilder.getClassByName( "org.thoughtworks.qdox.JavaProjectBuilder" );
+ assertNotNull(clss);
+ }
+
+ // github #73
+ public void testLambdaExpression() {
+ String source = "public enum GenerateType {"
+ + "ENTITY(\"entity\", (mojo, biConsumer) -> {} )"
+ + "}";
+
+ builder.addSource( new StringReader( source ) );
+ }
+
+ // github #75
+ public void testAnnotationWithConstant() {
+ String constantSource = "package com.xenoamess;\n"
+ + "public interface Constants {\n"
+ + " public String STATIC_STRING_A=\"SOME_VALUE\";" + "}";
+ builder.addSource( new StringReader( constantSource ) );
+
+ String source = "import static com.xenoamess.Constants.STATIC_STRING_A;\n"
+ + "\n" + "public class ClassA{\n"
+ + " @AnnotationA(annotationFieldA = STATIC_STRING_A)\n"
+ + " public void functionA(){\n" + " }\n"
+ + "}";
+ JavaMethod method =
+ builder.addSource( new StringReader( source ) ).getClassByName( "ClassA" ).getMethods().get( 0 );
+ assertEquals( "@AnnotationA(annotationFieldA=com.xenoamess.Constants.STATIC_STRING_A)\n",
+ method.getAnnotations().get( 0 ).getCodeBlock() );
+ }
+
+ // Github #76
+ public void testAtInComment() throws Exception
+ {
+ String source = "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ + "// source: model.proto\n"
+ + "\n"
+ + "public interface ModelOrBuilder {\n"
+ + " // @@protoc_insertion_point(interface_extends:Model)\n"
+ + "\n"
+ + " /**\n"
+ + " * <code>string name = 1;</code>\n"
+ + " */\n"
+ + " java.lang.String getName();\n"
+ + " /**\n"
+ + " * <code>string name = 1;</code>\n"
+ + " */\n"
+ + " String getNameBytes();\n"
+ + "}";
+ JavaClass clazz = builder.addSource( new StringReader( source ) ).getClassByName( "ModelOrBuilder" );
+ assertEquals( 0, clazz.getMethods().get( 0 ).getAnnotations().size() );
+ }
+
public void testGenericEnumMethod() throws Exception {
String source = "package java.time.temporal;\r\n" +
"public final class IsoFields {\r\n" +
=====================================
src/test/java/com/thoughtworks/qdox/RecordsTest.java
=====================================
@@ -0,0 +1,141 @@
+package com.thoughtworks.qdox;
+
+import java.io.StringReader;
+
+import org.junit.Test;
+
+/**
+ * Examples from <a href="https://docs.oracle.com/en/java/javase/16/language/records.html">https://docs.oracle.com/en/java/javase/16/language/records.html</a>
+ *
+ * @author Robert Scholte
+ */
+public class RecordsTest
+{
+ private JavaProjectBuilder builder = new JavaProjectBuilder();
+
+ @Test
+ public void withTwoFields() {
+ String source = "record Rectangle(double length, double width) { }";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withCanonicalConstructor() {
+ String source = "record Rectangle(double length, double width) {\n"
+ + " public Rectangle(double length, double width) {\n"
+ + " if (length <= 0 || width <= 0) {\n"
+ + " throw new java.lang.IllegalArgumentException(\n"
+ + " String.format(\"Invalid dimensions: %f, %f\", length, width));\n"
+ + " }\n"
+ + " this.length = length;\n"
+ + " this.width = width;\n"
+ + " }\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withCompactConstructor() {
+ String source = "record Rectangle(double length, double width) {\n"
+ + " public Rectangle {\n"
+ + " if (length <= 0 || width <= 0) {\n"
+ + " throw new java.lang.IllegalArgumentException(\n"
+ + " String.format(\"Invalid dimensions: %f, %f\", length, width));\n"
+ + " }\n"
+ + " }\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withPublicAccessorMethod() {
+ String source = "record Rectangle(double length, double width) {\n"
+ + " \n"
+ + " // Public accessor method\n"
+ + " public double length() {\n"
+ + " System.out.println(\"Length is \" + length);\n"
+ + " return length;\n"
+ + " }\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withStaticMembers() {
+ String source = "record Rectangle(double length, double width) {\n"
+ + " \n"
+ + " // Static field\n"
+ + " static double goldenRatio;\n"
+ + "\n"
+ + " // Static initializer\n"
+ + " static {\n"
+ + " goldenRatio = (1 + Math.sqrt(5)) / 2;\n"
+ + " }\n"
+ + "\n"
+ + " // Static method\n"
+ + " public static Rectangle createGoldenRectangle(double width) {\n"
+ + " return new Rectangle(width, width * goldenRatio);\n"
+ + " }\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withNonStaticMembers() {
+ String source = "record Rectangle(double length, double width) {\n"
+ + "\n"
+ + " // Field declarations must be static:\n"
+ + " BiFunction<Double, Double, Double> diagonal;\n"
+ + "\n"
+ + " // Instance initializers are not allowed in records:\n"
+ + " {\n"
+ + " diagonal = (x, y) -> Math.sqrt(x*x + y*y);\n"
+ + " }\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withNestedRecord() {
+ String source = "record Rectangle(double length, double width) {\n"
+ + "\n"
+ + " // Nested record class\n"
+ + " record RotationAngle(double angle) {\n"
+ + " public RotationAngle {\n"
+ + " angle = Math.toRadians(angle);\n"
+ + " }\n"
+ + " }\n"
+ + " \n"
+ + " // Public instance method\n"
+ + " public Rectangle getRotatedRectangleBoundingBox(double angle) {\n"
+ + " RotationAngle ra = new RotationAngle(angle);\n"
+ + " double x = Math.abs(length * Math.cos(ra.angle())) +\n"
+ + " Math.abs(width * Math.sin(ra.angle()));\n"
+ + " double y = Math.abs(length * Math.sin(ra.angle())) +\n"
+ + " Math.abs(width * Math.cos(ra.angle()));\n"
+ + " return new Rectangle(x, y);\n"
+ + " }\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withGenerics() {
+ String source = "record Triangle<C extends Coordinate> (C top, C left, C right) { }";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withInterface() {
+ String source = "record Customer(String... data) implements Billable { }";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void withAnnotatedParameters() {
+ String source = "record Rectangle(\n"
+ + " @GreaterThanZero double length,\n"
+ + " @GreaterThanZero double width) { }";
+ builder.addSource( new StringReader(source) );
+ }
+}
=====================================
src/test/java/com/thoughtworks/qdox/SealedClassesTest.java
=====================================
@@ -0,0 +1,42 @@
+package com.thoughtworks.qdox;
+
+import java.io.StringReader;
+
+import org.junit.Test;
+
+/**
+ * Examples from <a href="https://docs.oracle.com/en/java/javase/16/language/sealed-classes-and-interfaces.html">https://docs.oracle.com/en/java/javase/16/language/sealed-classes-and-interfaces.html</a>
+ * @author Robert Scholte
+ */
+public class SealedClassesTest
+{
+ private JavaProjectBuilder builder = new JavaProjectBuilder();
+
+ @Test
+ public void sealedClass() {
+ String source = "public sealed class Shape\r\n"
+ + " permits Circle, Square, Rectangle {\r\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void nonSealedClass() {
+ String source = "public non-sealed class Square extends Shape {\r\n"
+ + " public double side;\r\n"
+ + "}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void sealedInterface() {
+ String source = "public sealed interface Shape permits Polygon {}";
+ builder.addSource( new StringReader(source) );
+ }
+
+ @Test
+ public void nonSealedInterface() {
+ String source = "public non-sealed interface Polygon extends Shape { }";
+ builder.addSource( new StringReader(source) );
+ }
+}
=====================================
src/test/java/com/thoughtworks/qdox/TextBlocksTest.java
=====================================
@@ -0,0 +1,34 @@
+package com.thoughtworks.qdox;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.StringReader;
+
+import org.junit.Test;
+
+import com.thoughtworks.qdox.model.JavaField;
+import com.thoughtworks.qdox.model.JavaSource;
+
+/**
+ * Examples from <a href="https://docs.oracle.com/en/java/javase/16/text-blocks/index.html">https://docs.oracle.com/en/java/javase/16/text-blocks/index.html</a>
+ * @author Robert Scholte
+ *
+ */
+public class TextBlocksTest
+{
+ private JavaProjectBuilder builder = new JavaProjectBuilder();
+
+ @Test
+ public void test()
+ {
+ String source = "interface Something { "
+ + "// Using a text block\r\n"
+ + "String tbName = \"\"\"\r\n"
+ + " Pat Q. Smith\"\"\"; }";
+ JavaSource javaSource = builder.addSource( new StringReader( source ) );
+ JavaField javaField = javaSource.getClasses().get( 0 ).getFieldByName( "tbName" );
+ assertEquals( "\"\"\"\r\n"
+ + " Pat Q. Smith\"\"\"", javaField.getInitializationExpression() );
+ }
+
+}
=====================================
src/test/java/com/thoughtworks/qdox/builder/impl/EvaluatingVisitorTest.java
=====================================
@@ -493,11 +493,10 @@ public class EvaluatingVisitorTest
}
JavaField nonStaticNonFinalfield = mock( JavaField.class );
-
JavaClass declaringClass = mock( JavaClass.class );
when( declaringClass.getFieldByName( "fieldname" ) ).thenReturn( nonStaticNonFinalfield );
+ when( nonStaticNonFinalfield.getDeclaringClass() ).thenReturn( declaringClass );
- JavaClass annotatedClass = mock( JavaClass.class );
ref.setDeclaringClass( declaringClass );
try
{
View it on GitLab: https://salsa.debian.org/java-team/qdox2/-/commit/31ddd89a986f0e32560506b911fb039d69c3e480
--
View it on GitLab: https://salsa.debian.org/java-team/qdox2/-/commit/31ddd89a986f0e32560506b911fb039d69c3e480
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20220620/bb031d75/attachment.htm>
More information about the pkg-java-commits
mailing list