You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2018/03/19 22:42:44 UTC
[1/2] incubator-freemarker git commit: Forward ported from 2.3-gae:
Some more cleanup in FTL.jj
Repository: incubator-freemarker
Updated Branches:
refs/heads/3 6e61c1d60 -> 0d21cbb77
Forward ported from 2.3-gae: Some more cleanup in FTL.jj
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/348e73dc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/348e73dc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/348e73dc
Branch: refs/heads/3
Commit: 348e73dc61f90af24ebe01e31b1db83a1b966517
Parents: 6e61c1d
Author: ddekany <dd...@apache.org>
Authored: Mon Mar 19 00:25:26 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Mon Mar 19 00:25:26 2018 +0100
----------------------------------------------------------------------
.../core/InterpolationSyntaxTest.java | 1 +
freemarker-core/src/main/javacc/FTL.jj | 35 +++++++++++---------
2 files changed, 21 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/348e73dc/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
index e6b0eeb..4d7d0cc 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
@@ -90,6 +90,7 @@ public class InterpolationSyntaxTest extends TemplateTest {
assertErrorContains("[=", "end of file");
assertErrorContains("[=1", "unclosed \"[\"");
+ assertErrorContains("[=1}", "\"}\"", "open");
assertOutput("[='[\\=1]']", "[=1]");
assertOutput("[='[\\=1][=2]']", "12"); // Usual legacy interpolation escaping glitch...
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/348e73dc/freemarker-core/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/javacc/FTL.jj b/freemarker-core/src/main/javacc/FTL.jj
index 8da0768..76b32f5 100644
--- a/freemarker-core/src/main/javacc/FTL.jj
+++ b/freemarker-core/src/main/javacc/FTL.jj
@@ -527,7 +527,7 @@ TOKEN_MGR_DECLS:
* Keeps track of how deeply nested we have the hash literals. This is necessary since we need to be able to
* distinguish the } used to close a hash literal and the one used to close a ${
*/
- private int hashLiteralNesting;
+ private int curlyBracketNesting;
private int parenthesisNesting;
private int bracketNesting;
private boolean inFTLHeader;
@@ -632,22 +632,21 @@ TOKEN_MGR_DECLS:
SwitchTo(FM_EXPRESSION);
}
- /**
- * @param tok
- * Assumed to be an '}', or something that is the closing pair of another "mirror image" character.
- */
- private void endInterpolation(Token tok) {
+ private void endInterpolation(Token closingTk) {
if (postInterpolationLexState == -1) {
- char c = tok.image.charAt(0);
- throw new TokenMgrError(
- "You can't have an \"" + c + "\" here, as there's nothing open that it could close.",
- TokenMgrError.LEXICAL_ERROR,
- tok.beginLine, tok.beginColumn,
- tok.endLine, tok.endColumn);
+ throw newUnexpectedClosingTokenException(closingTk);
}
SwitchTo(postInterpolationLexState);
postInterpolationLexState = -1;
}
+
+ private TokenMgrError newUnexpectedClosingTokenException(Token closingTk) {
+ return new TokenMgrError(
+ "You can't have an \"" + closingTk.image + "\" here, as there's nothing open that it could close.",
+ TokenMgrError.LEXICAL_ERROR,
+ closingTk.beginLine, closingTk.beginColumn,
+ closingTk.endLine, closingTk.endColumn);
+ }
private void eatNewline() {
int charsRead = 0;
@@ -953,6 +952,7 @@ TOKEN:
// Find related: [interpolation prefixes]
<DOLLAR_INTERPOLATION_OPENING : "${"> { startInterpolation(matchedToken); }
|
+ // Find related: [interpolation prefixes]
<SQUARE_BRACKET_INTERPOLATION_OPENING : "[="> { startInterpolation(matchedToken); }
}
@@ -1121,13 +1121,18 @@ TOKEN:
|
<OPENING_CURLY_BRACKET : "{">
{
- ++hashLiteralNesting;
+ ++curlyBracketNesting;
}
|
<CLOSING_CURLY_BRACKET : "}">
{
- if (hashLiteralNesting == 0) endInterpolation(matchedToken);
- else --hashLiteralNesting;
+ if (curlyBracketNesting > 0) {
+ --curlyBracketNesting;
+ } else if (interpolationSyntax != InterpolationSyntax.SQUARE_BRACKET) {
+ endInterpolation(matchedToken);
+ } else {
+ throw newUnexpectedClosingTokenException(matchedToken);
+ }
}
|
<IN : "in">
[2/2] incubator-freemarker git commit: Forward ported from 2.3-gae:
FTL.jj cleanup. Can't close with "]" when using angle bracket tag syntax
anymore.
Posted by dd...@apache.org.
Forward ported from 2.3-gae: FTL.jj cleanup. Can't close with "]" when using angle bracket tag syntax anymore.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/0d21cbb7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/0d21cbb7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/0d21cbb7
Branch: refs/heads/3
Commit: 0d21cbb77004014654b6e7160ad7791939f0faad
Parents: 348e73d
Author: ddekany <dd...@apache.org>
Authored: Mon Mar 19 23:42:35 2018 +0100
Committer: ddekany <dd...@apache.org>
Committed: Mon Mar 19 23:42:35 2018 +0100
----------------------------------------------------------------------
.../core/InterpolationSyntaxTest.java | 27 +++++--
.../core/ParsingErrorMessagesTest.java | 67 ++++++---------
.../freemarker/core/ASTExpStringLiteral.java | 3 +-
freemarker-core/src/main/javacc/FTL.jj | 85 ++++++++++++++------
4 files changed, 109 insertions(+), 73 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0d21cbb7/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
index 4d7d0cc..7dc0dd0 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/InterpolationSyntaxTest.java
@@ -48,7 +48,10 @@ public class InterpolationSyntaxTest extends TemplateTest {
assertOutput("${'a${1}#{2}b[=3]'}", "a1#{2}b[=3]");
assertOutput("<@r'${1} #{1} [=1]'?interpret />", "1 #{1} [=1]");
- assertOutput("${'\"${1} #{1} [=1]\"'?eval}", "1 #{1} [=1]");
+ assertOutput("${'\"${1} #{1} [=1]\"'?eval}", "1 #{1} [=1]");
+
+ assertOutput("<#setting booleanFormat='y,n'>${2>1}", "y"); // Not an error since 2.3.28
+ assertOutput("[#ftl][#setting booleanFormat='y,n']${2>1}", "y"); // Not an error since 2.3.28
}
@Test
@@ -94,7 +97,10 @@ public class InterpolationSyntaxTest extends TemplateTest {
assertOutput("[='[\\=1]']", "[=1]");
assertOutput("[='[\\=1][=2]']", "12"); // Usual legacy interpolation escaping glitch...
- assertOutput("[=r'[=1]']", "[=1]");
+ assertOutput("[=r'[=1]']", "[=1]");
+
+ assertOutput("<#setting booleanFormat='y,n'>[=2>1]", "y");
+ assertOutput("[#ftl][#setting booleanFormat='y,n'][=2>1]", "y");
StringWriter sw = new StringWriter();
new Template(null, "[= 1 + '[= 2 ]' ]", getConfiguration()).dump(sw);
@@ -116,19 +122,28 @@ public class InterpolationSyntaxTest extends TemplateTest {
}
@Test
- public void legacyTagSyntaxGlitchStillWorksTest() throws Exception {
- String ftl = "<#if [true][0]]t<#else]f</#if]";
+ public void legacyTagSyntaxGlitchFixedTest() throws Exception {
+ String badFtl1 = "<#if [true][0]]OK</#if>";
+ String badFtl2 = "<#if true>OK</#if]";
+ String badFtl3 = "<#assign x = 'OK'/]${x}";
+ String badFtl4 = " <#t/]OK\n";
setConfiguration(new TestConfigurationBuilder()
.interpolationSyntax(InterpolationSyntax.DOLLAR)
.build());
- assertOutput(ftl, "t");
+ assertErrorContains(badFtl1, "\"]\"");
+ assertErrorContains(badFtl2, "\"]\"");
+ assertErrorContains(badFtl3, "\"]\"");
+ assertErrorContains(badFtl4, "\"]\"");
// Glitch is not emulated with this:
setConfiguration(new TestConfigurationBuilder()
.interpolationSyntax(InterpolationSyntax.SQUARE_BRACKET)
.build());
- assertErrorContains(ftl, "\"]\"");
+ assertErrorContains(badFtl1, "\"]\"");
+ assertErrorContains(badFtl2, "\"]\"");
+ assertErrorContains(badFtl3, "\"]\"");
+ assertErrorContains(badFtl4, "\"]\"");
}
@Test
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0d21cbb7/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
index bf729ea..962e7a9 100644
--- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
+++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ParsingErrorMessagesTest.java
@@ -19,19 +19,20 @@
package org.apache.freemarker.core;
-import static org.junit.Assert.*;
-
import java.io.IOException;
-import org.apache.freemarker.core.util._StringUtils;
+import org.apache.freemarker.test.TemplateTest;
import org.apache.freemarker.test.TestConfigurationBuilder;
import org.junit.Test;
-public class ParsingErrorMessagesTest {
+public class ParsingErrorMessagesTest extends TemplateTest {
- private Configuration cfg = new TestConfigurationBuilder()
- .tagSyntax(TagSyntax.AUTO_DETECT)
- .build();
+ @Override
+ protected Configuration createDefaultConfiguration() throws Exception {
+ return new TestConfigurationBuilder()
+ .tagSyntax(TagSyntax.AUTO_DETECT)
+ .build();
+ }
@Test
public void testNeedlessInterpolation() {
@@ -122,10 +123,14 @@ public class ParsingErrorMessagesTest {
}
@Test
- public void testInterpolatingClosingsErrors() {
- assertErrorContains("${x", "unclosed");
+ public void testInterpolatingClosingsErrors() throws Exception {
+ assertErrorContains("<#ftl>${x", "unclosed");
assertErrorContains("<#assign x = x}>", "\"}\"", "open");
- // TODO assertErrorContains("<#assign x = '${x'>", "unclosed");
+ assertErrorContains("<#ftl>${'x']", "\"]\"", "open");
+ super.assertErrorContains("<#ftl>${'x'>", "end of file");
+ super.assertErrorContains("[#ftl]${'x'>", "end of file");
+
+ assertOutput("<#assign x = '${x'>", ""); // TODO [FM3] Legacy glitch... should fail in theory.
}
@Test
@@ -167,43 +172,19 @@ public class ParsingErrorMessagesTest {
assertErrorContains("<#function f(a=0, b)></#function>", "with default", "without a default");
assertErrorContains("<#function f(a,)></#function>", "Comma without");
assertErrorContains("<#macro m a{positional}, b{positional},></#macro>", "Comma without");
- assertErrorContains(false, "<#function f(a, b></#function>");
- assertErrorContains(false, "<#function f(></#function>");
- assertErrorContains(false, "[#ftl][#function f(a, b][/#function]", "Missing closing \")\"");
- assertErrorContains(false, "[#ftl][#function f(][/#function]", "Missing closing \")\"");
+ super.assertErrorContains("<#function f(a, b></#function>");
+ super.assertErrorContains("<#function f(></#function>");
+ super.assertErrorContains("[#ftl][#function f(a, b][/#function]", "Missing closing \")\"");
+ super.assertErrorContains("[#ftl][#function f(][/#function]", "Missing closing \")\"");
assertErrorContains("<#macro m a b)></#macro>", "\")\" without", "opening");
assertErrorContains("<#macro m a b a></#macro>", "\"a\"", "multiple");
}
- private void assertErrorContains(String ftl, String... expectedSubstrings) {
- assertErrorContains(false, ftl, expectedSubstrings);
- assertErrorContains(true, ftl, expectedSubstrings);
- }
-
- private void assertErrorContains(boolean convertToSquare, String ftl, String... expectedSubstrings) {
- try {
- if (convertToSquare) {
- ftl = ftl.replace('<', '[').replace('>', ']');
- }
- new Template("adhoc", ftl, cfg);
- fail("The template had to fail");
- } catch (ParseException e) {
- String msg = e.getMessage();
- for (String needle: expectedSubstrings) {
- if (needle.startsWith("\\!")) {
- String netNeedle = needle.substring(2);
- if (msg.contains(netNeedle)) {
- fail("The message shouldn't contain substring " + _StringUtils.jQuote(netNeedle) + ":\n" + msg);
- }
- } else if (!msg.contains(needle)) {
- fail("The message didn't contain substring " + _StringUtils.jQuote(needle) + ":\n" + msg);
- }
- }
- showError(e);
- } catch (IOException e) {
- // Won't happen
- throw new RuntimeException(e);
- }
+ @Override
+ protected Throwable assertErrorContains(String ftl, String... expectedSubstrings) {
+ super.assertErrorContains(ftl, expectedSubstrings);
+ ftl = ftl.replace('<', '[').replace('>', ']');
+ return super.assertErrorContains(ftl, expectedSubstrings);
}
private void showError(Throwable e) {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0d21cbb7/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpStringLiteral.java
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpStringLiteral.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpStringLiteral.java
index a86c4d5..ebd8ff6 100644
--- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpStringLiteral.java
+++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTExpStringLiteral.java
@@ -49,13 +49,14 @@ final class ASTExpStringLiteral extends ASTExpression implements TemplateStringM
* inherit tokenizer-level auto-detected settings.
*/
void parseValue(FMParserTokenManager parentTkMan, OutputFormat outputFormat) throws ParseException {
- // TODO [FM3] (Find related: [interpolation prefixes])
+ // TODO [FM3]
// The way this works is incorrect (the literal should be parsed without un-escaping),
// but we can't fix this backward compatibly.
Template parentTemplate = getTemplate();
ParsingConfiguration pCfg = parentTemplate.getParsingConfiguration();
InterpolationSyntax intSyn = pCfg.getInterpolationSyntax();
if (value.length() > 3 && (
+ // Find related: [interpolation prefixes]
intSyn == InterpolationSyntax.DOLLAR && value.indexOf("${") != -1
|| intSyn == InterpolationSyntax.SQUARE_BRACKET && value.indexOf("[=") != -1)) {
try {
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/0d21cbb7/freemarker-core/src/main/javacc/FTL.jj
----------------------------------------------------------------------
diff --git a/freemarker-core/src/main/javacc/FTL.jj b/freemarker-core/src/main/javacc/FTL.jj
index 76b32f5..fa29105 100644
--- a/freemarker-core/src/main/javacc/FTL.jj
+++ b/freemarker-core/src/main/javacc/FTL.jj
@@ -533,7 +533,7 @@ TOKEN_MGR_DECLS:
private boolean inFTLHeader;
boolean squBracTagSyntax,
autodetectTagSyntax,
- directiveSyntaxEstablished,
+ tagSyntaxEstablished,
inNamedParameterExpression;
InterpolationSyntax interpolationSyntax;
int incompatibleImprovements;
@@ -550,7 +550,7 @@ TOKEN_MGR_DECLS:
final String image = tok.image;
char firstChar = image.charAt(0);
- if (autodetectTagSyntax && !directiveSyntaxEstablished) {
+ if (autodetectTagSyntax && !tagSyntaxEstablished) {
squBracTagSyntax = (firstChar == '[');
}
if ((firstChar == '[' && !squBracTagSyntax) || (firstChar == '<' && squBracTagSyntax)) {
@@ -558,7 +558,22 @@ TOKEN_MGR_DECLS:
return;
}
- directiveSyntaxEstablished = true;
+ tagSyntaxEstablished = true;
+
+ // For END_xxx tags, as they can't contain expressions, the whole tag is a single token. So this is the only
+ // chance to check if we got something inconsistent like `</#if]`. (We can't do this at the #CLOSE_TAG1 or
+ // such, as at that point it's possible that the tag syntax is not yet established.)
+ char lastChar = image.charAt(image.length() - 1);
+ // Is it an end tag?
+ if (lastChar == ']' || lastChar == '>') {
+ if (!squBracTagSyntax && lastChar != '>' || squBracTagSyntax && lastChar != ']') {
+ throw new TokenMgrError(
+ "The tag shouldn't end with \""+ lastChar + "\".",
+ TokenMgrError.LEXICAL_ERROR,
+ tok.beginLine, tok.beginColumn,
+ tok.endLine, tok.endColumn);
+ }
+ } // if end-tag
SwitchTo(newLexState);
}
@@ -581,7 +596,7 @@ TOKEN_MGR_DECLS:
private void dynamicTopLevelCall(Token tok) {
char firstChar = tok.image.charAt(0);
- if (autodetectTagSyntax && !directiveSyntaxEstablished) {
+ if (autodetectTagSyntax && !tagSyntaxEstablished) {
squBracTagSyntax = (firstChar == '[');
}
if (squBracTagSyntax && firstChar == '<') {
@@ -592,7 +607,7 @@ TOKEN_MGR_DECLS:
tok.kind = STATIC_TEXT_NON_WS;
return;
}
- directiveSyntaxEstablished = true;
+ tagSyntaxEstablished = true;
SwitchTo(NO_SPACE_EXPRESSION);
}
@@ -633,9 +648,6 @@ TOKEN_MGR_DECLS:
}
private void endInterpolation(Token closingTk) {
- if (postInterpolationLexState == -1) {
- throw newUnexpectedClosingTokenException(closingTk);
- }
SwitchTo(postInterpolationLexState);
postInterpolationLexState = -1;
}
@@ -674,9 +686,9 @@ TOKEN_MGR_DECLS:
}
private void ftlHeader(Token matchedToken) {
- if (!directiveSyntaxEstablished) {
+ if (!tagSyntaxEstablished) {
squBracTagSyntax = matchedToken.image.charAt(0) == '[';
- directiveSyntaxEstablished = true;
+ tagSyntaxEstablished = true;
autodetectTagSyntax = false;
}
String img = matchedToken.image;
@@ -869,9 +881,9 @@ TOKEN:
{
char firstChar = matchedToken.image.charAt(0);
- if (!directiveSyntaxEstablished && autodetectTagSyntax) {
+ if (!tagSyntaxEstablished && autodetectTagSyntax) {
squBracTagSyntax = (firstChar == '[');
- directiveSyntaxEstablished = true;
+ tagSyntaxEstablished = true;
}
if (firstChar == '<' && squBracTagSyntax) {
@@ -1090,18 +1102,18 @@ TOKEN:
{
if (bracketNesting > 0) {
--bracketNesting;
- } else if (interpolationSyntax == InterpolationSyntax.SQUARE_BRACKET
- && (postInterpolationLexState != -1 || !squBracTagSyntax)) {
+ } else if (interpolationSyntax == InterpolationSyntax.SQUARE_BRACKET && postInterpolationLexState != -1) {
endInterpolation(matchedToken);
- } else {
- // TODO [FM3] Don't mimic this glitch anymore.
- // Glitch where you can close any tag with `]`, like `<#if x]`. We keep it for backward compatibility.
+ } else if (squBracTagSyntax
+ && postInterpolationLexState == -1 /* We're in an interpolation => We aren't in a tag */) {
matchedToken.kind = DIRECTIVE_END;
if (inFTLHeader) {
eatNewline();
inFTLHeader = false;
}
SwitchTo(DEFAULT);
+ } else {
+ throw newUnexpectedClosingTokenException(matchedToken);
}
}
|
@@ -1128,7 +1140,7 @@ TOKEN:
{
if (curlyBracketNesting > 0) {
--curlyBracketNesting;
- } else if (interpolationSyntax != InterpolationSyntax.SQUARE_BRACKET) {
+ } else if (interpolationSyntax != InterpolationSyntax.SQUARE_BRACKET && postInterpolationLexState != -1) {
endInterpolation(matchedToken);
} else {
throw newUnexpectedClosingTokenException(matchedToken);
@@ -1321,19 +1333,46 @@ TOKEN:
{
<DIRECTIVE_END : ">">
{
- if (inFTLHeader) eatNewline();
- inFTLHeader = false;
- if (squBracTagSyntax) {
+ if (inFTLHeader) {
+ eatNewline();
+ inFTLHeader = false;
+ }
+ if (squBracTagSyntax || postInterpolationLexState != -1 /* We are in an interpolation */) {
matchedToken.kind = NATURAL_GT;
} else {
+ if (tagSyntaxEstablished) {
+ if (squBracTagSyntax) {
+ throw new TokenMgrError(
+ "The tag shouldn't end with \"" + image.charAt(image.length() - 1) + "\".",
+ TokenMgrError.LEXICAL_ERROR,
+ matchedToken.beginLine, matchedToken.beginColumn,
+ matchedToken.endLine, matchedToken.endColumn);
+ }
+ }
+
SwitchTo(DEFAULT);
}
}
|
<EMPTY_DIRECTIVE_END : "/>" | "/]">
{
- if (inFTLHeader) eatNewline();
- inFTLHeader = false;
+ if (inFTLHeader) {
+ eatNewline();
+ inFTLHeader = false;
+ }
+
+ if (tagSyntaxEstablished) {
+ String image = matchedToken.image;
+ char lastChar = image.charAt(image.length() - 1);
+ if (!squBracTagSyntax && lastChar != '>' || squBracTagSyntax && lastChar != ']') {
+ throw new TokenMgrError(
+ "The tag shouldn't end with \""+ lastChar + "\".",
+ TokenMgrError.LEXICAL_ERROR,
+ matchedToken.beginLine, matchedToken.beginColumn,
+ matchedToken.endLine, matchedToken.endColumn);
+ }
+ }
+
SwitchTo(DEFAULT);
}
}