Changeset 869
- Timestamp:
- 10/21/07 22:23:18 (1 year ago)
- Files:
-
- trunk/descent.core/src/descent/internal/codeassist/CompletionEngine.java (modified) (9 diffs)
- trunk/descent.core/src/descent/internal/codeassist/complete/CompletionOnBreakStatement.java (added)
- trunk/descent.core/src/descent/internal/codeassist/complete/CompletionOnContinueStatement.java (added)
- trunk/descent.core/src/descent/internal/codeassist/complete/CompletionParser.java (modified) (2 diffs)
- trunk/descent.core/src/descent/internal/compiler/parser/Parser.java (modified) (6 diffs)
- trunk/descent.core/src/descent/internal/compiler/parser/VarDeclaration.java (modified) (1 diff)
- trunk/descent.tests/descent/tests/assist/AbstractCompletionOnBreakContinueStatement_Test.java (added)
- trunk/descent.tests/descent/tests/assist/CompletionOnBreakStatement_Test.java (added)
- trunk/descent.tests/descent/tests/assist/CompletionOnContinueStatement_Test.java (added)
- trunk/descent.tests/descent/tests/assist/CompletionOnGotoStatement_Test.java (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/descent.core/src/descent/internal/codeassist/CompletionEngine.java
r861 r869 12 12 import descent.core.dom.AST; 13 13 import descent.internal.codeassist.complete.CompletionOnArgumentName; 14 import descent.internal.codeassist.complete.CompletionOnBreakStatement; 15 import descent.internal.codeassist.complete.CompletionOnContinueStatement; 14 16 import descent.internal.codeassist.complete.CompletionOnGotoStatement; 15 17 import descent.internal.codeassist.complete.CompletionOnImport; … … 23 25 import descent.internal.compiler.parser.Argument; 24 26 import descent.internal.compiler.parser.ClassDeclaration; 27 import descent.internal.compiler.parser.CompoundStatement; 25 28 import descent.internal.compiler.parser.EnumDeclaration; 26 29 import descent.internal.compiler.parser.FuncDeclaration; 30 import descent.internal.compiler.parser.FuncLiteralDeclaration; 27 31 import descent.internal.compiler.parser.Global; 28 32 import descent.internal.compiler.parser.HashtableOfCharArrayAndObject; 33 import descent.internal.compiler.parser.IdentifierExp; 29 34 import descent.internal.compiler.parser.InterfaceDeclaration; 35 import descent.internal.compiler.parser.InvariantDeclaration; 30 36 import descent.internal.compiler.parser.LabelStatement; 31 37 import descent.internal.compiler.parser.Module; 32 38 import descent.internal.compiler.parser.SemanticContext; 39 import descent.internal.compiler.parser.Statement; 33 40 import descent.internal.compiler.parser.StructDeclaration; 34 41 import descent.internal.compiler.parser.TemplateDeclaration; … … 36 43 import descent.internal.compiler.parser.TypeFunction; 37 44 import descent.internal.compiler.parser.UnionDeclaration; 45 import descent.internal.compiler.parser.UnitTestDeclaration; 38 46 import descent.internal.compiler.parser.ast.AstVisitorAdapter; 39 47 import descent.internal.compiler.util.HashtableOfObject; … … 163 171 } else if (assistNode instanceof CompletionOnGotoStatement) { 164 172 CompletionOnGotoStatement node = (CompletionOnGotoStatement) assistNode; 165 completeGotoStatement(node); 173 completeGotoBreakOrContinueStatement(node.ident, false /* don't check in loop */); 174 } else if (assistNode instanceof CompletionOnBreakStatement) { 175 CompletionOnBreakStatement node = (CompletionOnBreakStatement) assistNode; 176 completeGotoBreakOrContinueStatement(node.ident, true /* check in loop */); 177 } else if (assistNode instanceof CompletionOnContinueStatement) { 178 CompletionOnContinueStatement node = (CompletionOnContinueStatement) assistNode; 179 completeGotoBreakOrContinueStatement(node.ident, true /* check in loop */); 166 180 } 167 181 } … … 242 256 243 257 private void completeArgumentName(CompletionOnArgumentName node) { 244 char[] name; 245 if (node.ident == null || node.ident.ident == null) { 246 this.startPosition = this.actualCompletionPosition; 247 this.endPosition = this.actualCompletionPosition; 248 name = CharOperation.NO_CHAR; 249 } else { 250 this.startPosition = node.ident.start; 251 this.endPosition = node.ident.start + node.ident.length; 252 name = node.ident.ident; 253 } 254 258 char[] name = computePrefixAndSourceRange(node.ident); 255 259 findVariableNames(name, node.type, findExcludedNames(node)); 256 260 } 257 261 258 private void completeGoto Statement(CompletionOnGotoStatement node) {262 private void completeGotoBreakOrContinueStatement(IdentifierExp ident, final boolean inLoop) { 259 263 final HashtableOfCharArrayAndObject labelsMap = new HashtableOfCharArrayAndObject(); 260 264 module.accept(new AstVisitorAdapter() { … … 264 268 @Override 265 269 public boolean visit(FuncDeclaration node) { 270 return visitFunc(node); 271 } 272 273 @Override 274 public boolean visit(UnitTestDeclaration node) { 275 return visitFunc(node); 276 } 277 278 @Override 279 public boolean visit(InvariantDeclaration node) { 280 return visitFunc(node); 281 } 282 283 @Override 284 public boolean visit(FuncLiteralDeclaration node) { 285 return visitFunc(node); 286 } 287 288 private boolean visitFunc(FuncDeclaration node) { 266 289 if (inRange(node)) { 267 290 func = node; … … 275 298 @Override 276 299 public boolean visit(LabelStatement node) { 277 if (func != null && func.start <= node.start && node.start <= func.start + func.length) { 300 if (func != null && func.start <= node.start && node.start <= func.start + func.length 301 && (!inLoop || isRelevant(node))) { 278 302 labelsMap.put(node.ident.ident, this); 279 303 } 280 304 return true; 281 }282 283 @Override284 public boolean visit(EnumDeclaration node) {285 return false;286 }287 288 @Override289 public boolean visit(ClassDeclaration node) {290 return inRange(node);291 }292 293 @Override294 public boolean visit(InterfaceDeclaration node) {295 return inRange(node);296 }297 298 @Override299 public boolean visit(StructDeclaration node) {300 return inRange(node);301 }302 303 @Override304 public boolean visit(UnionDeclaration node) {305 return inRange(node);306 }307 308 @Override309 public boolean visit(TemplateDeclaration node) {310 return inRange(node);311 305 } 312 306 … … 316 310 } 317 311 312 private boolean isRelevant(LabelStatement node) { 313 Statement stm = node.statement; 314 while(stm != null) { 315 int type = stm.getNodeType(); 316 if (type == ASTDmdNode.WHILE_STATEMENT || 317 type == ASTDmdNode.DO_STATEMENT || 318 type == ASTDmdNode.FOR_STATEMENT) { 319 return true; 320 } else if (type == ASTDmdNode.COMPOUND_STATEMENT) { 321 CompoundStatement cs = (CompoundStatement) stm; 322 if (cs.sourceStatements != null && cs.sourceStatements.size() > 0) { 323 stm = cs.sourceStatements.get(0); 324 } else { 325 return false; 326 } 327 } else { 328 return false; 329 } 330 } 331 return false; 332 } 333 334 @Override 335 public boolean visit(EnumDeclaration node) { 336 return false; 337 } 338 @Override 339 public boolean visit(ClassDeclaration node) { 340 return inRange(node); 341 } 342 @Override 343 public boolean visit(InterfaceDeclaration node) { 344 return inRange(node); 345 } 346 @Override 347 public boolean visit(StructDeclaration node) { 348 return inRange(node); 349 } 350 @Override 351 public boolean visit(UnionDeclaration node) { 352 return inRange(node); 353 } 354 @Override 355 public boolean visit(TemplateDeclaration node) { 356 return inRange(node); 357 } 318 358 }); 319 359 320 360 char[][] labels = labelsMap.keys(); 321 361 if (labels != null) { 322 char[] prefix; 323 if (node.ident == null || node.ident.ident == null) { 324 this.startPosition = this.actualCompletionPosition; 325 this.endPosition = this.actualCompletionPosition; 326 prefix = CharOperation.NO_CHAR; 327 } else { 328 this.startPosition = node.ident.start; 329 this.endPosition = node.ident.start + node.ident.length; 330 prefix = node.ident.ident; 331 } 332 362 char[] prefix = computePrefixAndSourceRange(ident); 333 363 for(char[] label : labels) { 334 364 if (label != null) { … … 343 373 } 344 374 } 375 } 376 377 private char[] computePrefixAndSourceRange(IdentifierExp ident) { 378 char[] prefix; 379 if (ident == null || ident.ident == null) { 380 this.startPosition = this.actualCompletionPosition; 381 this.endPosition = this.actualCompletionPosition; 382 prefix = CharOperation.NO_CHAR; 383 } else { 384 this.startPosition = ident.start; 385 this.endPosition = ident.start + ident.length; 386 prefix = ident.ident; 387 } 388 return prefix; 345 389 } 346 390 trunk/descent.core/src/descent/internal/codeassist/complete/CompletionParser.java
r860 r869 7 7 import descent.internal.compiler.parser.ASTDmdNode; 8 8 import descent.internal.compiler.parser.Argument; 9 import descent.internal.compiler.parser.BreakStatement; 9 10 import descent.internal.compiler.parser.Chars; 11 import descent.internal.compiler.parser.ContinueStatement; 10 12 import descent.internal.compiler.parser.Expression; 11 13 import descent.internal.compiler.parser.GotoStatement; … … 96 98 97 99 @Override 100 protected BreakStatement newBreakStatement(Loc loc, IdentifierExp ident) { 101 if (prevToken.ptr + prevToken.sourceLen <= cursorLocation && cursorLocation <= token.ptr 102 && prevToken.value != TOK.TOKdot && prevToken.value != TOK.TOKslice && prevToken.value != TOK.TOKdotdotdot) { 103 104 includeExpectations = false; 105 106 assistNode = new CompletionOnBreakStatement(loc, ident); 107 return (BreakStatement) assistNode; 108 } else { 109 return super.newBreakStatement(loc, ident); 110 } 111 } 112 113 @Override 114 protected ContinueStatement newContinueStatement(Loc loc, IdentifierExp ident) { 115 if (prevToken.ptr + prevToken.sourceLen <= cursorLocation && cursorLocation <= token.ptr 116 && prevToken.value != TOK.TOKdot && prevToken.value != TOK.TOKslice && prevToken.value != TOK.TOKdotdotdot) { 117 118 includeExpectations = false; 119 120 assistNode = new CompletionOnContinueStatement(loc, ident); 121 return (ContinueStatement) assistNode; 122 } else { 123 return super.newContinueStatement(loc, ident); 124 } 125 } 126 127 @Override 98 128 protected void expect(char[][] toks) { 99 129 // If we are completing already a more important thing, exclude trunk/descent.core/src/descent/internal/compiler/parser/Parser.java
r860 r869 1196 1196 InvariantDeclaration invariant = new InvariantDeclaration(loc); 1197 1197 invariant.invariantStart = start; 1198 invariant. fbody = parseStatement(PScurly);1198 invariant.setFbody(parseStatement(PScurly)); 1199 1199 invariant.setSourceRange(start, prevToken.ptr + prevToken.sourceLen - start); 1200 1200 return invariant; … … 1206 1206 1207 1207 UnitTestDeclaration unitTest = new UnitTestDeclaration(loc); 1208 unitTest. fbody = parseStatement(PScurly);1208 unitTest.setFbody(parseStatement(PScurly)); 1209 1209 unitTest.setSourceRange(start, prevToken.ptr + prevToken.sourceLen - start); 1210 1210 return unitTest; … … 4191 4191 check(TOKsemicolon); 4192 4192 4193 s = new BreakStatement(loc, ident);4193 s = newBreakStatement(loc, ident); 4194 4194 break; 4195 4195 } … … 4208 4208 check(TOKsemicolon); 4209 4209 4210 s = new ContinueStatement(loc, ident);4210 s = newContinueStatement(loc, ident); 4211 4211 break; 4212 4212 } … … 6128 6128 6129 6129 e.setSourceRange(start, prevToken.ptr + prevToken.sourceLen - start); 6130 if (e instanceof FuncExp) { 6131 ((FuncExp) e).fd.setSourceRange(e.start, e.length); 6132 } 6130 6133 6131 6134 return e; … … 6966 6969 } 6967 6970 6971 protected ContinueStatement newContinueStatement(Loc loc, IdentifierExp ident) { 6972 return new ContinueStatement(loc, ident); 6973 } 6974 6975 protected BreakStatement newBreakStatement(Loc loc, IdentifierExp ident) { 6976 return new BreakStatement(loc, ident); 6977 } 6978 6968 6979 /** 6969 6980 * The parser expects the current token to be trunk/descent.core/src/descent/internal/compiler/parser/VarDeclaration.java
r851 r869 91 91 if (children) { 92 92 TreeVisitor.acceptChildren(visitor, modifiers); 93 TreeVisitor.acceptChildren(visitor, type);93 TreeVisitor.acceptChildren(visitor, sourceType); 94 94 TreeVisitor.acceptChildren(visitor, ident); 95 TreeVisitor.acceptChildren(visitor, sourceInit); 95 96 } 96 97 visitor.endVisit(this); trunk/descent.tests/descent/tests/assist/CompletionOnGotoStatement_Test.java
r860 r869 5 5 public class CompletionOnGotoStatement_Test extends AbstractCompletionTest { 6 6 7 public void testEmpty () throws Exception {7 public void testEmptyOnFunction() throws Exception { 8 8 String s = "void foo() { someLabel: int x; otherLabel: int y; goto "; 9 9 … … 13 13 } 14 14 15 public void testSome () throws Exception {15 public void testSomeOnFunction() throws Exception { 16 16 String s = "void foo() { someLabel: int x; otherLabel: int y; goto o"; 17 18 assertCompletions(null, "test.d", s, s.length(), 19 CompletionProposal.LABEL_REF, "otherLabel", s.length() - 1, s.length()); 20 } 21 22 public void testEmptyOnUnitTest() throws Exception { 23 String s = "unittest { someLabel: int x; otherLabel: int y; goto "; 24 25 assertCompletions(null, "test.d", s, s.length(), 26 CompletionProposal.LABEL_REF, "otherLabel", s.length(), s.length(), 27 CompletionProposal.LABEL_REF, "someLabel", s.length(), s.length()); 28 } 29 30 public void testSomeOnUnitTest() throws Exception { 31 String s = "unittest { someLabel: int x; otherLabel: int y; goto o"; 32 33 assertCompletions(null, "test.d", s, s.length(), 34 CompletionProposal.LABEL_REF, "otherLabel", s.length() - 1, s.length()); 35 } 36 37 public void testEmptyOnInvariant() throws Exception { 38 String s = "invariant() { someLabel: int x; otherLabel: int y; goto "; 39 40 assertCompletions(null, "test.d", s, s.length(), 41 CompletionProposal.LABEL_REF, "otherLabel", s.length(), s.length(), 42 CompletionProposal.LABEL_REF, "someLabel", s.length(), s.length()); 43 } 44 45 public void testSomeOnInvariant() throws Exception { 46 String s = "invariant() { someLabel: int x; otherLabel: int y; goto o"; 17 47 18 48 assertCompletions(null, "test.d", s, s.length(),
