7070import org .eclipse .jdt .core .dom .Annotation ;
7171import org .eclipse .jdt .core .dom .AnnotationTypeMemberDeclaration ;
7272import org .eclipse .jdt .core .dom .AnonymousClassDeclaration ;
73+ import org .eclipse .jdt .core .dom .Assignment ;
7374import org .eclipse .jdt .core .dom .Block ;
7475import org .eclipse .jdt .core .dom .CatchClause ;
7576import org .eclipse .jdt .core .dom .ChildListPropertyDescriptor ;
@@ -687,6 +688,13 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
687688 if (!fieldAccessType .isRecovered ()) {
688689 processMembers (fieldAccess , fieldAccessExpr .resolveTypeBinding (), specificCompletionBindings , false );
689690 publishFromScope (specificCompletionBindings );
691+ if (fieldAccessExpr instanceof ThisExpression ) {
692+ // this.new can be used to instantiate non-static inner classes
693+ // eg. MyInner myInner = this.new MyInner(12);
694+ if (CharOperation .prefixEquals (this .prefix .toCharArray (), Keywords .NEW )) {
695+ this .requestor .accept (createKeywordProposal (Keywords .NEW , -1 , -1 ));
696+ }
697+ }
690698 IVariableBinding variableToCast = null ;
691699 if (fieldAccessExpr instanceof Name name && name .resolveBinding () instanceof IVariableBinding variableBinding ) {
692700 variableToCast = variableBinding ;
@@ -1011,6 +1019,8 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
10111019 // }
10121020 ITypeBinding typeDeclBinding = typeDecl .resolveBinding ();
10131021 findOverridableMethods (typeDeclBinding , this .javaProject , null );
1022+ suggestTypeKeywords (true );
1023+ suggestModifierKeywords (0 );
10141024 }
10151025 }
10161026 suggestDefaultCompletions = false ;
@@ -1843,14 +1853,29 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
18431853 }
18441854 if (context instanceof SwitchStatement || context instanceof SwitchExpression ) {
18451855 boolean hasDefault = false ;
1856+ boolean afterLabel = false ;
18461857 if (context instanceof SwitchStatement switchStatement ) {
1847- hasDefault = switchStatement .statements ().stream ().anyMatch (statement -> {
1848- return statement instanceof SwitchCase switchCase && switchCase .isDefault ();
1849- });
1858+ for (Statement statement : (List <Statement >)switchStatement .statements ()) {
1859+ if (statement instanceof SwitchCase switchCase ) {
1860+ if (switchCase .isDefault ()) {
1861+ hasDefault = true ;
1862+ }
1863+ if (switchCase .getStartPosition () < this .offset ) {
1864+ afterLabel = true ;
1865+ }
1866+ }
1867+ }
18501868 } else {
1851- hasDefault = ((SwitchExpression )context ).statements ().stream ().anyMatch (statement -> {
1852- return statement instanceof SwitchCase switchCase && switchCase .isDefault ();
1853- });
1869+ for (Statement statement : (List <Statement >)((SwitchExpression )context ).statements ()) {
1870+ if (statement instanceof SwitchCase switchCase ) {
1871+ if (switchCase .isDefault ()) {
1872+ hasDefault = true ;
1873+ }
1874+ if (switchCase .getStartPosition () < this .offset ) {
1875+ afterLabel = true ;
1876+ }
1877+ }
1878+ }
18541879 }
18551880 if (!this .isFailedMatch (this .prefix .toCharArray (), Keywords .CASE )) {
18561881 this .requestor .accept (createKeywordProposal (Keywords .CASE , -1 , -1 ));
@@ -1860,6 +1885,10 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
18601885 this .requestor .accept (createKeywordProposal (Keywords .DEFAULT , -1 , -1 ));
18611886 }
18621887 }
1888+ if (!afterLabel ) {
1889+ // case or default label required before regular body statements
1890+ suggestDefaultCompletions = false ;
1891+ }
18631892 }
18641893 if (context != null && context .getLocationInParent () == QualifiedType .NAME_PROPERTY && context .getParent () instanceof QualifiedType qType ) {
18651894 Type qualifier = qType .getQualifier ();
@@ -2860,9 +2889,19 @@ private void checkCancelled() {
28602889
28612890 private void statementLikeKeywords () {
28622891 List <char []> keywords = new ArrayList <>();
2863- boolean isExpressionExpected = (this .toComplete .getParent () instanceof IfStatement ifStatement
2892+ boolean isExpressionExpected =
2893+ (this .toComplete .getParent () instanceof IfStatement ifStatement
28642894 && (IfStatement .EXPRESSION_PROPERTY .getId ().equals (this .toComplete .getLocationInParent ().getId ())
2865- || "$missing$" .equals (ifStatement .getExpression ().toString ())));
2895+ || "$missing$" .equals (ifStatement .getExpression ().toString ())))
2896+ ||
2897+ (this .toComplete .getParent () instanceof WhileStatement whileStatement
2898+ && (WhileStatement .EXPRESSION_PROPERTY .getId ().equals (this .toComplete .getLocationInParent ().getId ())
2899+ || "$missing$" .equals (whileStatement .getExpression ().toString ())))
2900+ ||
2901+ (this .toComplete .getParent () instanceof Assignment )
2902+ ||
2903+ (this .toComplete instanceof Assignment )
2904+ ;
28662905 if (!isExpressionExpected ) {
28672906 keywords .add (Keywords .ASSERT );
28682907 keywords .add (Keywords .RETURN );
@@ -2874,8 +2913,14 @@ private void statementLikeKeywords() {
28742913 keywords .add (Keywords .SYNCHRONIZED );
28752914 keywords .add (Keywords .THROW );
28762915 keywords .add (Keywords .TRY );
2916+ keywords .add (Keywords .FINAL );
28772917 }
28782918 keywords .add (Keywords .SUPER );
2919+ keywords .add (Keywords .NEW );
2920+
2921+ if (!this .expectedTypes .getExpectedTypes ().isEmpty ()) {
2922+ keywords .add (Keywords .NULL );
2923+ }
28792924 if (DOMCompletionUtil .findParent (this .toComplete ,
28802925 new int [] { ASTNode .WHILE_STATEMENT , ASTNode .DO_STATEMENT , ASTNode .FOR_STATEMENT }) != null ) {
28812926 if (!isExpressionExpected ) {
@@ -2919,6 +2964,19 @@ private void statementLikeKeywords() {
29192964 this .requestor .accept (createKeywordProposal (keyword , this .toComplete .getStartPosition (), this .offset ));
29202965 }
29212966 }
2967+ // Z means boolean
2968+ if (this .expectedTypes .getExpectedTypes ().stream ().anyMatch (type -> "Z" .equals (type .getKey ()))) {
2969+ if (!isFailedMatch (this .prefix .toCharArray (), Keywords .TRUE )) {
2970+ CompletionProposal completionProposal = createKeywordProposal (Keywords .TRUE , this .toComplete .getStartPosition (), this .offset );
2971+ completionProposal .setRelevance (completionProposal .getRelevance () + RelevanceConstants .R_EXACT_EXPECTED_TYPE + RelevanceConstants .R_UNQUALIFIED );
2972+ this .requestor .accept (completionProposal );
2973+ }
2974+ if (!isFailedMatch (this .prefix .toCharArray (), Keywords .FALSE )) {
2975+ CompletionProposal completionProposal = createKeywordProposal (Keywords .FALSE , this .toComplete .getStartPosition (), this .offset );
2976+ completionProposal .setRelevance (completionProposal .getRelevance () + RelevanceConstants .R_EXACT_EXPECTED_TYPE + RelevanceConstants .R_UNQUALIFIED );
2977+ this .requestor .accept (completionProposal );
2978+ }
2979+ }
29222980 }
29232981
29242982 private void completeJavadocBlockTags (TagElement tagNode ) {
0 commit comments