diff options
author | Jeffrey Overbey | 2012-05-08 17:38:38 +0000 |
---|---|---|
committer | Jeffrey Overbey | 2012-05-08 17:38:38 +0000 |
commit | e96af388aa653377a2c71294830fc4d23232055a (patch) | |
tree | a242ecfc191803f43923a860512f6dd9d76adcf7 | |
parent | 1ab302ef8cb8c56d66987cf1dd37a7fbff1e9e9c (diff) | |
download | org.eclipse.photran-e96af388aa653377a2c71294830fc4d23232055a.tar.gz org.eclipse.photran-e96af388aa653377a2c71294830fc4d23232055a.tar.xz org.eclipse.photran-e96af388aa653377a2c71294830fc4d23232055a.zip |
Bug 347191 - Correct Indentation handles line continuations incorrectly
7 files changed, 100 insertions, 20 deletions
diff --git a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/06-continuation-test.f90.result b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/06-continuation-test.f90.result index b5849809..97afea1a 100644 --- a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/06-continuation-test.f90.result +++ b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/06-continuation-test.f90.result @@ -1,6 +1,6 @@ program continuation !<<<<<START implicit none print & - *,& - "work" + *,& + "work" end program continuation !<<<<<END diff --git a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90 b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90 index d5b668ce..515ffaeb 100644 --- a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90 +++ b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90 @@ -2,6 +2,13 @@ program print *, & "Hello" + print *, 1 & + 2, & + &3, & + & 4, & + & 5,& + 6, & + 7 end& program program diff --git a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90.result b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90.result index 51552b8d..c6e5607c 100644 --- a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90.result +++ b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/12-line-continuations.f90.result @@ -1,17 +1,24 @@ program & !<<<<<START -program + program print *, & - "Hello" + "Hello" + print *, 1 & + 2, & + &3, & + & 4, & + & 5,& + 6, & + 7 end& -program program + program program subroutine s integer :: i do i = 3, 4 do j =& - 5, 6 + 5, 6 print *, i + j end do end& - do + do end subroutine !<<<<<END diff --git a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/13-bug-347191.f90 b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/13-bug-347191.f90 new file mode 100644 index 00000000..96c1687f --- /dev/null +++ b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/13-bug-347191.f90 @@ -0,0 +1,5 @@ +program program +print *, 1, & + & 2 +print *, 3 !<<<<<START !<<<<<END +end diff --git a/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/13-bug-347191.f90.result b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/13-bug-347191.f90.result new file mode 100644 index 00000000..863906fc --- /dev/null +++ b/org.eclipse.photran.core.vpg.tests/refactoring-test-code/infrastructure/reindenter/13-bug-347191.f90.result @@ -0,0 +1,5 @@ +program program + print *, 1, & + & 2 + print *, 3 !<<<<<START !<<<<<END +end diff --git a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/ReindentEachLineVisitor.java b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/ReindentEachLineVisitor.java index 2c676735..b9c021d8 100644 --- a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/ReindentEachLineVisitor.java +++ b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/ReindentEachLineVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 University of Illinois at Urbana-Champaign and others. + * Copyright (c) 2010, 2012 University of Illinois at Urbana-Champaign and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -22,10 +22,10 @@ import org.eclipse.photran.internal.core.reindenter.Reindenter.Strategy; * @author Rui Wang */ final class ReindentEachLineVisitor extends ReindentingVisitor -{ +{ private StartOfLine previousLine; private String previousIndentation; - + protected ReindentEachLineVisitor(IFortranAST ast, Token firstTokenInRegion, Token lastTokenInRegion) { super(ast, firstTokenInRegion, lastTokenInRegion); @@ -43,13 +43,14 @@ final class ReindentEachLineVisitor extends ReindentingVisitor final String newIndentation = computeNewIndentation(currentLine); currentLine.reindent(currentIndentation, newIndentation); - + // Lines with labels tend to have atypical indentation (heuristically), // so try to avoid using them to compute the next line's indentation // (unless we're the first line in the file or the first line in a // DO-construct, IF-construct, etc.) if (!currentLine.hasLabel() || previousLine == null || previousLine.startsIndentedRegion() || currentLine.endsIndentedRegion()) - this.previousIndentation = currentLine.getIndentation(); + if (!currentLine.isContinuationLine()) + this.previousIndentation = currentLine.getIndentation(); this.previousLine = currentLine; } @@ -58,12 +59,13 @@ final class ReindentEachLineVisitor extends ReindentingVisitor { if (previousLine == null) // currentLine is the line in the file return ""; //$NON-NLS-1$ + else if (currentLine.isContinuationLine()) + return StartOfLine.getIncreasedIndentation(previousIndentation) + currentLine.getContinuationPrefix(); else if (previousLine.startsIndentedRegion() && !currentLine.isContinuationLine() && !currentLine.endsIndentedRegion()) return StartOfLine.getIncreasedIndentation(previousIndentation); else if (currentLine.endsDoublyIndentedRegion() && !previousLine.startsIndentedRegion()) return StartOfLine.getDecreasedIndentation(StartOfLine.getDecreasedIndentation(previousIndentation)); else if (currentLine.isEndDoStmt() && previousLine.isContinueStmt()) - //|| currentLine.isContinueStmt() && previousLine.isEndDoStmt()) return previousIndentation; else if (currentLine.endsIndentedRegion() && !previousLine.startsIndentedRegion() || currentLine.endsDoublyIndentedRegion() && previousLine.startsIndentedRegion()) diff --git a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/StartOfLine.java b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/StartOfLine.java index 2f15b0e0..a5dff58d 100644 --- a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/StartOfLine.java +++ b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/StartOfLine.java @@ -15,6 +15,8 @@ import static org.eclipse.photran.internal.core.reindenter.Reindenter.defaultInd import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.photran.core.IFortranAST; import org.eclipse.photran.internal.core.lexer.Terminal; @@ -284,16 +286,37 @@ final class StartOfLine public String getIndentation() { + String result = getFinalLineOfWhitetext(); + result = replaceLabelAtBeginningOfLineWithSpaces(result); + result = removeTrailingContinuationPrefix(result); + return result; + } + + private String getFinalLineOfWhitetext() + { String whiteText = getFirstTokenOnLine().getWhiteBefore(); - int lastCR = whiteText.lastIndexOf('\n'); - String result = whiteText.substring(lastCR + 1); - if (result.equals("") && getFirstTokenOnLine() == label) //$NON-NLS-1$ + int lastLF = whiteText.lastIndexOf('\n'); + return whiteText.substring(lastLF + 1); + } + + private String replaceLabelAtBeginningOfLineWithSpaces(String finalLineOfWhiteText) + { + if (finalLineOfWhiteText.equals("") && getFirstTokenOnLine() == label) //$NON-NLS-1$ { - whiteText = spaces(label.getText().length()) + firstStmtToken.getWhiteBefore(); - lastCR = whiteText.lastIndexOf('\n'); - result = whiteText.substring(lastCR + 1); + String newWhiteText = spaces(label.getText().length()) + firstStmtToken.getWhiteBefore(); + int lastCR = newWhiteText.lastIndexOf('\n'); + finalLineOfWhiteText = newWhiteText.substring(lastCR + 1); } - return result; + return finalLineOfWhiteText; + } + + private String removeTrailingContinuationPrefix(String string) + { + Matcher matcher = CONTINUATION_PREFIX.matcher(string); + if (matcher.find()) + return string.substring(0, matcher.start()); + else + return string; } private String spaces(int count) @@ -469,4 +492,35 @@ final class StartOfLine { return firstStmtToken.findNearestAncestor(ASTContinueStmtNode.class) != null; } + + /** + * See {@link #getContinuationPrefix()}. Matches an ampersand and zero or more spaces + * at the end of a string. + */ + private static final Pattern CONTINUATION_PREFIX = Pattern.compile("&[ \t]*$"); //$NON-NLS-1$ + + /** + * If a line is a continuation of a previous line, and it begins with an ampersand, returns + * the substring beginning with that ampersand. + * <p> + * For example, when invoked on the second line of this input: + * <pre> + * call subroutine(1, 2, & + * & 3, 4) + * </pre> + * this method returns "& " (i.e., the ampersand and space preceding the 3). + * + * @return the second ampersand and any trailing spaces/tabs appearing at the beginning of + * a continuation line, or the empty string if there is no second ampersand for the + * continuation (or if this is not a continuation line). + */ + public String getContinuationPrefix() + { + final String finalLineOfWhitetext = getFinalLineOfWhitetext(); + final Matcher matcher = CONTINUATION_PREFIX.matcher(finalLineOfWhitetext); + if (matcher.find()) + return matcher.group(); + else + return ""; //$NON-NLS-1$ + } }
\ No newline at end of file |