Changeset 869

Show
Ignore:
Timestamp:
10/21/07 22:23:18 (1 year ago)
Author:
asterite
Message:

Completion on goto statement now also works in unittests, invariants and function literals. Added completion on break and continue statements.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/descent.core/src/descent/internal/codeassist/CompletionEngine.java

    r861 r869  
    1212import descent.core.dom.AST; 
    1313import descent.internal.codeassist.complete.CompletionOnArgumentName; 
     14import descent.internal.codeassist.complete.CompletionOnBreakStatement; 
     15import descent.internal.codeassist.complete.CompletionOnContinueStatement; 
    1416import descent.internal.codeassist.complete.CompletionOnGotoStatement; 
    1517import descent.internal.codeassist.complete.CompletionOnImport; 
     
    2325import descent.internal.compiler.parser.Argument; 
    2426import descent.internal.compiler.parser.ClassDeclaration; 
     27import descent.internal.compiler.parser.CompoundStatement; 
    2528import descent.internal.compiler.parser.EnumDeclaration; 
    2629import descent.internal.compiler.parser.FuncDeclaration; 
     30import descent.internal.compiler.parser.FuncLiteralDeclaration; 
    2731import descent.internal.compiler.parser.Global; 
    2832import descent.internal.compiler.parser.HashtableOfCharArrayAndObject; 
     33import descent.internal.compiler.parser.IdentifierExp; 
    2934import descent.internal.compiler.parser.InterfaceDeclaration; 
     35import descent.internal.compiler.parser.InvariantDeclaration; 
    3036import descent.internal.compiler.parser.LabelStatement; 
    3137import descent.internal.compiler.parser.Module; 
    3238import descent.internal.compiler.parser.SemanticContext; 
     39import descent.internal.compiler.parser.Statement; 
    3340import descent.internal.compiler.parser.StructDeclaration; 
    3441import descent.internal.compiler.parser.TemplateDeclaration; 
     
    3643import descent.internal.compiler.parser.TypeFunction; 
    3744import descent.internal.compiler.parser.UnionDeclaration; 
     45import descent.internal.compiler.parser.UnitTestDeclaration; 
    3846import descent.internal.compiler.parser.ast.AstVisitorAdapter; 
    3947import descent.internal.compiler.util.HashtableOfObject; 
     
    163171                } else if (assistNode instanceof CompletionOnGotoStatement) { 
    164172                    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 */); 
    166180                } 
    167181            } 
     
    242256     
    243257    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); 
    255259        findVariableNames(name, node.type, findExcludedNames(node)); 
    256260    } 
    257261     
    258     private void completeGotoStatement(CompletionOnGotoStatement node) { 
     262    private void completeGotoBreakOrContinueStatement(IdentifierExp ident, final boolean inLoop) { 
    259263        final HashtableOfCharArrayAndObject labelsMap = new HashtableOfCharArrayAndObject();         
    260264        module.accept(new AstVisitorAdapter() { 
     
    264268            @Override 
    265269            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) { 
    266289                if (inRange(node)) { 
    267290                    func = node; 
     
    275298            @Override 
    276299            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))) { 
    278302                    labelsMap.put(node.ident.ident, this); 
    279303                } 
    280304                return true; 
    281             } 
    282              
    283             @Override 
    284             public boolean visit(EnumDeclaration node) { 
    285                 return false; 
    286             } 
    287              
    288             @Override 
    289             public boolean visit(ClassDeclaration node) { 
    290                 return inRange(node); 
    291             } 
    292              
    293             @Override 
    294             public boolean visit(InterfaceDeclaration node) { 
    295                 return inRange(node); 
    296             } 
    297              
    298             @Override 
    299             public boolean visit(StructDeclaration node) { 
    300                 return inRange(node); 
    301             } 
    302              
    303             @Override 
    304             public boolean visit(UnionDeclaration node) { 
    305                 return inRange(node); 
    306             } 
    307              
    308             @Override 
    309             public boolean visit(TemplateDeclaration node) { 
    310                 return inRange(node); 
    311305            } 
    312306             
     
    316310            } 
    317311             
     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            }            
    318358        }); 
    319359         
    320360        char[][] labels = labelsMap.keys(); 
    321361        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);          
    333363            for(char[] label : labels) { 
    334364                if (label != null) { 
     
    343373            } 
    344374        } 
     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; 
    345389    } 
    346390     
  • trunk/descent.core/src/descent/internal/codeassist/complete/CompletionParser.java

    r860 r869  
    77import descent.internal.compiler.parser.ASTDmdNode; 
    88import descent.internal.compiler.parser.Argument; 
     9import descent.internal.compiler.parser.BreakStatement; 
    910import descent.internal.compiler.parser.Chars; 
     11import descent.internal.compiler.parser.ContinueStatement; 
    1012import descent.internal.compiler.parser.Expression; 
    1113import descent.internal.compiler.parser.GotoStatement; 
     
    9698     
    9799    @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 
    98128    protected void expect(char[][] toks) { 
    99129        // If we are completing already a more important thing, exclude 
  • trunk/descent.core/src/descent/internal/compiler/parser/Parser.java

    r860 r869  
    11961196        InvariantDeclaration invariant = new InvariantDeclaration(loc); 
    11971197        invariant.invariantStart = start; 
    1198         invariant.fbody = parseStatement(PScurly); 
     1198        invariant.setFbody(parseStatement(PScurly)); 
    11991199        invariant.setSourceRange(start, prevToken.ptr + prevToken.sourceLen - start); 
    12001200        return invariant; 
     
    12061206         
    12071207        UnitTestDeclaration unitTest = new UnitTestDeclaration(loc); 
    1208         unitTest.fbody = parseStatement(PScurly); 
     1208        unitTest.setFbody(parseStatement(PScurly)); 
    12091209        unitTest.setSourceRange(start, prevToken.ptr + prevToken.sourceLen - start); 
    12101210        return unitTest; 
     
    41914191            check(TOKsemicolon); 
    41924192             
    4193             s = new BreakStatement(loc, ident); 
     4193            s = newBreakStatement(loc, ident); 
    41944194            break; 
    41954195        } 
     
    42084208            check(TOKsemicolon); 
    42094209             
    4210             s = new ContinueStatement(loc, ident); 
     4210            s = newContinueStatement(loc, ident); 
    42114211            break; 
    42124212        } 
     
    61286128 
    61296129        e.setSourceRange(start, prevToken.ptr + prevToken.sourceLen - start); 
     6130        if (e instanceof FuncExp) { 
     6131            ((FuncExp) e).fd.setSourceRange(e.start, e.length); 
     6132        } 
    61306133 
    61316134        return e; 
     
    69666969    } 
    69676970     
     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     
    69686979    /** 
    69696980     * The parser expects the current token to be 
  • trunk/descent.core/src/descent/internal/compiler/parser/VarDeclaration.java

    r851 r869  
    9191        if (children) { 
    9292            TreeVisitor.acceptChildren(visitor, modifiers); 
    93             TreeVisitor.acceptChildren(visitor, type); 
     93            TreeVisitor.acceptChildren(visitor, sourceType); 
    9494            TreeVisitor.acceptChildren(visitor, ident); 
     95            TreeVisitor.acceptChildren(visitor, sourceInit); 
    9596        } 
    9697        visitor.endVisit(this); 
  • trunk/descent.tests/descent/tests/assist/CompletionOnGotoStatement_Test.java

    r860 r869  
    55public class CompletionOnGotoStatement_Test extends AbstractCompletionTest { 
    66     
    7     public void testEmpty() throws Exception { 
     7    public void testEmptyOnFunction() throws Exception { 
    88        String s = "void foo() { someLabel: int x; otherLabel: int y; goto "; 
    99         
     
    1313    } 
    1414     
    15     public void testSome() throws Exception { 
     15    public void testSomeOnFunction() throws Exception { 
    1616        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"; 
    1747         
    1848        assertCompletions(null, "test.d", s, s.length(),