mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#515, introduction of string definition handling in IndentationCorrectingWriter
This commit is contained in:
parent
2ece25a086
commit
124c2a4001
@ -29,6 +29,16 @@ import java.util.Arrays;
|
|||||||
* This writer discards any leading whitespace characters following to a line break character. When the first
|
* This writer discards any leading whitespace characters following to a line break character. When the first
|
||||||
* non-whitespace character is written after a line break, the correct indentation characters are added, which is four
|
* non-whitespace character is written after a line break, the correct indentation characters are added, which is four
|
||||||
* whitespace characters per indentation level.
|
* whitespace characters per indentation level.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The state pattern is line oriented. It starts by writing text. Indentation is increased if a brace '('or
|
||||||
|
* brace '{' is encountered in the code to be generated and written out in state: IN_TEXT_START_OF_LINE. Whenever
|
||||||
|
* a line end occurs (PC or Linux style) the amount of enters is checked and at max set to 2.
|
||||||
|
*
|
||||||
|
* Whenever a string definition is encountered in the code that should be generated, increasing the indentation is
|
||||||
|
* stopped (so `{` and '(' are ignored) until the end of the string is encountered ('"'). To avoid writing a new
|
||||||
|
* indentation, the state then returns to IN_TEXT.
|
||||||
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* This is a very basic implementation which does not take into account comments, escaping etc.
|
* This is a very basic implementation which does not take into account comments, escaping etc.
|
||||||
*
|
*
|
||||||
@ -43,7 +53,7 @@ class IndentationCorrectingWriter extends Writer {
|
|||||||
private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
|
private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
|
||||||
private static final boolean IS_WINDOWS = System.getProperty( "os.name" ).startsWith( "Windows" );
|
private static final boolean IS_WINDOWS = System.getProperty( "os.name" ).startsWith( "Windows" );
|
||||||
|
|
||||||
private State currentState = State.IN_TEXT;
|
private State currentState = State.START_OF_LINE;
|
||||||
private final StateContext context;
|
private final StateContext context;
|
||||||
|
|
||||||
IndentationCorrectingWriter(Writer out) {
|
IndentationCorrectingWriter(Writer out) {
|
||||||
@ -99,12 +109,22 @@ class IndentationCorrectingWriter extends Writer {
|
|||||||
private enum State {
|
private enum State {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Within any text.
|
* Within any text, before encountering a String definition.
|
||||||
*/
|
*/
|
||||||
IN_TEXT {
|
START_OF_LINE {
|
||||||
@Override
|
@Override
|
||||||
State doHandleCharacter(char c, StateContext context) {
|
State doHandleCharacter(char c, StateContext context) {
|
||||||
switch ( c ) {
|
switch ( c ) {
|
||||||
|
case '{':
|
||||||
|
case '(':
|
||||||
|
context.indentationLevel++;
|
||||||
|
return IN_TEXT;
|
||||||
|
case '}':
|
||||||
|
case ')':
|
||||||
|
context.indentationLevel--;
|
||||||
|
return IN_TEXT;
|
||||||
|
case '\"':
|
||||||
|
return IN_STRING;
|
||||||
case '\r':
|
case '\r':
|
||||||
return isWindows() ? IN_LINE_BREAK : AFTER_LINE_BREAK;
|
return isWindows() ? IN_LINE_BREAK : AFTER_LINE_BREAK;
|
||||||
case '\n':
|
case '\n':
|
||||||
@ -142,27 +162,115 @@ class IndentationCorrectingWriter extends Writer {
|
|||||||
flush( context );
|
flush( context );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flush(StateContext context) throws IOException {
|
},
|
||||||
if ( null != context.characters && context.currentIndex - context.lastStateChange > 0 ) {
|
|
||||||
context.writer.write(
|
|
||||||
context.characters,
|
|
||||||
context.lastStateChange,
|
|
||||||
context.currentIndex - context.lastStateChange
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( DEBUG ) {
|
/**
|
||||||
System.out.print(
|
* Within any text, but after a String (" ").
|
||||||
new String(
|
*/
|
||||||
java.util.Arrays.copyOfRange(
|
IN_TEXT {
|
||||||
context.characters,
|
@Override
|
||||||
context.lastStateChange,
|
State doHandleCharacter(char c, StateContext context) {
|
||||||
context.currentIndex
|
switch ( c ) {
|
||||||
)
|
case '{':
|
||||||
)
|
case '(':
|
||||||
);
|
context.indentationLevel++;
|
||||||
|
return IN_TEXT;
|
||||||
|
case '}':
|
||||||
|
case ')':
|
||||||
|
context.indentationLevel--;
|
||||||
|
return IN_TEXT;
|
||||||
|
case '\"':
|
||||||
|
return IN_STRING;
|
||||||
|
case '\r':
|
||||||
|
return isWindows() ? IN_LINE_BREAK : AFTER_LINE_BREAK;
|
||||||
|
case '\n':
|
||||||
|
return AFTER_LINE_BREAK;
|
||||||
|
default:
|
||||||
|
return IN_TEXT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the current text.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void onExit(StateContext context) throws IOException {
|
||||||
|
flush( context );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the current text.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void onBufferFinished(StateContext context) throws IOException {
|
||||||
|
flush( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In a String definition, Between un-escaped quotes " "
|
||||||
|
*/
|
||||||
|
IN_STRING {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
State doHandleCharacter(char c, StateContext context) {
|
||||||
|
switch ( c ) {
|
||||||
|
case '\"':
|
||||||
|
return IN_TEXT;
|
||||||
|
case '\\':
|
||||||
|
return IN_STRING_ESCAPED_CHAR;
|
||||||
|
default:
|
||||||
|
return IN_STRING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the current text.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void onExit(StateContext context) throws IOException {
|
||||||
|
flush( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the current text.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void onBufferFinished(StateContext context) throws IOException {
|
||||||
|
flush( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In a String, character following an escape character '\', should be ignored, can also be '"' that
|
||||||
|
* should be ignored.
|
||||||
|
*/
|
||||||
|
IN_STRING_ESCAPED_CHAR {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
State doHandleCharacter(char c, StateContext context) {
|
||||||
|
// ignore escaped character
|
||||||
|
return IN_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the current text.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void onExit(StateContext context) throws IOException {
|
||||||
|
flush( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the current text.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void onBufferFinished(StateContext context) throws IOException {
|
||||||
|
flush( context );
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,7 +294,16 @@ class IndentationCorrectingWriter extends Writer {
|
|||||||
AFTER_LINE_BREAK {
|
AFTER_LINE_BREAK {
|
||||||
@Override
|
@Override
|
||||||
State doHandleCharacter(char c, StateContext context) {
|
State doHandleCharacter(char c, StateContext context) {
|
||||||
|
|
||||||
switch ( c ) {
|
switch ( c ) {
|
||||||
|
case '{':
|
||||||
|
case '(':
|
||||||
|
context.indentationLevel++;
|
||||||
|
return START_OF_LINE;
|
||||||
|
case '}':
|
||||||
|
case ')':
|
||||||
|
context.indentationLevel--;
|
||||||
|
return START_OF_LINE;
|
||||||
case '\r':
|
case '\r':
|
||||||
return isWindows() ? IN_LINE_BREAK : AFTER_LINE_BREAK;
|
return isWindows() ? IN_LINE_BREAK : AFTER_LINE_BREAK;
|
||||||
case ' ':
|
case ' ':
|
||||||
@ -195,7 +312,7 @@ class IndentationCorrectingWriter extends Writer {
|
|||||||
context.consecutiveLineBreaks++;
|
context.consecutiveLineBreaks++;
|
||||||
return AFTER_LINE_BREAK;
|
return AFTER_LINE_BREAK;
|
||||||
default:
|
default:
|
||||||
return IN_TEXT;
|
return START_OF_LINE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,12 +337,7 @@ class IndentationCorrectingWriter extends Writer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
final State handleCharacter(char c, StateContext context) throws IOException {
|
final State handleCharacter(char c, StateContext context) throws IOException {
|
||||||
if ( c == '{' || c == '(' ) {
|
|
||||||
context.indentationLevel++;
|
|
||||||
}
|
|
||||||
else if ( c == '}' || c == ')' ) {
|
|
||||||
context.indentationLevel--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return doHandleCharacter( c, context );
|
return doHandleCharacter( c, context );
|
||||||
}
|
}
|
||||||
@ -245,6 +357,28 @@ class IndentationCorrectingWriter extends Writer {
|
|||||||
|
|
||||||
void onBufferFinished(StateContext context) throws IOException {
|
void onBufferFinished(StateContext context) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void flush(StateContext context) throws IOException {
|
||||||
|
if ( null != context.characters && context.currentIndex - context.lastStateChange > 0 ) {
|
||||||
|
context.writer.write(
|
||||||
|
context.characters,
|
||||||
|
context.lastStateChange,
|
||||||
|
context.currentIndex - context.lastStateChange
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( DEBUG ) {
|
||||||
|
System.out.print(
|
||||||
|
new String(
|
||||||
|
java.util.Arrays.copyOfRange(
|
||||||
|
context.characters,
|
||||||
|
context.lastStateChange,
|
||||||
|
context.currentIndex
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed 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.mapstruct.ap.test.bugs._515;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public abstract class Issue515Mapper {
|
||||||
|
|
||||||
|
public static final Issue515Mapper INSTANCE = Mappers.getMapper( Issue515Mapper.class );
|
||||||
|
|
||||||
|
@Mapping( target = "id", expression = "java(\"blah)\\\"\")" )
|
||||||
|
public abstract Target map(Source source);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed 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.mapstruct.ap.test.bugs._515;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
import org.mapstruct.ap.testutil.WithClasses;
|
||||||
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reproducer for https://github.com/mapstruct/mapstruct/issues/515.
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
@IssueKey( "515" )
|
||||||
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
public class Issue515Test {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithClasses( { Issue515Mapper.class, Source.class, Target.class } )
|
||||||
|
public void shouldIgnoreParanthesesOpenInStringDefinition() {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed 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.mapstruct.ap.test.bugs._515;
|
||||||
|
|
||||||
|
public class Source {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||||
|
* and/or other contributors as indicated by the @authors tag. See the
|
||||||
|
* copyright.txt file in the distribution for a full listing of all
|
||||||
|
* contributors.
|
||||||
|
*
|
||||||
|
* Licensed 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.mapstruct.ap.test.bugs._515;
|
||||||
|
|
||||||
|
|
||||||
|
public class Target {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user