Changeset 876
- Timestamp:
- 10/22/07 22:32:59 (1 year ago)
- Files:
-
- trunk/descent.core/src/descent/internal/codeassist/CompletionEngine.java (modified) (8 diffs)
- trunk/descent.core/src/descent/internal/codeassist/complete/CompletionOnCaseStatement.java (added)
- trunk/descent.core/src/descent/internal/codeassist/complete/CompletionParser.java (modified) (5 diffs)
- trunk/descent.core/src/descent/internal/compiler/parser/CaseStatement.java (modified) (4 diffs)
- trunk/descent.core/src/descent/internal/compiler/parser/ErrorExp.java (added)
- trunk/descent.core/src/descent/internal/compiler/parser/GotoStatement.java (modified) (2 diffs)
- trunk/descent.core/src/descent/internal/compiler/parser/Parser.java (modified) (5 diffs)
- trunk/descent.tests/descent/tests/assist/CompletionOnCaseStatement.java (added)
- trunk/descent.tests/descent/tests/mars/Bugs_Test.java (modified) (1 diff)
- trunk/descent.ui/src/descent/ui/text/java/CompletionProposalLabelProvider.java (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/descent.core/src/descent/internal/codeassist/CompletionEngine.java
r875 r876 4 4 import java.util.Map; 5 5 6 import descent.core.CompletionContext; 6 7 import descent.core.CompletionProposal; 7 8 import descent.core.CompletionRequestor; … … 13 14 import descent.internal.codeassist.complete.CompletionOnArgumentName; 14 15 import descent.internal.codeassist.complete.CompletionOnBreakStatement; 16 import descent.internal.codeassist.complete.CompletionOnCaseStatement; 15 17 import descent.internal.codeassist.complete.CompletionOnContinueStatement; 16 18 import descent.internal.codeassist.complete.CompletionOnGotoStatement; … … 25 27 import descent.internal.compiler.parser.ASTDmdNode; 26 28 import descent.internal.compiler.parser.Argument; 29 import descent.internal.compiler.parser.CaseStatement; 30 import descent.internal.compiler.parser.CastExp; 27 31 import descent.internal.compiler.parser.ClassDeclaration; 28 32 import descent.internal.compiler.parser.CompoundStatement; 33 import descent.internal.compiler.parser.Dsymbol; 29 34 import descent.internal.compiler.parser.EnumDeclaration; 35 import descent.internal.compiler.parser.EnumMember; 36 import descent.internal.compiler.parser.ErrorExp; 37 import descent.internal.compiler.parser.Expression; 30 38 import descent.internal.compiler.parser.FuncDeclaration; 31 39 import descent.internal.compiler.parser.FuncLiteralDeclaration; … … 40 48 import descent.internal.compiler.parser.Statement; 41 49 import descent.internal.compiler.parser.StructDeclaration; 50 import descent.internal.compiler.parser.SwitchStatement; 42 51 import descent.internal.compiler.parser.TemplateDeclaration; 43 52 import descent.internal.compiler.parser.Type; 53 import descent.internal.compiler.parser.TypeEnum; 44 54 import descent.internal.compiler.parser.TypeFunction; 45 55 import descent.internal.compiler.parser.UnionDeclaration; 46 56 import descent.internal.compiler.parser.UnitTestDeclaration; 57 import descent.internal.compiler.parser.VarDeclaration; 58 import descent.internal.compiler.parser.VarExp; 47 59 import descent.internal.compiler.parser.VersionCondition; 48 60 import descent.internal.compiler.parser.ast.AstVisitorAdapter; … … 158 170 ASTDmdNode assistNode = parser.getAssistNode(); 159 171 172 this.requestor.acceptContext(buildContext()); 173 160 174 // First the assist node 161 175 if (assistNode != null) { … … 183 197 CompletionOnVersionCondition node = (CompletionOnVersionCondition) assistNode; 184 198 completeVersionCondition(node); 199 } else if (assistNode instanceof CompletionOnCaseStatement) { 200 CompletionOnCaseStatement node = (CompletionOnCaseStatement) assistNode; 201 completeCaseStatement(node); 185 202 } 186 203 } … … 195 212 } 196 213 } 197 214 } catch (Exception e) { 215 e.printStackTrace(); 198 216 } finally { 199 217 this.requestor.endReporting(); 200 218 } 219 } 220 221 private CompletionContext buildContext() { 222 // TODO Descent completion context 223 CompletionContext context = new CompletionContext(); 224 context.setOffset(this.offset); 225 return context; 201 226 } 202 227 … … 405 430 proposal.setName(id); 406 431 proposal.setCompletion(id); 432 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 433 CompletionEngine.this.requestor.accept(proposal); 434 } 435 } 436 } 437 438 private void completeCaseStatement(CompletionOnCaseStatement node) { 439 doSemantic(module); 440 441 // Check to see if the condition is an enum, and suggest 442 // the members of it 443 SwitchStatement sw = node.sw; 444 if (sw == null) { 445 return; 446 } 447 448 // TODO maybe make each node implement something like 449 // "findEnumDeclaration" 450 TypeEnum typeEnum; 451 452 Expression condition = sw.condition; 453 if (condition == null) { 454 return; 455 } else if (condition instanceof VarExp) { 456 VarExp var = (VarExp) condition; 457 Type type = var.type; 458 if (type == null || !(type instanceof TypeEnum)) { 459 return; 460 } 461 462 typeEnum = (TypeEnum) type; 463 } else if (condition instanceof CastExp) { 464 CastExp castExp = (CastExp) condition; 465 if (castExp.e1 == null || !(castExp.e1 instanceof VarExp)) { 466 return; 467 } 468 469 VarExp varExp = (VarExp) castExp.e1; 470 if (varExp.var == null || !(varExp.var instanceof VarDeclaration)) { 471 return; 472 } 473 474 VarDeclaration varDeclaration = (VarDeclaration) varExp.var; 475 if (varDeclaration.type == null || !(varDeclaration.type instanceof TypeEnum)) { 476 return; 477 } 478 479 typeEnum = (TypeEnum) varDeclaration.type; 480 } else { 481 return; 482 } 483 484 EnumDeclaration enumDeclaration = typeEnum.sym; 485 if (enumDeclaration == null) { 486 return; 487 } 488 489 if (enumDeclaration.members == null) { 490 return; 491 } 492 493 char[] name; 494 Expression caseExp = node.originalExpression; 495 if (caseExp instanceof ErrorExp) { 496 name = CharOperation.NO_CHAR; 497 this.startPosition = this.actualCompletionPosition; 498 this.endPosition = this.actualCompletionPosition; 499 } else if (caseExp instanceof IdentifierExp) { 500 IdentifierExp idExp = (IdentifierExp) caseExp; 501 name = idExp.ident; 502 this.startPosition = idExp.start; 503 this.endPosition = this.actualCompletionPosition; 504 } else { 505 return; 506 } 507 508 HashtableOfCharArrayAndObject excludedNames = new HashtableOfCharArrayAndObject(); 509 if (sw.cases != null) { 510 for(Object caseObject : sw.cases) { 511 CaseStatement caseStatement = (CaseStatement) caseObject; 512 Expression exp = caseStatement.sourceExp; 513 if (exp != null) { 514 excludedNames.put(exp.toCharArray(), this); 515 } 516 } 517 } 518 519 for(Dsymbol symbol : enumDeclaration.members) { 520 if (!(symbol instanceof EnumMember)) { 521 continue; 522 } 523 524 EnumMember member = (EnumMember) symbol; 525 526 char[] proposition = CharOperation.concat(enumDeclaration.ident.ident, member.ident.ident, '.'); 527 if (!excludedNames.containsKey(proposition) && 528 CharOperation.prefixEquals(name, proposition, false)) { 529 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 530 proposal.setName(proposition); 531 proposal.setCompletion(proposition); 407 532 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 408 533 CompletionEngine.this.requestor.accept(proposal); trunk/descent.core/src/descent/internal/codeassist/complete/CompletionParser.java
r874 r876 2 2 3 3 import java.util.ArrayList; 4 import java.util.Collections; 4 5 import java.util.List; 5 6 … … 8 9 import descent.internal.compiler.parser.Argument; 9 10 import descent.internal.compiler.parser.BreakStatement; 11 import descent.internal.compiler.parser.CaseStatement; 10 12 import descent.internal.compiler.parser.Chars; 11 13 import descent.internal.compiler.parser.ContinueStatement; 14 import descent.internal.compiler.parser.ErrorExp; 12 15 import descent.internal.compiler.parser.Expression; 13 16 import descent.internal.compiler.parser.GotoStatement; … … 20 23 import descent.internal.compiler.parser.ModuleDeclaration; 21 24 import descent.internal.compiler.parser.Parser; 25 import descent.internal.compiler.parser.Statement; 22 26 import descent.internal.compiler.parser.TOK; 23 27 import descent.internal.compiler.parser.Type; … … 46 50 47 51 public List<ICompletionOnKeyword> getKeywordCompletions() { 48 return keywordCompletions; 52 if (includeExpectations) { 53 return keywordCompletions; 54 } else { 55 return Collections.EMPTY_LIST; 56 } 49 57 } 50 58 … … 190 198 } 191 199 200 @Override 201 protected CaseStatement newCaseStatement(Loc loc, Expression exp, Statement statement, int caseEnd, int expStart, int expLength) { 202 // exp.start is -1 if it's an error expression 203 if (caseEnd <= cursorLocation && cursorLocation <= expStart + expLength && exp != null && (exp instanceof ErrorExp || 204 (exp.getNodeType() == ASTDmdNode.IDENTIFIER_EXP))) { 205 includeExpectations = false; 206 207 assistNode = new CompletionOnCaseStatement(loc, exp, statement); 208 return (CaseStatement) assistNode; 209 } else { 210 return super.newCaseStatement(loc, exp, statement, caseEnd, expStart, expLength); 211 } 212 } 213 192 214 private boolean inCompletion() { 193 215 return prevToken.ptr + prevToken.sourceLen <= cursorLocation && cursorLocation <= token.ptr + token.sourceLen trunk/descent.core/src/descent/internal/compiler/parser/CaseStatement.java
r847 r876 12 12 public Expression exp, sourceExp; 13 13 public Statement statement, sourceStatement; 14 15 public SwitchStatement sw; // descent 14 16 15 17 public CaseStatement(Loc loc, Expression exp, Statement s) { … … 78 80 public Statement semantic(Scope sc, SemanticContext context) { 79 81 SwitchStatement sw = sc.sw; 82 this.sw = sw; 80 83 81 84 exp = exp.semantic(sc, context); … … 120 123 } 121 124 125 public void setStatement(Statement s) { 126 this.statement = this.sourceStatement = s; 127 } 128 122 129 @Override 123 130 public Statement syntaxCopy() { … … 150 157 } 151 158 159 160 152 161 } trunk/descent.core/src/descent/internal/compiler/parser/GotoStatement.java
r860 r876 11 11 public LabelDsymbol label; 12 12 public TryFinallyStatement tf; 13 14 public FuncDeclaration fd; // descent: The parent function declaration after the first semantic pass is done15 13 16 14 public GotoStatement(Loc loc, IdentifierExp ident) { … … 58 56 @Override 59 57 public Statement semantic(Scope sc, SemanticContext context) { 60 FuncDeclaration fd = sc.parent.isFuncDeclaration();61 this.fd = fd; // descent62 tf = sc.tf;63 64 58 if (ident == null) { 65 // It's a broken node, it has already syntax errors, 66 // but assign fd and tf first 59 // It's a broken node, it has already syntax errors 67 60 return this; 68 61 } 69 62 63 FuncDeclaration fd = sc.parent.isFuncDeclaration(); 64 tf = sc.tf; 70 65 label = fd.searchLabel(ident); 71 66 if (null == label.statement && sc.fes != null) { trunk/descent.core/src/descent/internal/compiler/parser/Parser.java
r874 r876 4128 4128 Expression exp; 4129 4129 Statements statements; 4130 List cases = new ArrayList(); // array of Expression's 4130 // List cases = new ArrayList(); // array of Expression's 4131 4132 // Note: this code was changed a little from DMD to support 4133 // better code completion 4134 List<CaseStatement> caseStatements = new ArrayList<CaseStatement>(); 4131 4135 4132 4136 while (true) { 4137 int caseEnd = token.ptr + token.sourceLen; 4138 4133 4139 nextToken(); 4140 4141 int expStart = token.ptr; 4142 int expLength = token.sourceLen; 4143 4134 4144 exp = parseAssignExp(); 4135 cases.add(exp); 4136 if (token.value != TOKcomma) 4145 caseStatements.add(newCaseStatement(loc, exp, null, caseEnd, expStart, expLength)); 4146 // cases.add(exp); 4147 4148 if (token.value != TOKcomma) { 4137 4149 break; 4150 } 4138 4151 } 4139 4152 check(TOKcolon); … … 4142 4155 while (token.value != TOKcase && token.value != TOKdefault 4143 4156 && token.value != TOKrcurly) { 4157 4158 if (token.value == TOKeof) { 4159 break; 4160 } 4161 4144 4162 statements.add(parseStatement(PSsemi | PScurlyscope)); 4145 4163 } … … 4148 4166 4149 4167 /* 4168 FIXME this can bring incompatibilities between Descent and DMD: put back! 4150 4169 s = new ScopeStatement(s); 4151 4170 */ 4152 4171 4153 4172 // Keep cases in order by building the case statements backwards 4154 for (int i = cases.size(); i != 0; i--) { 4155 exp = (Expression) cases.get(i - 1); 4156 s = new CaseStatement(loc, exp, s); 4157 } 4173 // for (int i = cases.size(); i != 0; i--) { 4174 // exp = (Expression) cases.get(i - 1); 4175 // s = new CaseStatement(loc, exp, s); 4176 // } 4177 4178 for(int i = caseStatements.size(); i != 0; i--) { 4179 CaseStatement cs = caseStatements.get(i - 1); 4180 cs.setStatement(s); 4181 s = cs; 4182 } 4183 4158 4184 break; 4159 4185 } … … 5816 5842 // Lerr: 5817 5843 // Anything for e, as long as it's not NULL 5818 e = new IntegerExp(loc, Id.ZERO, 0, Type.tint32);5844 e = new ErrorExp(); 5819 5845 e.setSourceRange(token.ptr, token.sourceLen); 5820 5846 nextToken(); … … 7004 7030 } 7005 7031 7032 protected CaseStatement newCaseStatement(Loc loc, Expression exp, Statement statement, int caseEnd, int expStart, int expLength) { 7033 return new CaseStatement(loc, exp, statement); 7034 } 7035 7006 7036 /** 7007 7037 * The parser expects the current token to be trunk/descent.tests/descent/tests/mars/Bugs_Test.java
r797 r876 230 230 } 231 231 232 public void testCaseOpen() { 233 String s = "void foo() { switch(1) case "; 234 getCompilationUnit(s); 235 } 236 232 237 public void testDstress_run_t_typeof_16_A() { 233 238 String s = "char[] name = (typeof(o)).classinfo.name;"; trunk/descent.ui/src/descent/ui/text/java/CompletionProposalLabelProvider.java
r875 r876 369 369 StringBuffer buf= new StringBuffer(); 370 370 buf.append(proposal.getCompletion()); 371 /* TODO JDT code complete 371 372 char[] typeName= Signature.getSignatureSimpleName(proposal.getSignature()); 372 373 if (typeName.length > 0) { … … 382 383 } 383 384 } 384 385 */ 385 386 return buf.toString(); 386 387 } … … 544 545 545 546 ImageDescriptor createPackageImageDescriptor(CompletionProposal proposal) { 546 return decorateImageDescriptor(JavaPluginImages.DESC_OBJS_ PACKAGE, proposal);547 return decorateImageDescriptor(JavaPluginImages.DESC_OBJS_MODULE, proposal); 547 548 } 548 549
