You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by jo...@apache.org on 2021/11/15 23:04:49 UTC

[royale-compiler] 01/05: formatter: disable and re-enable formatting with comments

This is an automated email from the ASF dual-hosted git repository.

joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git

commit 6e2657111e61d4b70502beafb3e5f26d561f0942
Author: Josh Tynjala <jo...@apache.org>
AuthorDate: Mon Nov 15 11:33:43 2021 -0800

    formatter: disable and re-enable formatting with comments
    
    Uses // @formatter:off and // @formatter:on
---
 .../org/apache/royale/formatter/FORMATTER.java     | 88 +++++++++++++++-------
 .../apache/royale/formatter/TestFormatterOff.java  | 72 ++++++++++++++++++
 2 files changed, 132 insertions(+), 28 deletions(-)

diff --git a/formatter/src/main/java/org/apache/royale/formatter/FORMATTER.java b/formatter/src/main/java/org/apache/royale/formatter/FORMATTER.java
index dace35d..d4a8935 100644
--- a/formatter/src/main/java/org/apache/royale/formatter/FORMATTER.java
+++ b/formatter/src/main/java/org/apache/royale/formatter/FORMATTER.java
@@ -79,6 +79,8 @@ public class FORMATTER {
 	private static final String DEFAULT_VAR = "files";
 	private static final String L10N_CONFIG_PREFIX = "org.apache.royale.compiler.internal.config.configuration";
 	private static final Pattern ASDOC_START_LINE_PATTERN = Pattern.compile("^\\*(\\s*)");
+	private static final String FORMATTER_TAG_OFF = "@formatter:off";
+	private static final String FORMATTER_TAG_ON = "@formatter:on";
 
 	static enum ExitCode {
 		SUCCESS(0), PRINT_HELP(1), FAILED_WITH_PROBLEMS(2), FAILED_WITH_EXCEPTIONS(3), FAILED_WITH_CONFIG_PROBLEMS(4);
@@ -658,6 +660,7 @@ public class FORMATTER {
 		boolean blockOpenPending = false;
 		boolean indentedStatement = false;
 		boolean caseOrDefaultBlockOpenPending = false;
+		boolean skipFormatting = false;
 		List<BlockStackItem> blockStack = new ArrayList<BlockStackItem>();
 		int controlFlowParenStack = 0;
 		int ternaryStack = 0;
@@ -674,30 +677,34 @@ public class FORMATTER {
 		for (int i = 0; i < tokens.size(); i++) {
 			token = tokens.get(i);
 			if (token.getType() == TOKEN_TYPE_EXTRA) {
-				if (i == (tokens.size() - 1)) {
-					// if the last token is whitespace, include new lines
-					numRequiredNewLines = Math.max(0, countNewLinesInExtra(token));
-					appendNewLines(builder, numRequiredNewLines);
-					break;
-				}
-				if (!blockOpenPending) {
-					int newLinesInExtra = countNewLinesInExtra(token);
-					if (prevToken != null && prevToken.getType() == ASTokenTypes.HIDDEN_TOKEN_SINGLE_LINE_COMMENT) {
-						newLinesInExtra++;
-					}
-					numRequiredNewLines = Math.max(numRequiredNewLines, newLinesInExtra);
-					if (!indentedStatement && numRequiredNewLines > 0 && prevTokenNotComment != null
-							&& prevTokenNotComment.getType() != ASTokenTypes.TOKEN_SEMICOLON
-							&& prevTokenNotComment.getType() != ASTokenTypes.TOKEN_BLOCK_CLOSE
-							&& !(caseOrDefaultBlockOpenPending
-									&& prevTokenNotComment.getType() == ASTokenTypes.TOKEN_COLON)
-							&& !(prevTokenNotComment instanceof MetaDataPayloadToken)) {
-						boolean needsIndent = prevTokenNotComment.getType() != ASTokenTypes.TOKEN_BLOCK_OPEN
-								|| (!blockStack.isEmpty() && blockStack
-										.get(blockStack.size() - 1) instanceof ObjectLiteralBlockStackItem);
-						if (needsIndent) {
-							indentedStatement = true;
-							indent = increaseIndent(indent);
+				if (skipFormatting) {
+					builder.append(token.getText());
+				} else {
+					if (i == (tokens.size() - 1)) {
+						// if the last token is whitespace, include new lines
+						numRequiredNewLines = Math.max(0, countNewLinesInExtra(token));
+						appendNewLines(builder, numRequiredNewLines);
+						break;
+					}
+					if (!blockOpenPending) {
+						int newLinesInExtra = countNewLinesInExtra(token);
+						if (prevToken != null && prevToken.getType() == ASTokenTypes.HIDDEN_TOKEN_SINGLE_LINE_COMMENT) {
+							newLinesInExtra++;
+						}
+						numRequiredNewLines = Math.max(numRequiredNewLines, newLinesInExtra);
+						if (!indentedStatement && numRequiredNewLines > 0 && prevTokenNotComment != null
+								&& prevTokenNotComment.getType() != ASTokenTypes.TOKEN_SEMICOLON
+								&& prevTokenNotComment.getType() != ASTokenTypes.TOKEN_BLOCK_CLOSE
+								&& !(caseOrDefaultBlockOpenPending
+										&& prevTokenNotComment.getType() == ASTokenTypes.TOKEN_COLON)
+								&& !(prevTokenNotComment instanceof MetaDataPayloadToken)) {
+							boolean needsIndent = prevTokenNotComment.getType() != ASTokenTypes.TOKEN_BLOCK_OPEN
+									|| (!blockStack.isEmpty() && blockStack
+											.get(blockStack.size() - 1) instanceof ObjectLiteralBlockStackItem);
+							if (needsIndent) {
+								indentedStatement = true;
+								indent = increaseIndent(indent);
+							}
 						}
 					}
 				}
@@ -802,10 +809,23 @@ public class FORMATTER {
 					case ASTokenTypes.TOKEN_RESERVED_WORD_EACH:
 					case ASTokenTypes.TOKEN_RESERVED_WORD_EXTENDS:
 					case ASTokenTypes.TOKEN_RESERVED_WORD_IMPLEMENTS:
-					case ASTokenTypes.HIDDEN_TOKEN_MULTI_LINE_COMMENT:
+					case ASTokenTypes.HIDDEN_TOKEN_MULTI_LINE_COMMENT: {
+						// needs an extra space before the token
+						requiredSpace = true;
+						break;
+					}
 					case ASTokenTypes.HIDDEN_TOKEN_SINGLE_LINE_COMMENT: {
 						// needs an extra space before the token
 						requiredSpace = true;
+
+						String trimmed = token.getText().substring(2).trim();
+						if (!skipFormatting && FORMATTER_TAG_OFF.equals(trimmed)) {
+							skipFormatting = true;
+						} else if (skipFormatting && FORMATTER_TAG_ON.equals(trimmed)) {
+							skipFormatting = false;
+							numRequiredNewLines = 0;
+							requiredSpace = false;
+						}
 						break;
 					}
 					case ASTokenTypes.TOKEN_OPERATOR_EQUAL:
@@ -932,7 +952,7 @@ public class FORMATTER {
 					}
 				}
 			}
-			if (prevToken != null) {
+			if (!skipFormatting && prevToken != null) {
 				if (numRequiredNewLines > 0) {
 					appendNewLines(builder, numRequiredNewLines);
 					appendIndent(builder, indent);
@@ -953,7 +973,7 @@ public class FORMATTER {
 			}
 
 			// include the token's own text
-			builder.append(getTokenText(token, indent));
+			builder.append(getTokenText(token, indent, skipFormatting));
 
 			// characters that must appear after the token
 			if (token.getType() != ASTokenTypes.HIDDEN_TOKEN_SINGLE_LINE_COMMENT
@@ -1462,7 +1482,7 @@ public class FORMATTER {
 		return builder.toString();
 	}
 
-	private String getTokenText(IASToken token, int indent) {
+	private String getTokenText(IASToken token, int indent, boolean skipFormatting) {
 
 		if (token instanceof MetaDataPayloadToken) {
 			MetaDataPayloadToken metaPlayloadToken = (MetaDataPayloadToken) token;
@@ -1470,18 +1490,30 @@ public class FORMATTER {
 		} else {
 			switch (token.getType()) {
 				case ASTokenTypes.TOKEN_ASDOC_COMMENT: {
+					if (skipFormatting) {
+						return token.getText();
+					}
 					return formatASDocComment(token.getText(), indent);
 				}
 				case ASTokenTypes.HIDDEN_TOKEN_SINGLE_LINE_COMMENT: {
+					if (skipFormatting) {
+						return token.getText();
+					}
 					return formatSingleLineComment(token.getText());
 				}
 				case ASTokenTypes.HIDDEN_TOKEN_MULTI_LINE_COMMENT: {
+					if (skipFormatting) {
+						return token.getText();
+					}
 					return formatMultiLineComment(token.getText());
 				}
 				case ASTokenTypes.TOKEN_LITERAL_STRING: {
 					return formatLiteralString(token.getText());
 				}
 				case ASTokenTypes.TOKEN_SEMICOLON: {
+					if (skipFormatting) {
+						return token.isImplicit() ? "" : token.getText();
+					}
 					boolean skipSemicolon = Semicolons.REMOVE.equals(semicolons)
 							|| (Semicolons.IGNORE.equals(semicolons) && token.isImplicit());
 					if (!skipSemicolon) {
diff --git a/formatter/src/test/java/org/apache/royale/formatter/TestFormatterOff.java b/formatter/src/test/java/org/apache/royale/formatter/TestFormatterOff.java
new file mode 100644
index 0000000..c0c8f9b
--- /dev/null
+++ b/formatter/src/test/java/org/apache/royale/formatter/TestFormatterOff.java
@@ -0,0 +1,72 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.royale.formatter;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class TestFormatterOff extends BaseFormatterTests {
+	@Test
+	public void testFormatterOff() {
+		FORMATTER formatter = new FORMATTER();
+		formatter.insertSpaceAfterKeywordsInControlFlowStatements = true;
+		formatter.placeOpenBraceOnNewLine = true;
+		formatter.insertSpaces = true;
+		formatter.tabSize = 2;
+		formatter.maxPreserveNewLines = 2;
+		String result = formatter.formatActionScriptText(
+		// @formatter:off
+			"// @formatter:off\n" +
+			"for(var i:int=0;i<3;i++){\n" +
+			"\ttrace(i)//print to console\n" +
+			"\n" +
+			"\n" +
+			"\n" +
+			"}\n" +
+			"// @formatter:on\n" +
+			"for(var i:int=0;i<3;i++){\n" +
+			"\ttrace(i)//print to console\n" +
+			"\n" +
+			"\n" +
+			"\n" +
+			"}",
+			// @formatter:on
+			problems
+		);
+		assertEquals(
+		// @formatter:off
+				"// @formatter:off\n" +
+				"for(var i:int=0;i<3;i++){\n" +
+				"\ttrace(i)//print to console\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"}\n" +
+				"// @formatter:on\n" +
+				"for (var i:int = 0; i < 3; i++)\n" +
+				"{\n" +
+				"  trace(i); // print to console\n" +
+				"\n" +
+				"}",
+				// @formatter:on
+				result);
+	}
+}
\ No newline at end of file