View | Details | Raw Unified | Return to bug 332492 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/photran/internal/core/refactoring/Messages.java (+33 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *    UIUC - Initial API and implementation
9
 *    UIUC - Initial API and implementation
10
 *    Rita Chow - Photran Modifications
11
 *    Nicola Hall - Photran Modifications
12
 *    Jerry Hsiao - Photran Modifications
13
 *    Mark Mozolewski - Photran Modifications
14
 *    Chamil Wijenayaka - Photran Modifications
10
 *******************************************************************************/
15
 *******************************************************************************/
11
package org.eclipse.photran.internal.core.refactoring;
16
package org.eclipse.photran.internal.core.refactoring;
12
17
Lines 356-364 Link Here
356
361
357
    public static String RemoveArithmeticIfRefactoring_Name;
362
    public static String RemoveArithmeticIfRefactoring_Name;
358
363
364
    public static String RemoveBranchToEndIfRefactoring_Name;
365
    
366
    public static String RemoveBranchToEndIfRefactoring_MissingGoToStatement;
367
    
368
    public static String RemoveBranchToEndIfRefactoring_GoToLabelDoesNotMatchAnyEndIfLabel;
369
    
370
    public static String RemoveBranchToEndIfRefactoring_BranchToImmediateEndIf;
371
    
372
    public static String RemoveBranchToEndIfRefactoring_SelectEndIfStatementToRefactor;
373
    
374
    public static String RemoveBranchToEndIfRefactoring_CanNotFindIfConstruct;
375
    
376
    public static String RemoveBranchToEndIfRefactoring_CanNotFindGoToStatementForThisLabel;
377
    
359
    public static String RemoveComputedGoToRefactoring_Name;
378
    public static String RemoveComputedGoToRefactoring_Name;
360
379
361
    public static String RemoveComputedGoToRefactoring_PleaseSelectComputedGotoStmt;
380
    public static String RemoveComputedGoToRefactoring_PleaseSelectComputedGotoStmt;
381
    
382
    public static String RemovePauseStmtRefactoring_Name;
383
    
384
    public static String RemovePauseStmtRefactoring_SelectPauseStmt;
385
    
386
    public static String RemoveRealAndDoublePrecisionLoopCountersRefactoring_Name;
387
    
388
    public static String RemoveRealAndDoublePrecisionLoopCountersRefactoring_PleaseSelectADoLoop;
389
    
390
    public static String RemoveRealAndDoublePrecisionLoopCountersRefactoring_PleaseSelectAControlledDoLoop;
391
    
392
    public static String RemoveRealAndDoublePrecisionLoopCountersRefactoring_LoopControlVariableMissingDeclaration;
393
    
394
    public static String RemoveRealAndDoublePrecisionLoopCountersRefactoring_LoopControlVariableNotRealOrDouble;
362
395
363
    public static String RemoveUnusedVariablesRefactoring_CouldNotCompleteOperation;
396
    public static String RemoveUnusedVariablesRefactoring_CouldNotCompleteOperation;
364
397
(-)src/org/eclipse/photran/internal/core/refactoring/RemoveBranchToEndIfRefactoring.java (+564 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Rita Chow, Nicola Hall, Jerry Hsiao, Mark Mozolewski, Chamil Wijenayaka
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    Rita Chow - Initial Implementation
10
 *    Nicola Hall - Initial Implementation
11
 *    Jerry Hsiao - Initial Implementation
12
 *    Mark Mozolewski - Initial Implementation
13
 *    Chamil Wijenayaka - Initial Implementation
14
 *******************************************************************************/
15
package org.eclipse.photran.internal.core.refactoring;
16
17
import java.util.LinkedList;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.OperationCanceledException;
21
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
22
import org.eclipse.photran.internal.core.analysis.binding.ScopingNode;
23
import org.eclipse.photran.internal.core.analysis.loops.ASTProperLoopConstructNode;
24
import org.eclipse.photran.internal.core.analysis.loops.ASTVisitorWithLoops;
25
import org.eclipse.photran.internal.core.analysis.loops.LoopReplacer;
26
import org.eclipse.photran.internal.core.parser.*;
27
import org.eclipse.photran.internal.core.refactoring.infrastructure.FortranEditorRefactoring;
28
29
/**
30
 * Remove branching to END IF statement from outside its IF ... END IF block. Such branching should
31
 * be replaced with branching to CONTINUE statement that immediately follows the END IF statement.
32
 * If the END IF statement is followed by a CONTINUE statement then outside GOTO branches should
33
 * target the CONTINUE statement. If one does not exist the refactoring will insert one and target
34
 * it. GOTOs inside the selected IF block are not re-targeted.
35
 * 
36
 * User Selection Requirements: The labeled END IF that they want considered for the refactoring.
37
 * 
38
 * @author Rita Chow (chow15), Jerry Hsiao (jhsiao2), Mark Mozolewski (mozolews), Chamil Wijenayaka
39
 *         (wijenay2), Nicola Hall (nfhall2)
40
 */
41
public class RemoveBranchToEndIfRefactoring extends FortranEditorRefactoring
42
{
43
    private IASTNode selectedNode;
44
45
    private ASTEndIfStmtNode selectedEndIfNode;
46
47
    private ASTIfConstructNode selectedIfConstructNode;
48
49
    private LinkedList<ASTGotoStmtNode> gotoStatements;
50
51
    private LinkedList<ASTGotoStmtNode> selectedGotoStatements;
52
53
    private ASTContinueStmtNode continueAfterIfStmtNode;
54
55
    private LinkedList<ASTGotoStmtNode> selectedGotoStatementWithEndIfLabel;
56
57
    private LinkedList<ASTGotoStmtNode> gotoStatementWithEndIfLabel;
58
59
    /**
60
     * Provide GUI refactoring label.
61
     */
62
    @Override
63
    public String getName()
64
    {
65
        return Messages.RemoveBranchToEndIfRefactoring_Name;
66
    }
67
68
    /**
69
     * Preconditions that are checked before the refactoring is applied are: 1) END IF selected must
70
     * be labeled and part of an IF block. 2) GOTO from either inside the selected IF block or
71
     * outside the selected IF block must target the label of the END IF selected. 3) must be more
72
     * GOTOs than just in local selected END IF scope.
73
     * 
74
     */
75
    @Override
76
    protected void doCheckInitialConditions(RefactoringStatus status, IProgressMonitor pm)
77
        throws PreconditionFailure
78
    {
79
        ensureProjectHasRefactoringEnabled(status);
80
81
        // Check if selected text is a portion within an END IF statement with label.
82
        setSelectedNodeAndEndIfNode();
83
        if ((selectedEndIfNode == null) || (selectedEndIfNode.getLabel() == null))
84
        {
85
            System.out
86
                .println(Messages.RemoveBranchToEndIfRefactoring_SelectEndIfStatementToRefactor);
87
            fail(Messages.RemoveBranchToEndIfRefactoring_SelectEndIfStatementToRefactor);
88
        }
89
90
        // Check if selected END IF is within an IF block.
91
        setSelectedIfConstructNode();
92
        if (selectedIfConstructNode == null)
93
        {
94
            System.out.println(Messages.RemoveBranchToEndIfRefactoring_CanNotFindIfConstruct);
95
            fail(Messages.RemoveBranchToEndIfRefactoring_CanNotFindIfConstruct);
96
        }
97
98
        // Check if selected scope contains a branch.
99
        setGotoStatements();
100
        if (gotoStatements.isEmpty())
101
        {
102
            System.out.println(Messages.RemoveBranchToEndIfRefactoring_MissingGoToStatement);
103
            fail(Messages.RemoveBranchToEndIfRefactoring_MissingGoToStatement);
104
        }
105
106
        // Check if contains a GOTO statement with selected END IF label.
107
        setGotoStatementsWithEndIfLabel();
108
        if (gotoStatementWithEndIfLabel.size() == 0)
109
        {
110
            System.out
111
                .println(Messages.RemoveBranchToEndIfRefactoring_CanNotFindGoToStatementForThisLabel);
112
            fail(Messages.RemoveBranchToEndIfRefactoring_CanNotFindGoToStatementForThisLabel);
113
        }
114
115
        // Check to see if there are branches outside of selected if block to selected END IF label.
116
        setSelectedGotoStatementsWithEndIfLabel();
117
        if (selectedGotoStatementWithEndIfLabel.size() == gotoStatementWithEndIfLabel.size())
118
        {
119
            System.out.println(Messages.RemoveBranchToEndIfRefactoring_BranchToImmediateEndIf);
120
            fail(Messages.RemoveBranchToEndIfRefactoring_BranchToImmediateEndIf);
121
        }
122
123
        setContinueAfterIfStmtNode();
124
    }
125
126
    /**
127
     * There are no final conditions.
128
     */
129
    @Override
130
    protected void doCheckFinalConditions(RefactoringStatus status, IProgressMonitor pm)
131
        throws PreconditionFailure
132
    {
133
        // No final conditions
134
    }
135
136
    /**
137
     * Separate refactroing methods based on if there is a CONTINUE statement after the selected END
138
     * IF (if so target it) or if no CONTINUE statement exists after the END IF block (insert one
139
     * with unique label and have GOTO statements outside the IF block target it.).
140
     */
141
    @Override
142
    protected void doCreateChange(IProgressMonitor pm) throws CoreException,
143
        OperationCanceledException
144
    {
145
        setAstAndNodes();
146
147
        if (continueAfterIfStmtNode == null)
148
        {
149
            changeNoContinueAfterEndIf(); // User Story #2
150
151
        }
152
        else
153
        {
154
            changeGotoLabelToContinueLabel(); // User Story #1
155
        }
156
157
        // User Story 3 checked in doCheckInitialConditions
158
159
        this.addChangeFromModifiedAST(this.fileInEditor, pm);
160
        vpg.releaseAST(this.fileInEditor);
161
    }
162
163
    /**
164
     * Sets AST of selected file and nodes used for refactoring.
165
     * 
166
     * @param None.
167
     * 
168
     * @return None.
169
     */
170
    private void setAstAndNodes()
171
    {
172
        this.astOfFileInEditor = vpg.acquireTransientAST(fileInEditor);
173
174
        // Setup nodes used for refactoring
175
        setSelectedNodeAndEndIfNode();
176
        setSelectedIfConstructNode();
177
        setGotoStatements();
178
        setGotoStatementsWithEndIfLabel();
179
        setSelectedGotoStatementsWithEndIfLabel();
180
        setContinueAfterIfStmtNode();
181
    }
182
183
    /**
184
     * Set selected node and selected end if node used for refactoring.
185
     * 
186
     * @param None.
187
     * 
188
     * @return None.
189
     */
190
    private void setSelectedNodeAndEndIfNode()
191
    {
192
        selectedNode = findEnclosingNode(this.astOfFileInEditor, this.selectedRegionInEditor);
193
        selectedEndIfNode = (ASTEndIfStmtNode)findEnclosingNodeOfType(selectedNode,
194
            ASTEndIfStmtNode.class);
195
    }
196
197
    /**
198
     * Set selected if construct node used for refactoring.
199
     * 
200
     * @param None.
201
     * 
202
     * @return None.
203
     */
204
    private void setSelectedIfConstructNode()
205
    {
206
        selectedIfConstructNode = (ASTIfConstructNode)findEnclosingNodeOfType(selectedEndIfNode,
207
            ASTIfConstructNode.class);
208
    }
209
210
    /**
211
     * Set goto statements used for refactoring.
212
     * 
213
     * @param None.
214
     * 
215
     * @return None.
216
     */
217
    private void setGotoStatements()
218
    {
219
        gotoStatements = getGotoNodes(ScopingNode.getLocalScope(selectedEndIfNode));
220
    }
221
222
    /**
223
     * Set go to statements with end if label used for refactoring.
224
     * 
225
     * @param None.
226
     * 
227
     * @return None.
228
     */
229
    private void setGotoStatementsWithEndIfLabel()
230
    {
231
        gotoStatementWithEndIfLabel = findGotoForLabel(gotoStatements, selectedEndIfNode.getLabel()
232
            .getText());
233
    }
234
235
    /**
236
     * Set selected go to statements with end if label used for refactoring.
237
     * 
238
     * @param None.
239
     * 
240
     * @return None.
241
     */
242
    private void setSelectedGotoStatementsWithEndIfLabel()
243
    {
244
        selectedGotoStatements = getGotoNodes(selectedIfConstructNode);
245
        selectedGotoStatementWithEndIfLabel = findGotoForLabel(selectedGotoStatements,
246
            selectedEndIfNode.getLabel().getText());
247
    }
248
249
    /**
250
     * Set continue after if statement used for refactoring.
251
     * 
252
     * @param None.
253
     * 
254
     * @return None.
255
     */
256
    private void setContinueAfterIfStmtNode()
257
    {
258
        continueAfterIfStmtNode = continueAfterIfStmt(selectedIfConstructNode);
259
    }
260
261
    /**
262
     * Main refactoring code for condition when CONTINUE statement follows the END..IF that was
263
     * selected for refactoring. The logic will renumber/retarget any GOTO statements in the GOTO to
264
     * that of the CONINUE label. (Per FORTRAN language standard the CONTINUE statement must have a
265
     * label). If any GOTO statement inside the selected END..IF targets the END..IF selected for
266
     * the Refactoring then the label of the END..IF will not be removed and that inner GOTO will
267
     * still target it. If there are no inner GOTOs targeting the END..IF label then the END..IF
268
     * label will be removed as part of the refactoring.
269
     * 
270
     */
271
    private void changeGotoLabelToContinueLabel()
272
    {
273
        // Check all GOTO statements in the entire PROGRAM to see if they target the END..IF label
274
        // number selected during the Refactoring. If so then retarget/renumber them to the
275
        // CONTINUE block that follows. (Note: Inner GOTO statements that that target the END..IF
276
        // statement are not retargeted/renumbered.)
277
        for (ASTGotoStmtNode gotoNode : gotoStatementWithEndIfLabel)
278
        {
279
            // Do not re-target GOTO statements from within the selected END..IF for refactoring.
280
            if (!selectedGotoStatementWithEndIfLabel.contains(gotoNode))
281
            { // Goto targeted to our selected IF..ENDIF block
282
                gotoNode.getGotoLblRef().getLabel()
283
                    .setText(continueAfterIfStmtNode.getLabel().getText()); // Use existing
284
            }
285
        }
286
287
        // Label of selected END..IF for Refactoring is only removed after all other GOTOs have been
288
        // retargeted and if no inner GOTO statements target its label.
289
        if (selectedGotoStatementWithEndIfLabel.isEmpty())
290
        {
291
            selectedEndIfNode.setLabel(null);
292
            selectedEndIfNode.findFirstToken().setWhiteBefore(
293
                selectedIfConstructNode.findFirstToken().getWhiteBefore()); // reindenter alt.
294
        }
295
296
    }
297
298
    /**
299
     * Modify Fortran code to add a CONTINUE statement after labeled END IF then remove END IF label
300
     * only if there are no GOTO statements within the selected IF statement that target that END IF
301
     * statement.
302
     * 
303
     */
304
    private void changeNoContinueAfterEndIf()
305
    {
306
307
        // build the CONTINUE node
308
        if (continueAfterIfStmtNode != null) { return; }
309
310
        @SuppressWarnings("unchecked")
311
        ASTListNode<ASTNode> listNode = (ASTListNode<ASTNode>)selectedIfConstructNode.getParent();
312
313
        // build the CONTINUE statement program source code
314
        String programString = "program p\n" + selectedEndIfNode.getLabel().getText() + " CONTINUE" //$NON-NLS-1$ //$NON-NLS-2$
315
            + EOL + "end program"; //$NON-NLS-1$
316
        ASTMainProgramNode programNode = (ASTMainProgramNode)parseLiteralProgramUnit(programString);
317
        ASTContinueStmtNode continueStmt = (ASTContinueStmtNode)programNode.getBody().get(0);
318
319
        // insert into AST
320
        continueStmt.setParent(selectedIfConstructNode.getParent());
321
        listNode.insertAfter(selectedIfConstructNode, continueStmt);
322
323
        // clear label on END IF statement
324
        if (selectedGotoStatementWithEndIfLabel.size() == 0)
325
        {
326
            selectedEndIfNode.setLabel(null);
327
            // correct indentation
328
            selectedEndIfNode.findFirstToken().setWhiteBefore(
329
                selectedIfConstructNode.findFirstToken().getWhiteBefore());
330
        }
331
        else
332
        {
333
            // Grab all labels
334
            LinkedList<IActionStmt> actionStmts = getActionStmts(ScopingNode
335
                .getLocalScope(selectedEndIfNode));
336
337
            // Calculate unique label
338
            String label = getUniqueLabel(actionStmts);
339
340
            // Set continue label to new label
341
            continueStmt.getLabel().setText(label);
342
343
            // Set all goto statements to new label
344
            for (ASTGotoStmtNode node : gotoStatementWithEndIfLabel)
345
            {
346
                if (!selectedGotoStatementWithEndIfLabel.contains(node))
347
                {
348
                    node.getGotoLblRef().getLabel().setText(label);
349
                }
350
            }
351
        }
352
    }
353
354
    /**
355
     * Build a list of all GOTO node types from the starting node.
356
     * 
357
     * @param startNode Node to start the search.
358
     * 
359
     * @return LinkedList of GOTO nodes.
360
     */
361
    private LinkedList<ASTGotoStmtNode> getGotoNodes(IASTNode startNode)
362
    {
363
        if (startNode == null) { return null; }
364
365
        /*
366
         * Unable to find all goto statements when there are do loops in startNode, so need to
367
         * search in the do loops separately.
368
         */
369
        final LinkedList<ASTGotoStmtNode> gotoNodes = getGotoStmtsInAllProperLoopConstructs(startNode);
370
371
        startNode.accept(new ASTVisitor()
372
        {
373
            @Override
374
            public void visitASTGotoStmtNode(ASTGotoStmtNode node)
375
            {
376
                gotoNodes.add(node);
377
            }
378
        });
379
380
        return gotoNodes;
381
    }
382
383
    /**
384
     * Build a list of all proper-loop-construct node types from the starting node.
385
     * 
386
     * @param startNode Node to start the search.
387
     * @return LinkedList of proper-loop-construct nodes.
388
     */
389
    private LinkedList<ASTGotoStmtNode> getGotoStmtsInAllProperLoopConstructs(IASTNode startNode)
390
    {
391
        final LinkedList<ASTGotoStmtNode> gotoNodes = new LinkedList<ASTGotoStmtNode>();
392
        final LinkedList<ASTProperLoopConstructNode> loopNodes = getProperLoopConstructs(startNode);
393
394
        for (ASTProperLoopConstructNode loop : loopNodes)
395
        {
396
            for (IASTNode node : loop.getBody())
397
            {
398
                node.accept(new ASTVisitor()
399
                {
400
                    @Override
401
                    public void visitASTGotoStmtNode(ASTGotoStmtNode node)
402
                    {
403
                        gotoNodes.add(node);
404
                    }
405
                });
406
            }
407
        }
408
409
        return gotoNodes;
410
    }
411
412
    /**
413
     * Find GOTO node(s) based on matching label.
414
     * 
415
     * @param gotos List of GOTO statements to check for matching label.
416
     * @param label Label to match against.
417
     * @return List of GOTO nodes that target the specified label.
418
     */
419
    private LinkedList<ASTGotoStmtNode> findGotoForLabel(LinkedList<ASTGotoStmtNode> gotos,
420
        String label)
421
    {
422
        if (gotos == null) { return new LinkedList<ASTGotoStmtNode>(); }
423
424
        LinkedList<ASTGotoStmtNode> gotoWithLabel = new LinkedList<ASTGotoStmtNode>();
425
        for (ASTGotoStmtNode gotoNode : gotos)
426
        {
427
            if (gotoNode.getGotoLblRef().getLabel().getText().contentEquals(label))
428
            {
429
                gotoWithLabel.add(gotoNode);
430
            }
431
        }
432
433
        return gotoWithLabel;
434
    }
435
436
    /**
437
     * Check for CONTINUE statement after a if construct node
438
     * 
439
     * @param ifStmt If construct node.
440
     * @return continue statement node or null.
441
     */
442
    private static ASTContinueStmtNode continueAfterIfStmt(ASTIfConstructNode ifStmt)
443
    {
444
        if (ifStmt == null) { return null; }
445
446
        @SuppressWarnings("unchecked")
447
        ASTListNode<ASTNode> list = (ASTListNode<ASTNode>)ifStmt.getParent();
448
449
        for (int i = 0; i < list.size() - 1; i++)
450
        {
451
            if (list.get(i) != null)
452
            {
453
                if (list.get(i).equals(ifStmt))
454
                {
455
                    if (list.get(i + 1) instanceof ASTContinueStmtNode) { return (ASTContinueStmtNode)list
456
                        .get(i + 1); }
457
                }
458
            }
459
        }
460
461
        return null;
462
    }
463
464
    /**
465
     * Generate a unique label based on the labels passed in (unique in that find the largest and
466
     * add 10)
467
     * 
468
     * @param actionStmts List of statements that may be labeled to consider for a unique label.
469
     * @return Unique label value.
470
     */
471
    private String getUniqueLabel(LinkedList<IActionStmt> actionStmts)
472
    {
473
        int label = Integer.parseInt(selectedEndIfNode.getLabel().getText());
474
        for (IActionStmt stmt : actionStmts)
475
        {
476
            if (stmt.getLabel() != null)
477
            {
478
                int currentLabel = Integer.parseInt(stmt.getLabel().getText());
479
                if (currentLabel > label)
480
                {
481
                    label = currentLabel;
482
                }
483
            }
484
        }
485
        label += 10;
486
487
        return String.valueOf(label);
488
    }
489
490
    /**
491
     * Find Action statement nodes in the tree from the starting search node.
492
     * 
493
     * @param startNode Starting node from which to perform the search.
494
     * @return LinkedList of action statement nodes that are found.
495
     */
496
    private LinkedList<IActionStmt> getActionStmts(IASTNode startNode)
497
    {
498
        final LinkedList<IActionStmt> actionStmts = getActionStmtsInAllProperLoopConstructs();
499
        startNode.accept(new ASTVisitor()
500
        {
501
            @Override
502
            public void visitIActionStmt(IActionStmt node)
503
            {
504
                actionStmts.add(node);
505
            }
506
        });
507
508
        return actionStmts;
509
    }
510
511
    /**
512
     * Find Action statement nodes in entire file in editor.
513
     * 
514
     * @return LinkedList of action statement nodes found.
515
     */
516
    private LinkedList<IActionStmt> getActionStmtsInAllProperLoopConstructs()
517
    {
518
        final LinkedList<IActionStmt> actionStmts = new LinkedList<IActionStmt>();
519
        final LinkedList<ASTProperLoopConstructNode> loopNodes = getProperLoopConstructs(ScopingNode
520
            .getLocalScope(selectedEndIfNode));
521
522
        for (ASTProperLoopConstructNode loop : loopNodes)
523
        {
524
            for (IASTNode node : loop.getBody())
525
            {
526
                node.accept(new ASTVisitor()
527
                {
528
                    @Override
529
                    public void visitIActionStmt(IActionStmt node)
530
                    {
531
                        actionStmts.add(node);
532
                    }
533
                });
534
            }
535
        }
536
537
        return actionStmts;
538
    }
539
540
    /**
541
     * Find all proper loop constructs in the tree from the starting search node.
542
     * 
543
     * @param startNode Starting node from which to perform the search.
544
     * @return LinkedList of proper loop construct nodes found.
545
     */
546
    private LinkedList<ASTProperLoopConstructNode> getProperLoopConstructs(IASTNode startNode)
547
    {
548
        final LinkedList<ASTProperLoopConstructNode> loopNodes = new LinkedList<ASTProperLoopConstructNode>();
549
550
        // Change AST to represent DO-loops as ASTProperLoopConstructNodes
551
        LoopReplacer.replaceAllLoopsIn(this.astOfFileInEditor.getRoot());
552
553
        startNode.accept(new ASTVisitorWithLoops()
554
        {
555
            @Override
556
            public void visitASTProperLoopConstructNode(ASTProperLoopConstructNode node)
557
            {
558
                loopNodes.add(node);
559
            }
560
        });
561
562
        return loopNodes;
563
    }
564
}
(-)src/org/eclipse/photran/internal/core/refactoring/RemovePauseStmtRefactoring.java (+145 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Rita Chow, Nicola Hall, Jerry Hsiao, Mark Mozolewski, Chamil Wijenayaka
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    Rita Chow - Initial Implementation
10
 *    Nicola Hall - Initial Implementation
11
 *    Jerry Hsiao - Initial Implementation
12
 *    Mark Mozolewski - Initial Implementation
13
 *    Chamil Wijenayaka - Initial Implementation
14
 *******************************************************************************/
15
package org.eclipse.photran.internal.core.refactoring;
16
17
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.IProgressMonitor;
19
import org.eclipse.core.runtime.OperationCanceledException;
20
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
21
import org.eclipse.photran.internal.core.refactoring.infrastructure.FortranEditorRefactoring;
22
import org.eclipse.photran.internal.core.parser.*;
23
24
/**
25
 * This feature address the replacement of the PAUSE statement with a PRINT and READ statement.
26
 * Execution of a PAUSE statement may be different on different platforms. The refactoring assumes
27
 * the most basic functionality: it replaces the PAUSE statement with a PRINT statement that
28
 * displays the message of the PAUSE statement, immediately followed by a READ statement that waits
29
 * for any input from the user.
30
 * 
31
 * User Selection Requirements: The PAUSE statement to be replaced.
32
 * 
33
 * @author Rita Chow (chow15), Jerry Hsiao (jhsiao2), Mark Mozolewski (mozolews), Chamil Wijenayaka
34
 *         (wijenay2), Nicola Hall (nfhall2)
35
 */
36
public class RemovePauseStmtRefactoring extends FortranEditorRefactoring
37
{
38
    private IASTNode selectedNode = null;
39
40
    private ASTPauseStmtNode selectedPauseStmt = null;
41
42
    /**
43
     * Preconditions checks: Check if project has refactoring is enabled. 
44
     * Checks that the user selects a PAUSE statement for refactoring. Failure 
45
     * to meet these conditions will result in a fail-initial condition.
46
     */
47
    @Override
48
    protected void doCheckInitialConditions(RefactoringStatus status, IProgressMonitor pm)
49
        throws org.eclipse.rephraserengine.core.vpg.refactoring.VPGRefactoring.PreconditionFailure
50
    {
51
        ensureProjectHasRefactoringEnabled(status);
52
53
        // Check if selected is a PAUSE statement
54
        setSelectedPauseStmt();
55
56
        if (selectedPauseStmt == null)
57
        {
58
            System.out.println(Messages.RemovePauseStmtRefactoring_SelectPauseStmt);
59
            fail(Messages.RemovePauseStmtRefactoring_SelectPauseStmt);
60
        }
61
    }
62
63
    /**
64
     * FinalConditions no final checks required. 
65
     */
66
    @Override
67
    protected void doCheckFinalConditions(RefactoringStatus status, IProgressMonitor pm)
68
        throws org.eclipse.rephraserengine.core.vpg.refactoring.VPGRefactoring.PreconditionFailure
69
    {
70
    }
71
72
    /**
73
     * Performs main refactoring (delegated to other methods).
74
     */
75
    @Override
76
    protected void doCreateChange(IProgressMonitor pm) throws CoreException,
77
        OperationCanceledException
78
    {
79
        changePauseStmt();
80
81
        // Finalize.
82
        this.addChangeFromModifiedAST(this.fileInEditor, pm);
83
        vpg.releaseAST(this.fileInEditor);
84
    }
85
86
    /**
87
     * Provide GUI refactoring label.
88
     */
89
    @Override
90
    public String getName()
91
    {
92
        return Messages.RemovePauseStmtRefactoring_Name;
93
    }
94
95
    /**
96
     * Obtains the selected pause statement else sets the member field to null.
97
     */
98
    private void setSelectedPauseStmt()
99
    {
100
        selectedNode = findEnclosingNode(this.astOfFileInEditor, this.selectedRegionInEditor);
101
102
        selectedPauseStmt = (ASTPauseStmtNode)findEnclosingNodeOfType(selectedNode,
103
            ASTPauseStmtNode.class);
104
    }
105
106
    /**
107
     * Insert modified PRINT statement and build READ() AST node to insert in to the program after
108
     * the PRINT statement.
109
     */
110
    private void changePauseStmt()
111
    {
112
        // change to modify the transient AST.
113
        this.astOfFileInEditor = vpg.acquireTransientAST(fileInEditor);
114
115
        // check on pause statement performed in initial, should not have changed in final.
116
        setSelectedPauseStmt();
117
118
        String pauseMessage = "\'\'"; //$NON-NLS-1$;
119
120
        // Contents of the PRINT statement to maintain.
121
        if (null != selectedPauseStmt.getStringConst())
122
        {
123
            pauseMessage = selectedPauseStmt.getStringConst().getText();
124
        }
125
126
        // Build new AST node for modified PRINT statement and new READ statement.
127
        String indent = selectedPauseStmt.findFirstToken().getWhiteBefore();
128
        String programString = "program p" + EOL + //$NON-NLS-1$
129
            indent
130
            + "PRINT *, " + pauseMessage + selectedPauseStmt.findLastToken().getWhiteBefore() + EOL + //$NON-NLS-1$
131
            indent + "READ (*, *)" + EOL + //$NON-NLS-1$
132
            "end program"; //$NON-NLS-1$
133
134
        // Insert new AST node in place of selected PRINT statement.
135
        ASTMainProgramNode programNode = (ASTMainProgramNode)parseLiteralProgramUnit(programString);
136
        ASTPrintStmtNode printStmt = (ASTPrintStmtNode)programNode.getBody().get(0);
137
        ASTReadStmtNode readStmt = (ASTReadStmtNode)programNode.getBody().get(1);
138
139
        @SuppressWarnings("unchecked")
140
        ASTListNode<ASTNode> listNode = (ASTListNode<ASTNode>)selectedPauseStmt.getParent();
141
142
        selectedPauseStmt.replaceWith(printStmt);
143
        listNode.insertAfter(printStmt, readStmt);
144
    }
145
}
(-)src/org/eclipse/photran/internal/core/refactoring/RemoveRealAndDoublePrecisionLoopCountersRefactoring.java (+392 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Rita Chow, Nicola Hall, Jerry Hsiao, Mark Mozolewski, Chamil Wijenayaka
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    Rita Chow - Initial Implementation
10
 *    Nicola Hall - Initial Implementation
11
 *    Jerry Hsiao - Initial Implementation
12
 *    Mark Mozolewski - Initial Implementation
13
 *    Chamil Wijenayaka - Initial Implementation
14
 *******************************************************************************/
15
package org.eclipse.photran.internal.core.refactoring;
16
17
import java.util.LinkedList;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.OperationCanceledException;
21
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
22
import org.eclipse.photran.internal.core.analysis.binding.ScopingNode;
23
import org.eclipse.photran.internal.core.analysis.loops.LoopReplacer;
24
import org.eclipse.photran.internal.core.parser.*;
25
import org.eclipse.photran.internal.core.refactoring.infrastructure.FortranEditorRefactoring;
26
import org.eclipse.photran.internal.core.analysis.loops.ASTProperLoopConstructNode;
27
28
/**
29
 * Remove Real and Double Precision Loop Counter Refactoring:
30
 * 
31
 * This refactoring will take a controlled DO loop, i.e. on that specifies the starting and ending
32
 * values for the control loop index and transform it to an uncontrolled do loop where the same loop
33
 * index and values are manually inserted into to the loop. If a explicit step size is specified is
34
 * used, otherwise an implicit one is inserted. The refactoring checks the start/end values of the
35
 * loop control variable to determine if the loop control variable should increment or decrement.
36
 * 
37
 * User Selection Requirements: A controlled DO loop statement to be considered for refactoring.
38
 * 
39
 * @author Rita Chow (chow15), Nicola Hall (nfhall2), Jerry Hsiao (jhsiao2), Mark Mozolewski
40
 *         (mozolews), Chamil Wijenayaka (wijenay2)
41
 */
42
public class RemoveRealAndDoublePrecisionLoopCountersRefactoring extends FortranEditorRefactoring
43
{
44
45
    private IASTNode selectedNode = null;
46
47
    private ASTProperLoopConstructNode selectedDoLoopNode = null;
48
49
    private LinkedList<ASTTypeDeclarationStmtNode> typeDeclarationsInFile;
50
51
    private String doVarName;
52
53
    private boolean shouldReplaceWithDoWhileLoop = false;
54
55
    /**
56
     * Provide GUI refactoring label.
57
     */
58
    @Override
59
    public String getName()
60
    {
61
        return Messages.RemoveRealAndDoublePrecisionLoopCountersRefactoring_Name;
62
    }
63
64
    /**
65
     * Set method for DO or DO WHILE refactoring selection variable.
66
     * 
67
     * @param value Set tracking variable for DO or DO WHILE refactoring selection.
68
     */
69
    public void setShouldReplaceWithDoWhileLoop(boolean value)
70
    {
71
        this.shouldReplaceWithDoWhileLoop = value;
72
    }
73
74
    /**
75
     * Precondition checks: Check if project has refactoring enabled.
76
     */
77
    @Override
78
    protected void doCheckInitialConditions(RefactoringStatus status, IProgressMonitor pm)
79
        throws PreconditionFailure
80
    {
81
        ensureProjectHasRefactoringEnabled(status);
82
    }
83
84
    /**
85
     * The following initial conditions are checked (a failure of any will result in a
86
     * fail-initial): - A controlled DO loop must be selected by the user. - Loop control variables
87
     * of a controlled DO loop must be declared as type REAL or DOUBLE PRECISION only.
88
     */
89
    @Override
90
    protected void doCheckFinalConditions(RefactoringStatus status, IProgressMonitor pm)
91
        throws PreconditionFailure
92
    {
93
        Boolean doVarNameIsRealOrDouble = false;
94
95
        this.astOfFileInEditor = vpg.acquireTransientAST(fileInEditor);
96
97
        // Change AST to represent DO-loops as ASTProperLoopConstructNodes
98
        LoopReplacer.replaceAllLoopsIn(this.astOfFileInEditor.getRoot());
99
100
        // Identify selected DO loop.
101
        selectedNode = findEnclosingNode(this.astOfFileInEditor, this.selectedRegionInEditor);
102
        selectedDoLoopNode = (ASTProperLoopConstructNode)findEnclosingNodeOfType(selectedNode,
103
            ASTProperLoopConstructNode.class);
104
105
        // Check for invalid selection (DO statement not selected)
106
        if (selectedDoLoopNode == null)
107
        {
108
            fail(Messages.RemoveRealAndDoublePrecisionLoopCountersRefactoring_PleaseSelectADoLoop);
109
        }
110
111
        // Check uncontrolled DO loop selected.
112
        if (selectedDoLoopNode.getLoopHeader().getLoopControl() == null)
113
        {
114
            fail(Messages.RemoveRealAndDoublePrecisionLoopCountersRefactoring_PleaseSelectAControlledDoLoop);
115
        }
116
117
        // Find all REAL and DOUBLE declared variables.
118
        doVarName = selectedDoLoopNode.getLoopHeader().getLoopControl().getVariableName().getText()
119
            .toString();
120
        typeDeclarationsInFile = getTypeDeclarations(this.astOfFileInEditor.getRoot());
121
122
        if (typeDeclarationsInFile == null)
123
        {
124
            fail(Messages.RemoveRealAndDoublePrecisionLoopCountersRefactoring_LoopControlVariableMissingDeclaration);
125
        }
126
127
        // Search all type declarations of the PROGRAM to find DO loop control variable name and
128
        // REAL or DOUBLE variable type.
129
        for (ASTTypeDeclarationStmtNode typeDeclaration : typeDeclarationsInFile)
130
        {
131
132
            if (typeDeclaration.getTypeSpec().isReal() || typeDeclaration.getTypeSpec().isDouble())
133
            {
134
135
                // Search all variable names for this REAL/DOUBLE variable declaration.
136
                for (ASTEntityDeclNode entityDeclaration : typeDeclaration.getEntityDeclList())
137
                {
138
139
                    if (entityDeclaration.getObjectName().getObjectName().getText()
140
                        .equals(doVarName))
141
                    {
142
                        doVarNameIsRealOrDouble = true;
143
                        break;
144
                    }
145
                }
146
147
            }
148
        }
149
150
        if (!doVarNameIsRealOrDouble)
151
        {
152
            fail(Messages.RemoveRealAndDoublePrecisionLoopCountersRefactoring_LoopControlVariableNotRealOrDouble);
153
        }
154
    }
155
156
    /**
157
     * After initial conditions checks pass there is a proper controlled DO loop variable to
158
     * refactor. The refactoring consists of building a number of AST node elements and inserting
159
     * them in to the program to do the work that the controlled DO loop would have done. This
160
     * includes: 1) Initial loop control variable assignment (starting value). 2)
161
     * Increment/Decrement control variable by specified amount (implicit or explicit step size) 3)
162
     * Check inside DO loop to see if loop variable limit specified is exceeded.
163
     */
164
    @Override
165
    protected void doCreateChange(IProgressMonitor pm) throws CoreException,
166
        OperationCanceledException
167
    {
168
        String ifCheckLb = selectedDoLoopNode.getLoopHeader().getLoopControl().getLb().toString();
169
        String ifCheckUb = selectedDoLoopNode.getLoopHeader().getLoopControl().getUb().toString();
170
        String ifCheckVar = selectedDoLoopNode.getLoopHeader().getLoopControl().getVariableName()
171
            .getText().toString();
172
173
        // Implicit step size check.
174
        String ifCheckStep = null;
175
        if (selectedDoLoopNode.getLoopHeader().getLoopControl().getStep() != null)
176
        {
177
            ifCheckStep = selectedDoLoopNode.getLoopHeader().getLoopControl().getStep().toString();
178
        }
179
        else
180
        {
181
            ifCheckStep = " 1"; //$NON-NLS-1$
182
        }
183
184
        String ifCheckIncrDecr = ""; //$NON-NLS-1$
185
        String ifCheckStr = ""; //$NON-NLS-1$
186
187
        // Work with both as double type.
188
        double dLb = Double.valueOf(ifCheckLb.trim()).doubleValue();
189
        double dUb = Double.valueOf(ifCheckUb.trim()).doubleValue();
190
191
        // Check for > or < IF check.
192
        if (dLb < dUb)
193
        {
194
            if (shouldReplaceWithDoWhileLoop)
195
                ifCheckStr = ifCheckVar + " <=" + ifCheckUb; //$NON-NLS-1$
196
            else
197
                ifCheckStr = ifCheckVar + " >" + ifCheckUb; //$NON-NLS-1$
198
            ifCheckIncrDecr = " +"; //$NON-NLS-1$
199
        }
200
        else
201
        {
202
            if (shouldReplaceWithDoWhileLoop)
203
                ifCheckStr = ifCheckVar + " >=" + ifCheckUb; //$NON-NLS-1$
204
            else
205
                ifCheckStr = ifCheckVar + " <" + ifCheckUb; //$NON-NLS-1$
206
            ifCheckIncrDecr = " -"; //$NON-NLS-1$
207
        }
208
209
        // AST modification for refactoring.
210
        if (shouldReplaceWithDoWhileLoop)
211
        {
212
            insertNewDoWhileLoop(ifCheckLb, ifCheckVar, ifCheckStep, ifCheckIncrDecr, ifCheckStr);
213
        }
214
        else
215
        {
216
            insertNewDoLoop(ifCheckLb, ifCheckVar, ifCheckStep, ifCheckIncrDecr, ifCheckStr);
217
        }
218
219
        // Finalize
220
        this.addChangeFromModifiedAST(this.fileInEditor, pm);
221
        vpg.releaseAST(this.fileInEditor);
222
    }
223
224
    /**
225
     * With provided strings this method builds the new AST nodes for the initial variable
226
     * assignment, increment/decrement statement, and IF DO loop break statement. They are then
227
     * inserted in to the proper hierarchy of the program AST structure. (See main refactoring
228
     * comments at the top of the file for a list of steps performed.)
229
     * 
230
     * @param ifCheckLb Lower bound (starting value) of loop variable.
231
     * @param ifCheckVar Loop control variable name.
232
     * @param ifCheckStep Loop counter variable step size (implicitly or explicitly declared)
233
     * @param ifCheckIncrDecr (+/-) Depending on loop variable count direction.
234
     * @param ifCheckStr The IF check condition to break the DO loop.
235
     */
236
    private void insertNewDoLoop(String ifCheckLb, String ifCheckVar, String ifCheckStep,
237
        String ifCheckIncrDecr, String ifCheckStr)
238
    {
239
        // Build initial value assignment node.
240
        insertInitialCounterAssignment(ifCheckVar, ifCheckLb);
241
242
        // Remove DO control
243
        int sizeOfLoopControlString = selectedDoLoopNode.getLoopHeader().getLoopControl()
244
            .toString().length();
245
        String replaceLoopControlStringWith = ""; //$NON-NLS-1$
246
        for (int i = 0; i < sizeOfLoopControlString; i++)
247
        {
248
            replaceLoopControlStringWith += " "; //$NON-NLS-1$
249
        }
250
        selectedDoLoopNode.getLoopHeader().setLoopControl(null);
251
        selectedDoLoopNode
252
            .getLoopHeader()
253
            .findLastToken()
254
            .setWhiteBefore(
255
                replaceLoopControlStringWith
256
                    + selectedDoLoopNode.getLoopHeader().findLastToken().getWhiteBefore());
257
258
        // Build increment assignment node.
259
        ASTAssignmentStmtNode incrDecrNode = insertCounterAssignment(ifCheckVar, ifCheckIncrDecr,
260
            ifCheckStep);
261
262
        // Build IF node for checking DO limits.
263
        IExecutionPartConstruct lastNodeInDoLoopBody = selectedDoLoopNode.getBody().get(
264
            selectedDoLoopNode.getBody().size() - 1);
265
        String initialIndent = ScopingNode.getLocalScope(selectedDoLoopNode).getBody()
266
            .findFirstToken().getWhiteBefore();
267
        String programString = ""; //$NON-NLS-1$
268
        programString = "program p\n" + lastNodeInDoLoopBody.findFirstToken().getWhiteBefore() //$NON-NLS-1$
269
            + "IF(" + ifCheckStr + ") THEN\n" //$NON-NLS-1$ //$NON-NLS-2$
270
            + lastNodeInDoLoopBody.findFirstToken().getWhiteBefore()
271
            + initialIndent
272
            + "EXIT\n" //$NON-NLS-1$
273
            + lastNodeInDoLoopBody.findFirstToken().getWhiteBefore()
274
            + "END IF" + EOL + "end program"; //$NON-NLS-1$ //$NON-NLS-2$
275
        ASTMainProgramNode programNode = (ASTMainProgramNode)parseLiteralProgramUnit(programString);
276
        ASTIfConstructNode ifNode = (ASTIfConstructNode)programNode.getBody().get(0);
277
278
        // Insert IF node into AST
279
        ifNode.setParent(selectedDoLoopNode.getParent());
280
        selectedDoLoopNode.getBody().insertAfter(incrDecrNode, ifNode);
281
    }
282
283
    /**
284
     * With provided strings this method builds the new AST nodes for the initial variable
285
     * assignment, increment/decrement statement, and DO WHILE loop check statement. They are then
286
     * inserted in to the proper hierarchy of the program AST structure. (See main refactoring
287
     * comments at the top of the file for a list of steps performed.)
288
     * 
289
     * @param ifCheckLb Lower bound (starting value) of loop variable.
290
     * @param ifCheckVar Loop control variable name.
291
     * @param ifCheckStep Loop counter variable step size (implicitly or explicitly declared)
292
     * @param ifCheckIncrDecr (+/-) Depending on loop variable count direction.
293
     * @param ifCheckStr The IF check condition to break the DO loop.
294
     */
295
    @SuppressWarnings("nls")
296
    private void insertNewDoWhileLoop(String ifCheckLb, String ifCheckVar, String ifCheckStep,
297
        String ifCheckIncrDecr, String ifCheckStr)
298
    {
299
        // Build initial value assignment node.
300
        insertInitialCounterAssignment(ifCheckVar, ifCheckLb);
301
302
        // Build increment assignment node.
303
        insertCounterAssignment(ifCheckVar, ifCheckIncrDecr, ifCheckStep);
304
305
        // Change do loop to while do loop
306
        String programString = "";
307
        programString = "program p\n"
308
            + selectedDoLoopNode.getLoopHeader().findFirstToken().getWhiteBefore() + "DO WHILE ("
309
            + ifCheckStr + ")"
310
            + selectedDoLoopNode.getLoopHeader().findLastToken().getWhiteBefore() + EOL
311
            + "EXIT\nENDDO" + EOL + "end program";
312
313
        ASTMainProgramNode programNode = (ASTMainProgramNode)parseLiteralProgramUnit(programString);
314
        ASTDoConstructNode doConstructNode = (ASTDoConstructNode)programNode.getBody().get(0);
315
        selectedDoLoopNode.setLoopHeader(doConstructNode.getLabelDoStmt());
316
        selectedDoLoopNode.getLoopHeader().findLastToken()
317
            .setWhiteBefore(selectedDoLoopNode.getLoopHeader().findLastToken().getWhiteBefore());
318
    }
319
320
    /**
321
     * Creates an assignment statement node for the initial loop counter value assignment and
322
     * inserts it before the selected DO loop of the refactoring.
323
     * 
324
     * @param ifCheckVar Loop control variable name.
325
     * @param ifCheckLb Lower bound (starting value) of loop variable.
326
     */
327
    private void insertInitialCounterAssignment(String ifCheckVar, String ifCheckLb)
328
    {
329
        String programString = "program p\n" + selectedDoLoopNode.findFirstToken().getWhiteBefore() + ifCheckVar + //$NON-NLS-1$
330
            " =" + ifCheckLb + EOL + "end program"; //$NON-NLS-1$ //$NON-NLS-2$
331
        ASTMainProgramNode programNode = (ASTMainProgramNode)parseLiteralProgramUnit(programString);
332
        ASTAssignmentStmtNode initValNode = (ASTAssignmentStmtNode)programNode.getBody().get(0);
333
334
        // Insert initial value assignment node into AST
335
        initValNode.setParent(selectedDoLoopNode.getParent());
336
        @SuppressWarnings("unchecked")
337
        ASTListNode<ASTNode> doNode = (ASTListNode<ASTNode>)selectedDoLoopNode.getParent();
338
        doNode.insertBefore(selectedDoLoopNode, initValNode);
339
    }
340
341
    /**
342
     * Creates an assignment statement node for the loop counter variable assignment and inserts it
343
     * after the selected DO loop of the refactoring.
344
     * 
345
     * @param ifCheckVar Loop control variable name.
346
     * @param ifCheckIncrDecr (+/-) Depending on loop variable count direction.
347
     * @param ifCheckStep Loop counter variable step size (implicitly or explicitly declared)
348
     */
349
    private ASTAssignmentStmtNode insertCounterAssignment(String ifCheckVar,
350
        String ifCheckIncrDecr, String ifCheckStep)
351
    {
352
        IExecutionPartConstruct lastNodeInDoLoopBody = selectedDoLoopNode.getBody().get(
353
            selectedDoLoopNode.getBody().size() - 1);
354
        String programString = ""; //$NON-NLS-1$
355
        programString = "program p\n" + lastNodeInDoLoopBody.findFirstToken().getWhiteBefore() + ifCheckVar + //$NON-NLS-1$
356
            " = " + ifCheckVar + ifCheckIncrDecr + ifCheckStep + EOL + "end program"; //$NON-NLS-1$ //$NON-NLS-2$
357
        ASTMainProgramNode programNode = (ASTMainProgramNode)parseLiteralProgramUnit(programString);
358
        ASTAssignmentStmtNode incrDecrNode = (ASTAssignmentStmtNode)programNode.getBody().get(0);
359
360
        // Insert increment/decrement assignment node into AST
361
        incrDecrNode.setParent(selectedDoLoopNode.getParent());
362
363
        selectedDoLoopNode.getBody().insertAfter(lastNodeInDoLoopBody, incrDecrNode);
364
365
        return incrDecrNode;
366
    }
367
368
    /**
369
     * Get all variable type declarations in the program.
370
     * 
371
     * @param startNode node to start search.
372
     * 
373
     * @return LinkedList of type declarations nodes.
374
     */
375
    private LinkedList<ASTTypeDeclarationStmtNode> getTypeDeclarations(IASTNode startNode)
376
    {
377
        if (startNode == null) { return null; }
378
379
        final LinkedList<ASTTypeDeclarationStmtNode> typeDeclarations = new LinkedList<ASTTypeDeclarationStmtNode>();
380
381
        startNode.accept(new ASTVisitor()
382
        {
383
            @Override
384
            public void visitASTTypeDeclarationStmtNode(ASTTypeDeclarationStmtNode node)
385
            {
386
                typeDeclarations.add(node);
387
            }
388
        });
389
390
        return typeDeclarations;
391
    }
392
}
(-)src/org/eclipse/photran/internal/core/refactoring/infrastructure/FortranResourceRefactoring.java (+26 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *    UIUC - Initial API and implementation
9
 *    UIUC - Initial API and implementation
10
 *    Rita Chow - Photran Modifications
11
 *    Nicola Hall - Photran Modifications
12
 *    Jerry Hsiao - Photran Modifications
13
 *    Mark Mozolewski - Photran Modifications
14
 *    Chamil Wijenayaka - Photran Modifications
10
 *******************************************************************************/
15
 *******************************************************************************/
11
package org.eclipse.photran.internal.core.refactoring.infrastructure;
16
package org.eclipse.photran.internal.core.refactoring.infrastructure;
12
17
Lines 373-378 Link Here
373
        return null;
378
        return null;
374
    }
379
    }
375
380
381
    /**
382
     * Get node based on type.
383
     * 
384
     * @param startNode node to start search.
385
     * @param typeChecker instance type to search.
386
     * 
387
     * @return node if found else null.
388
     */
389
    protected IASTNode findEnclosingNodeOfType(IASTNode startNode, Class classType)
390
    {
391
        if(startNode == null) { return null; }
392
393
        IASTNode node = startNode;
394
        while ((node != null) && (node.getClass() != classType))
395
        {
396
             node = node.getParent();
397
        }
398
399
        return node;
400
    }
401
376
    protected static boolean nodeExactlyEnclosesRegion(IASTNode parent, Token firstToken, Token lastToken)
402
    protected static boolean nodeExactlyEnclosesRegion(IASTNode parent, Token firstToken, Token lastToken)
377
    {
403
    {
378
        return parent.findFirstToken() == firstToken && parent.findLastToken() == lastToken;
404
        return parent.findFirstToken() == firstToken && parent.findLastToken() == lastToken;
(-)src/org/eclipse/photran/internal/tests/refactoring/RemoveBranchToEndIfTestSuite.java (+45 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Rita Chow, Nicola Hall, Jerry Hsiao, Mark Mozolewski, Chamil Wijenayaka
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    Rita Chow - Initial Implementation
10
 *    Nicola Hall - Initial Implementation
11
 *    Jerry Hsiao - Initial Implementation
12
 *    Mark Mozolewski - Initial Implementation
13
 *    Chamil Wijenayaka - Initial Implementation
14
 *******************************************************************************/
15
package org.eclipse.photran.internal.tests.refactoring;
16
17
import junit.framework.Test;
18
19
import org.eclipse.photran.internal.core.refactoring.RemoveBranchToEndIfRefactoring;
20
import org.eclipse.photran.internal.tests.Activator;
21
import org.eclipse.photran.internal.tests.PhotranRefactoringTestSuiteFromMarkers;
22
23
/**
24
 * Unit tests for the Remove Branch To End If Refactoring.
25
 *
26
 * @author 
27
 */
28
public class RemoveBranchToEndIfTestSuite extends PhotranRefactoringTestSuiteFromMarkers<RemoveBranchToEndIfRefactoring>
29
{
30
    private static final String DIR = "refactoring-test-code/remove-branch-to-end-if";
31
32
    public static Test suite() throws Exception
33
    {
34
        return new RemoveBranchToEndIfTestSuite();
35
    }
36
37
    public RemoveBranchToEndIfTestSuite() throws Exception
38
    {
39
        super(Activator.getDefault(),
40
              "Running Remove Branch To End If Refactoring in",
41
              DIR,
42
              RemoveBranchToEndIfRefactoring.class);
43
    }
44
    
45
}
(-)src/org/eclipse/photran/internal/tests/refactoring/RemovePauseStmtTestSuite.java (+45 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Rita Chow, Nicola Hall, Jerry Hsiao, Mark Mozolewski, Chamil Wijenayaka
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    Rita Chow - Initial Implementation
10
 *    Nicola Hall - Initial Implementation
11
 *    Jerry Hsiao - Initial Implementation
12
 *    Mark Mozolewski - Initial Implementation
13
 *    Chamil Wijenayaka - Initial Implementation
14
 *******************************************************************************/
15
package org.eclipse.photran.internal.tests.refactoring;
16
17
import junit.framework.Test;
18
19
import org.eclipse.photran.internal.core.refactoring.RemovePauseStmtRefactoring;
20
import org.eclipse.photran.internal.tests.Activator;
21
import org.eclipse.photran.internal.tests.PhotranRefactoringTestSuiteFromMarkers;
22
23
/**
24
 * Unit tests for the Remove Pause Statement Refractoring.
25
 *
26
 * @author 
27
 */
28
public class RemovePauseStmtTestSuite extends PhotranRefactoringTestSuiteFromMarkers<RemovePauseStmtRefactoring>
29
{
30
    private static final String DIR = "refactoring-test-code/remove-pause-stmt";
31
32
    public static Test suite() throws Exception
33
    {
34
        return new RemovePauseStmtTestSuite();
35
    }
36
37
    public RemovePauseStmtTestSuite() throws Exception
38
    {
39
        super(Activator.getDefault(),
40
              "Running Remove Pause Stmt Refactoring in",
41
              DIR,
42
              RemovePauseStmtRefactoring.class);
43
    }
44
    
45
}
(-)src/org/eclipse/photran/internal/tests/refactoring/RemoveRealAndDoublePrecisionLoopCountersTestSuite.java (+64 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Rita Chow, Nicola Hall, Jerry Hsiao, Mark Mozolewski, Chamil Wijenayaka
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    Rita Chow - Initial Implementation
10
 *    Nicola Hall - Initial Implementation
11
 *    Jerry Hsiao - Initial Implementation
12
 *    Mark Mozolewski - Initial Implementation
13
 *    Chamil Wijenayaka - Initial Implementation
14
 *******************************************************************************/
15
package org.eclipse.photran.internal.tests.refactoring;
16
17
import junit.framework.Test;
18
19
import org.eclipse.core.resources.IFile;
20
import org.eclipse.jface.text.TextSelection;
21
import org.eclipse.photran.internal.core.refactoring.RemoveRealAndDoublePrecisionLoopCountersRefactoring;
22
import org.eclipse.photran.internal.tests.Activator;
23
import org.eclipse.photran.internal.tests.PhotranRefactoringTestSuiteFromMarkers;
24
25
/**
26
 * Unit tests for the Remove Branch To End If Refactoring.
27
 *
28
 * @author 
29
 */
30
public class RemoveRealAndDoublePrecisionLoopCountersTestSuite extends PhotranRefactoringTestSuiteFromMarkers<RemoveRealAndDoublePrecisionLoopCountersRefactoring>
31
{
32
    private static final String DIR = "refactoring-test-code/remove-real-and-double-precision-loop-counters";
33
34
    public static Test suite() throws Exception
35
    {
36
        return new RemoveRealAndDoublePrecisionLoopCountersTestSuite();
37
    }
38
39
    public RemoveRealAndDoublePrecisionLoopCountersTestSuite() throws Exception
40
    {
41
        super(Activator.getDefault(),
42
              "Running Remove Real and Double Precision Loop Counters Refactoring in",
43
              DIR,
44
              RemoveRealAndDoublePrecisionLoopCountersRefactoring.class);
45
    }
46
    
47
    @Override
48
    protected boolean configureRefactoring(RemoveRealAndDoublePrecisionLoopCountersRefactoring refactoring,
49
                                           IFile file,
50
                                           TextSelection selection,
51
                                           String[] markerText)
52
    {
53
        boolean shouldSucceed = super.configureRefactoring(refactoring, file, selection, markerText);
54
55
        boolean shouldReplaceWithDoWhileLoop;
56
        if(markerText[4].equals("1"))
57
            shouldReplaceWithDoWhileLoop = true;
58
        else
59
            shouldReplaceWithDoWhileLoop = false;
60
        refactoring.setShouldReplaceWithDoWhileLoop(shouldReplaceWithDoWhileLoop);
61
62
        return shouldSucceed;
63
    }
64
}
(-)plugin.xml (+10 lines)
Lines 83-88 Link Here
83
         <editorRefactoring
83
         <editorRefactoring
84
         	class="org.eclipse.photran.internal.core.refactoring.RemoveComputedGoToRefactoring"
84
         	class="org.eclipse.photran.internal.core.refactoring.RemoveComputedGoToRefactoring"
85
         />
85
         />
86
         <editorRefactoring
87
         	class="org.eclipse.photran.internal.core.refactoring.RemoveBranchToEndIfRefactoring"
88
         />
89
         <editorRefactoring
90
            class="org.eclipse.photran.internal.core.refactoring.RemoveRealAndDoublePrecisionLoopCountersRefactoring"
91
            inputPage="org.eclipse.photran.internal.ui.refactoring.RemoveRealAndDoublePrecisionLoopCountersInputPage"
92
         />
93
         <editorRefactoring
94
         	class="org.eclipse.photran.internal.core.refactoring.RemovePauseStmtRefactoring"
95
         />
86
      </group>
96
      </group>
87
      <group><!-- Refactorings for performance/loop transformations -->
97
      <group><!-- Refactorings for performance/loop transformations -->
88
         <editorRefactoring
98
         <editorRefactoring
(-)src/org/eclipse/photran/internal/ui/refactoring/Messages.java (+16 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *    UIUC - Initial API and implementation
9
 *    UIUC - Initial API and implementation
10
 *    Rita Chow - Photran Modifications
11
 *    Nicola Hall - Photran Modifications
12
 *    Jerry Hsiao - Photran Modifications
13
 *    Mark Mozolewski - Photran Modifications
14
 *    Chamil Wijenayaka - Photran Modifications
10
 *******************************************************************************/
15
 *******************************************************************************/
11
package org.eclipse.photran.internal.ui.refactoring;
16
package org.eclipse.photran.internal.ui.refactoring;
12
17
Lines 84-89 Link Here
84
    public static String RenameAction_MatchExternalSubprograms;
89
    public static String RenameAction_MatchExternalSubprograms;
85
90
86
    public static String RenameAction_RenameAtoB;
91
    public static String RenameAction_RenameAtoB;
92
    
93
    public static String RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceRealDoublePrecisionLoopCounter;
94
95
    public static String RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceWithDoLoop;
96
    
97
    public static String RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceWithDoWhileLoop;
98
    
99
    public static String RemoveRealAndDoublePrecisionLoopCountersInputPage_ClickOKMessage;
100
    
101
    public static String RemoveRealAndDoublePrecisionLoopCountersInputPage_ClickPreviewMessage;
102
    
87
    static
103
    static
88
    {
104
    {
89
        // initialize resource bundle
105
        // initialize resource bundle
(-)src/org/eclipse/photran/internal/ui/refactoring/RemoveRealAndDoublePrecisionLoopCountersInputPage.java (+75 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Rita Chow, Nicola Hall, Jerry Hsiao, Mark Mozolewski, Chamil Wijenayaka
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    Rita Chow - Initial Implementation
10
 *    Nicola Hall - Initial Implementation
11
 *    Jerry Hsiao - Initial Implementation
12
 *    Mark Mozolewski - Initial Implementation
13
 *    Chamil Wijenayaka - Initial Implementation
14
 *******************************************************************************/
15
package org.eclipse.photran.internal.ui.refactoring;
16
17
import org.eclipse.photran.internal.core.refactoring.RemoveRealAndDoublePrecisionLoopCountersRefactoring;
18
import org.eclipse.rephraserengine.ui.refactoring.CustomUserInputPage;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.events.SelectionEvent;
21
import org.eclipse.swt.events.SelectionListener;
22
import org.eclipse.swt.layout.GridLayout;
23
import org.eclipse.swt.widgets.Button;
24
import org.eclipse.swt.widgets.Composite;
25
import org.eclipse.swt.widgets.Label;
26
27
/**
28
 * User input wizard page for the Change Keyword Case refactoring
29
 *
30
 * @author Kurt Hendle, Jeff Overbey
31
 */
32
public class RemoveRealAndDoublePrecisionLoopCountersInputPage extends CustomUserInputPage<RemoveRealAndDoublePrecisionLoopCountersRefactoring>
33
{
34
    protected Button doWhileLoop;
35
    protected Button doLoop;
36
37
    @Override
38
    public void createControl(Composite parent)
39
    {
40
        Composite top = new Composite(parent, SWT.NONE);
41
        initializeDialogUnits(top);
42
        setControl(top);
43
44
        top.setLayout(new GridLayout(1, false));
45
46
        Composite group = top;
47
        Label instr = new Label(group, SWT.NONE);
48
        instr.setText(Messages.RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceRealDoublePrecisionLoopCounter);
49
50
        doWhileLoop = new Button(group, SWT.RADIO);
51
        doWhileLoop.setText(Messages.RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceWithDoLoop);
52
        doWhileLoop.setSelection(true);
53
        doWhileLoop.addSelectionListener(new SelectionListener()
54
        {
55
            public void widgetDefaultSelected(SelectionEvent e)
56
            {
57
                widgetSelected(e);
58
            }
59
60
            public void widgetSelected(SelectionEvent e)
61
            {
62
                boolean isChecked = doLoop.getSelection();
63
                getRefactoring().setShouldReplaceWithDoWhileLoop(isChecked);
64
            }
65
        });
66
67
        doLoop = new Button(group, SWT.RADIO);
68
        doLoop.setText(Messages.RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceWithDoWhileLoop);
69
70
        Label ok = new Label(group, SWT.NONE);
71
        ok.setText("\n" + Messages.RemoveRealAndDoublePrecisionLoopCountersInputPage_ClickOKMessage); //$NON-NLS-1$
72
        Label preview = new Label(group, SWT.NONE);
73
        preview.setText(Messages.RemoveRealAndDoublePrecisionLoopCountersInputPage_ClickPreviewMessage);
74
    }
75
}
(-)src/org/eclipse/photran/internal/ui/refactoring/messages.properties (+5 lines)
Lines 31-33 Link Here
31
MoveFromModuleInputPage_selectDataMessage=Please select member data to move from module 
31
MoveFromModuleInputPage_selectDataMessage=Please select member data to move from module 
32
RenameAction_MatchExternalSubprograms=Match external subprograms with interfaces and external declarations
32
RenameAction_MatchExternalSubprograms=Match external subprograms with interfaces and external declarations
33
RenameAction_RenameAtoB=Rename {0} to
33
RenameAction_RenameAtoB=Rename {0} to
34
RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceRealDoublePrecisionLoopCounter=Replace real/double precision loop counter with:
35
RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceWithDoLoop=DO Loop
36
RemoveRealAndDoublePrecisionLoopCountersInputPage_ReplaceWithDoWhileLoop=DO WHILE Loop
37
RemoveRealAndDoublePrecisionLoopCountersInputPage_ClickOKMessage=Click OK to replace the real/double precision loop counter.
38
RemoveRealAndDoublePrecisionLoopCountersInputPage_ClickPreviewMessage=To see what the changes will be made, click Preview.

Return to bug 332492