4949import build .codemodel .jdk .descriptor .EnumType ;
5050import build .codemodel .jdk .descriptor .FieldInitializerDescriptor ;
5151import build .codemodel .jdk .descriptor .Final ;
52+ import build .codemodel .jdk .descriptor .ImportDeclaration ;
53+ import build .codemodel .jdk .descriptor .InitializerBlockDescriptor ;
5254import build .codemodel .jdk .descriptor .JDKClassTypeDescriptor ;
5355import build .codemodel .jdk .descriptor .JDKInterfaceTypeDescriptor ;
5456import build .codemodel .jdk .descriptor .JDKModuleDescriptor ;
5557import build .codemodel .jdk .descriptor .JDKTypeDescriptor ;
58+ import build .codemodel .jdk .descriptor .LocationTrait ;
59+ import build .codemodel .jdk .descriptor .MemberTypeDescriptor ;
5660import build .codemodel .jdk .descriptor .MethodBodyDescriptor ;
5761import build .codemodel .jdk .descriptor .MethodImplementationDescriptor ;
5862import build .codemodel .jdk .descriptor .RecordComponentDescriptor ;
5963import build .codemodel .jdk .descriptor .RecordType ;
6064import build .codemodel .jdk .descriptor .Static ;
65+ import build .codemodel .jdk .descriptor .Varargs ;
6166import build .codemodel .objectoriented .descriptor .AccessModifier ;
6267import build .codemodel .objectoriented .descriptor .Classification ;
6368import build .codemodel .objectoriented .descriptor .ConstructorDescriptor ;
6772import build .codemodel .objectoriented .descriptor .MethodDescriptor ;
6873import build .codemodel .objectoriented .descriptor .ParameterizedTypeDescriptor ;
6974import build .codemodel .objectoriented .naming .MethodName ;
75+ import com .sun .source .tree .BlockTree ;
7076import com .sun .source .tree .ClassTree ;
7177import com .sun .source .tree .CompilationUnitTree ;
7278import com .sun .source .tree .MethodTree ;
9096import java .util .Objects ;
9197import java .util .Optional ;
9298import java .util .stream .Collectors ;
99+ import java .util .stream .IntStream ;
93100import java .util .stream .Stream ;
94101import javax .lang .model .element .AnnotationMirror ;
95102import javax .lang .model .element .Element ;
@@ -340,10 +347,23 @@ private void processTypeElement(final TypeElement typeElement,
340347 typeDescriptor .addTrait (new EnclosingTypeDescriptor (resolveTypeName (enclosingElement )));
341348 }
342349
350+ if (classTree != null && cut != null ) {
351+ final var srcPositions = trees .getSourcePositions ();
352+ final var start = srcPositions .getStartPosition (cut , classTree );
353+ final var end = srcPositions .getEndPosition (cut , classTree );
354+ if (start != Diagnostic .NOPOS ) {
355+ typeDescriptor .addTrait (LocationTrait .of (cut .getSourceFile ().toUri (), start , end ));
356+ }
357+ }
358+
343359 addTypeParameters (typeDescriptor , typeElement );
344360 addModifiers (typeDescriptor , typeElement );
345361 addSuperclass (typeDescriptor , typeElement );
346362 addInterfaces (typeDescriptor , typeElement );
363+ addMemberTypes (typeDescriptor , typeElement );
364+ if (!(typeElement .getEnclosingElement () instanceof TypeElement )) {
365+ addImports (typeDescriptor , cut );
366+ }
347367 processMembers (typeDescriptor , typeElement , classTree , cut );
348368 if (typeElement .getKind () == ElementKind .RECORD ) {
349369 addRecordComponents (typeDescriptor , typeElement );
@@ -415,6 +435,36 @@ private void addInterfaces(final JDKTypeDescriptor typeDescriptor, final TypeEle
415435 }
416436 }
417437
438+ private void addMemberTypes (final JDKTypeDescriptor typeDescriptor , final TypeElement typeElement ) {
439+ typeElement .getEnclosedElements ().stream ()
440+ .filter (e -> e .getKind ().isClass () || e .getKind ().isInterface ())
441+ .map (TypeElement .class ::cast )
442+ .forEach (nested -> typeDescriptor .addTrait (new MemberTypeDescriptor (resolveTypeName (nested ))));
443+ }
444+
445+ private void addImports (final JDKTypeDescriptor typeDescriptor , final CompilationUnitTree cut ) {
446+ if (cut == null ) {
447+ return ;
448+ }
449+ final var imports = cut .getImports ();
450+ for (int i = 0 ; i < imports .size (); i ++) {
451+ final var importTree = imports .get (i );
452+ final var qualifiedId = importTree .getQualifiedIdentifier ().toString ();
453+ final boolean isStatic = importTree .isStatic ();
454+ final boolean isOnDemand = qualifiedId .endsWith (".*" );
455+ final var name = isOnDemand ? qualifiedId .substring (0 , qualifiedId .length () - 2 ) : qualifiedId ;
456+ if (isStatic && isOnDemand ) {
457+ typeDescriptor .addTrait (ImportDeclaration .ofStaticOnDemand (name , i ));
458+ } else if (isStatic ) {
459+ typeDescriptor .addTrait (ImportDeclaration .ofStatic (name , i ));
460+ } else if (isOnDemand ) {
461+ typeDescriptor .addTrait (ImportDeclaration .ofOnDemand (name , i ));
462+ } else {
463+ typeDescriptor .addTrait (ImportDeclaration .of (name , i ));
464+ }
465+ }
466+ }
467+
418468 private void processMembers (final JDKTypeDescriptor typeDescriptor ,
419469 final TypeElement typeElement ,
420470 final ClassTree classTree ,
@@ -426,6 +476,7 @@ private void processMembers(final JDKTypeDescriptor typeDescriptor,
426476 final var sortedMembers = classTree .getMembers ().stream ()
427477 .sorted (java .util .Comparator .comparingLong (m -> srcPositions .getStartPosition (cut , m )))
428478 .toList ();
479+ int enumConstantOrder = 0 ;
429480 for (final var member : sortedMembers ) {
430481 final var path = TreePath .getPath (cut , member );
431482 if (path == null ) {
@@ -434,25 +485,29 @@ private void processMembers(final JDKTypeDescriptor typeDescriptor,
434485 final var elem = trees .getElement (path );
435486 if (member instanceof VariableTree vt && elem instanceof VariableElement ve ) {
436487 if (ve .getKind () == ElementKind .FIELD ) {
437- processField (typeDescriptor , ve , vt , cut );
488+ processField (typeDescriptor , ve , vt , cut , srcPositions );
438489 } else if (ve .getKind () == ElementKind .ENUM_CONSTANT ) {
439490 final var name = nameProvider .getIrreducibleName (ve .getSimpleName ());
440- typeDescriptor .addTrait (EnumConstantDescriptor .of (name ));
491+ typeDescriptor .addTrait (EnumConstantDescriptor .of (name , enumConstantOrder ++ ));
441492 }
442493 } else if (member instanceof MethodTree mt && elem instanceof ExecutableElement ee ) {
443494 if (ee .getKind () == ElementKind .CONSTRUCTOR ) {
444495 processConstructor (typeDescriptor , ee , mt , cut , srcPositions );
445496 } else if (ee .getKind () == ElementKind .METHOD ) {
446- processMethod (typeDescriptor , ee , mt , cut );
497+ processMethod (typeDescriptor , ee , mt , cut , srcPositions );
447498 }
499+ } else if (member instanceof BlockTree bt ) {
500+ typeDescriptor .addTrait (
501+ new InitializerBlockDescriptor (bt .isStatic (), stmtConverter .convertStatements (bt .getStatements ())));
448502 }
449503 }
450504 }
451505
452506 private void processField (final JDKTypeDescriptor typeDescriptor ,
453507 final VariableElement fieldElement ,
454508 final VariableTree varTree ,
455- final CompilationUnitTree cut ) {
509+ final CompilationUnitTree cut ,
510+ final SourcePositions srcPositions ) {
456511 final var fieldName = nameProvider .getIrreducibleName (fieldElement .getSimpleName ());
457512 final var fieldType = resolveTypeUsage (fieldElement .asType (), fieldElement );
458513 final var fieldDescriptor = FieldDescriptor .of (codeModel , fieldName , fieldType );
@@ -466,6 +521,12 @@ private void processField(final JDKTypeDescriptor typeDescriptor,
466521 .map (mirror -> createAnnotationTypeUsage (fieldElement , mirror ))
467522 .forEach (fieldDescriptor ::addTrait );
468523
524+ final var start = srcPositions .getStartPosition (cut , varTree );
525+ final var end = srcPositions .getEndPosition (cut , varTree );
526+ if (start != Diagnostic .NOPOS ) {
527+ fieldDescriptor .addTrait (LocationTrait .of (cut .getSourceFile ().toUri (), start , end ));
528+ }
529+
469530 typeDescriptor .addTrait (fieldDescriptor );
470531
471532 if (varTree .getInitializer () != null ) {
@@ -496,6 +557,12 @@ private void processConstructor(final JDKTypeDescriptor typeDescriptor,
496557 .map (mirror -> createAnnotationTypeUsage (methodElement , mirror ))
497558 .forEach (constructorDescriptor ::addTrait );
498559
560+ final var start = srcPositions .getStartPosition (cut , ctorTree );
561+ final var end = srcPositions .getEndPosition (cut , ctorTree );
562+ if (start != Diagnostic .NOPOS ) {
563+ constructorDescriptor .addTrait (LocationTrait .of (cut .getSourceFile ().toUri (), start , end ));
564+ }
565+
499566 typeDescriptor .addTrait (constructorDescriptor );
500567
501568 if (ctorTree .getBody () != null ) {
@@ -512,15 +579,19 @@ private void processConstructor(final JDKTypeDescriptor typeDescriptor,
512579
513580 private Stream <FormalParameterDescriptor > getFormalParameters (final ExecutableElement methodElement ) {
514581 final var params = methodElement .getParameters ();
515- return params .stream ().map (variableElement -> {
516- final var param = variableElement ;
582+ final int lastIdx = params .size () - 1 ;
583+ return IntStream .range (0 , params .size ()).mapToObj (i -> {
584+ final var param = params .get (i );
517585 final var pd = FormalParameterDescriptor .of (
518586 codeModel ,
519587 Optional .of (nameProvider .getIrreducibleName (param .getSimpleName ())),
520588 resolveTypeUsage (param .asType (), param ));
521589 if (param .getModifiers ().contains (Modifier .FINAL )) {
522590 pd .addTrait (Final .FINAL );
523591 }
592+ if (methodElement .isVarArgs () && i == lastIdx ) {
593+ pd .addTrait (Varargs .VARARGS );
594+ }
524595 param .getAnnotationMirrors ().stream ()
525596 .map (mirror -> createAnnotationTypeUsage (param , mirror ))
526597 .forEach (pd ::addTrait );
@@ -531,7 +602,8 @@ private Stream<FormalParameterDescriptor> getFormalParameters(final ExecutableEl
531602 private void processMethod (final JDKTypeDescriptor typeDescriptor ,
532603 final ExecutableElement methodElement ,
533604 final MethodTree methodTree ,
534- final CompilationUnitTree cut ) {
605+ final CompilationUnitTree cut ,
606+ final SourcePositions srcPositions ) {
535607 final var methodSimpleName = nameProvider .getIrreducibleName (methodElement .getSimpleName ());
536608 final var returnType = resolveTypeUsage (methodElement .getReturnType (), methodElement );
537609 final var methodName = MethodName .of (
@@ -572,6 +644,12 @@ private void processMethod(final JDKTypeDescriptor typeDescriptor,
572644 .map (mirror -> createAnnotationTypeUsage (methodElement , mirror ))
573645 .forEach (methodDescriptor ::addTrait );
574646
647+ final var start = srcPositions .getStartPosition (cut , methodTree );
648+ final var end = srcPositions .getEndPosition (cut , methodTree );
649+ if (start != Diagnostic .NOPOS ) {
650+ methodDescriptor .addTrait (LocationTrait .of (cut .getSourceFile ().toUri (), start , end ));
651+ }
652+
575653 typeDescriptor .addTrait (methodDescriptor );
576654
577655 if (methodTree .getBody () != null ) {
0 commit comments