Skip to content

Commit de83cb1

Browse files
authored
Merge pull request #129 from kusumotolab/extract-field-files
フィールドをファイルとして抽出するように変更
2 parents 093cb28 + 343c488 commit de83cb1

File tree

8 files changed

+233
-23
lines changed

8 files changed

+233
-23
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package finergit.ast;
2+
3+
import java.nio.file.Path;
4+
import finergit.FinerGitConfig;
5+
6+
public class FinerJavaField extends FinerJavaModule {
7+
8+
private static final String ATTRIBUTE_EXTENSION = ".ajava";
9+
private static final String ATTRIBUTE_DELIMITER = "#";
10+
11+
public FinerJavaField(final String name, final FinerJavaModule outerModule,
12+
final FinerGitConfig config) {
13+
super(name, outerModule, config);
14+
}
15+
16+
@Override
17+
public Path getDirectory() {
18+
return this.outerModule.getDirectory();
19+
}
20+
21+
@Override
22+
public String getExtension() {
23+
return ATTRIBUTE_EXTENSION;
24+
}
25+
26+
/**
27+
* ベースネーム(拡張子がないファイル名)を返す.
28+
*
29+
* @return
30+
*/
31+
public String getBaseName() {
32+
return this.outerModule.getBaseName() + ATTRIBUTE_DELIMITER + this.name;
33+
}
34+
}

src/main/java/finergit/ast/FinerJavaFileBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ public void acceptAST(final String sourceFilePath, final CompilationUnit ast) {
4343
final JavaFileVisitor visitor =
4444
new JavaFileVisitor(path, FinerJavaFileBuilder.this.config);
4545
ast.accept(visitor);
46-
final List<FinerJavaModule> modules = visitor.getFinerJavaModules(false, true, true);
46+
final List<FinerJavaModule> modules =
47+
visitor.getFinerJavaModules(false, true, true, true);
4748
finerJavaModules.addAll(modules);
4849
}
4950
}
@@ -71,7 +72,7 @@ public List<FinerJavaModule> getFinerJavaModules(final String path, final String
7172

7273
final JavaFileVisitor visitor = new JavaFileVisitor(Paths.get(path), this.config);
7374
ast.accept(visitor);
74-
return visitor.getFinerJavaModules(false, true, true);
75+
return visitor.getFinerJavaModules(false, true, true, true);
7576
}
7677

7778
private ASTParser createNewParser() {

src/main/java/finergit/ast/JavaFileVisitor.java

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ public JavaFileVisitor(final Path path, final FinerGitConfig config) {
4242
}
4343

4444
public List<FinerJavaModule> getFinerJavaModules(final boolean wantFile, final boolean wantClass,
45-
final boolean wantMethod) {
45+
final boolean wantMethod, final boolean wantAttribute) {
4646
return this.moduleList.stream()
4747
.filter(m -> (FinerJavaFile.class == m.getClass() && wantFile)
4848
|| (FinerJavaClass.class == m.getClass() && wantClass)
49-
|| (FinerJavaMethod.class == m.getClass() && wantMethod))
49+
|| (FinerJavaMethod.class == m.getClass() && wantMethod)
50+
|| (FinerJavaField.class == m.getClass() && wantAttribute))
5051
.collect(Collectors.toList());
5152
}
5253

@@ -700,6 +701,13 @@ public boolean visit(final FieldAccess node) {
700701
@Override
701702
public boolean visit(final FieldDeclaration node) {
702703

704+
// 内部クラスのフィールドでない場合は,ダミーフィールドを生成し,モジュールスタックに追加
705+
if (1 == this.classNestLevel) {
706+
final FinerJavaModule outerModule = this.moduleStack.peek();
707+
final FinerJavaField dummyField = new FinerJavaField("DummyField", outerModule, null);
708+
this.moduleStack.push(dummyField);
709+
}
710+
703711
// Javadoc コメントの処理
704712
final Javadoc javadoc = node.getJavadoc();
705713
if (null != javadoc) {
@@ -713,16 +721,72 @@ public boolean visit(final FieldDeclaration node) {
713721
this.addToPeekModule(modifierToken);
714722
}
715723

724+
// 型の処理
716725
node.getType()
717726
.accept(this);
718727

719-
for (final Object o : node.fragments()) {
720-
final VariableDeclarationFragment fragment = (VariableDeclarationFragment) o;
721-
fragment.accept(this);
728+
// フィールド名の処理
729+
final List<?> fragments = node.fragments();
730+
((VariableDeclarationFragment) fragments.get(0)).accept(this);
731+
for (int index = 1; index < fragments.size(); index++) {
732+
this.addToPeekModule(new FIELDDECLARATIONCOMMA());
733+
((VariableDeclarationFragment) fragments.get(index)).accept(this);
722734
}
723735

736+
// フィールド宣言の最後にあるセミコロンの処理
724737
this.addToPeekModule(new FIELDDECLARATIONSEMICOLON());
725738

739+
// フィールドモジュールの名前を生成
740+
final StringBuilder fieldFileName = new StringBuilder();
741+
if (this.config.isAccessModifierIncluded()) { // アクセス修飾子を名前に入れる場合
742+
final int modifiers = node.getModifiers();
743+
if (Modifier.isPublic(modifiers)) {
744+
fieldFileName.append("public_");
745+
} else if (Modifier.isProtected(modifiers)) {
746+
fieldFileName.append("protected_");
747+
} else if (Modifier.isPrivate(modifiers)) {
748+
fieldFileName.append("private_");
749+
}
750+
}
751+
final String type = node.getType()
752+
.toString()
753+
.replace(' ', '-') // avoiding space existences
754+
.replace('?', '#') // for window's file system
755+
.replace('<', '[') // for window's file system
756+
.replace('>', ']'); // for window's file system
757+
fieldFileName.append(type);
758+
fieldFileName.append("_");
759+
fieldFileName.append(((VariableDeclarationFragment) fragments.get(0)).getName());
760+
for (int index = 1; index < fragments.size(); index++) {
761+
fieldFileName.append("_");
762+
fieldFileName.append(((VariableDeclarationFragment) fragments.get(index)).getName());
763+
}
764+
765+
// 内部クラスのフィールドでない場合は,ダミーフィールドをスタックから取り除く
766+
if (1 == this.classNestLevel) {
767+
final FinerJavaModule dummyField = this.moduleStack.pop();
768+
final FinerJavaModule outerModule = this.moduleStack.peek();
769+
final FinerJavaField javaField =
770+
new FinerJavaField(fieldFileName.toString(), outerModule, this.config);
771+
this.moduleList.add(javaField);
772+
773+
// 一行一トークンの場合は,ダミーフィールド内のトークンを抽出し,methodModule に移行
774+
if (this.config.isTokenized()) {
775+
dummyField.getTokens()
776+
.forEach(javaField::addToken);
777+
this.addToPeekModule(
778+
new FinerJavaFieldToken("FieldToken[" + javaField.name + "]", javaField));
779+
}
780+
781+
// 一行一トークンでない場合は,,フィールドの文字列表現からトークンを作り出し,それらをフィールドモジュールに追加し,処理を終了する
782+
else {
783+
Stream.of(node.toString()
784+
.split("(\\r\\n|\\r|\\n)"))
785+
.map(l -> new LineToken(l))
786+
.forEach(javaField::addToken);
787+
}
788+
}
789+
726790
return false;
727791
}
728792

@@ -1113,7 +1177,7 @@ public boolean visit(final MethodDeclaration node) {
11131177
final SingleVariableDeclaration svd = (SingleVariableDeclaration) parameter;
11141178
final StringBuilder typeText = new StringBuilder();
11151179
typeText.append(svd.getType());
1116-
for(int i = 0 ; i < svd.getExtraDimensions() ; i++) { // "int a[]"のような表記に対応するため
1180+
for (int i = 0; i < svd.getExtraDimensions(); i++) { // "int a[]"のような表記に対応するため
11171181
typeText.append("[]");
11181182
}
11191183
if (svd.isVarargs()) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package finergit.ast.token;
2+
3+
4+
public class FIELDDECLARATIONCOMMA extends COMMA {
5+
6+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package finergit.ast.token;
2+
3+
import finergit.ast.FinerJavaField;
4+
5+
public class FinerJavaFieldToken extends JavaToken {
6+
7+
final FinerJavaField finerJavaField;
8+
9+
public FinerJavaFieldToken(final String value, final FinerJavaField finerJavaField) {
10+
super(value);
11+
this.finerJavaField = finerJavaField;
12+
}
13+
}

src/test/java/finergit/ast/FinerJavaFileBuilderTest.java

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,10 @@ public void getFinerJavaModulesSuccessTest05() throws Exception {
117117
.map(m -> m.getFileName())
118118
.collect(Collectors.toSet());
119119
assertThat(moduleNames).containsExactlyInAnyOrder("GetterAndSetter.cjava",
120-
"GetterAndSetter#GetterAndSetter(String).mjava", "GetterAndSetter#String_getText().mjava",
121-
"GetterAndSetter#void_setText(String).mjava");
120+
"GetterAndSetter#public_GetterAndSetter(String).mjava",
121+
"GetterAndSetter#public_String_getText().mjava",
122+
"GetterAndSetter#public_void_setText(String).mjava",
123+
"GetterAndSetter#private_String_text.ajava");
122124
}
123125

124126
@Test
@@ -137,17 +139,20 @@ public void getFinerJavaModulesSuccessTest06() throws Exception {
137139
switch (module.name) {
138140
case "GetterAndSetter":
139141
break;
140-
case "GetterAndSetter(String)":
141-
assertThat(tokens).containsExactly("GetterAndSetter", "(", "String", "text", ")", "{",
142-
"this", ".", "text", "=", "text", ";", "}");
142+
case "public_GetterAndSetter(String)":
143+
assertThat(tokens).containsExactly("public", "GetterAndSetter", "(", "String", "text",
144+
")", "{", "this", ".", "text", "=", "text", ";", "}");
143145
break;
144-
case "String_getText()":
145-
assertThat(tokens).containsExactly("String", "getText", "(", ")", "{", "return", "text",
146-
";", "}");
146+
case "public_String_getText()":
147+
assertThat(tokens).containsExactly("public", "String", "getText", "(", ")", "{", "return",
148+
"text", ";", "}");
149+
break;
150+
case "public_void_setText(String)":
151+
assertThat(tokens).containsExactly("public", "void", "setText", "(", "String", "text",
152+
")", "{", "this", ".", "text", "=", "text", ";", "}");
147153
break;
148-
case "void_setText(String)":
149-
assertThat(tokens).containsExactly("void", "setText", "(", "String", "text", ")", "{",
150-
"this", ".", "text", "=", "text", ";", "}");
154+
case "private_String_text":
155+
assertThat(tokens).containsExactly("private", "String", "text", ";");
151156
break;
152157
default:
153158
System.err.println(module.name);
@@ -420,4 +425,66 @@ public void getFinerJavaModulesSuccessTest14() throws Exception {
420425
"ClassName#public_void_set(String).mjava", "[ClassName]A.cjava",
421426
"[ClassName]A#public_void_set(String).mjava");
422427
}
428+
429+
@Test
430+
public void getFinerJavaModulesSuccessTest15() throws Exception {
431+
final Path targetPath = Paths.get("src/test/resources/finergit/ast/token/Field.java");
432+
final String text = String.join(System.lineSeparator(), Files.readAllLines(targetPath));
433+
final FinerJavaFileBuilder builder = new FinerJavaFileBuilder(new FinerGitConfig());
434+
final List<FinerJavaModule> modules = builder.getFinerJavaModules(targetPath.toString(), text);
435+
436+
final List<String> moduleNames = modules.stream()
437+
.map(m -> m.getFileName())
438+
.collect(Collectors.toList());
439+
assertThat(moduleNames).containsExactlyInAnyOrder("Field.cjava", "Field#private_int_a.ajava",
440+
"Field#private_char_b.ajava", "Field#private_byte[]_c_d.ajava",
441+
"Field#private_short[]_e_f.ajava", "Field#public_long_g.ajava",
442+
"Field#void_method().mjava");
443+
}
444+
445+
@Test
446+
public void getFinerJavaModulesSuccessTest16() throws Exception {
447+
final Path targetPath = Paths.get("src/test/resources/finergit/ast/token/Field.java");
448+
final String text = String.join(System.lineSeparator(), Files.readAllLines(targetPath));
449+
final FinerJavaFileBuilder builder = new FinerJavaFileBuilder(new FinerGitConfig());
450+
final List<FinerJavaModule> modules = builder.getFinerJavaModules(targetPath.toString(), text);
451+
452+
for (final FinerJavaModule module : modules) {
453+
454+
final List<String> tokens = module.getTokens()
455+
.stream()
456+
.map(t -> t.value)
457+
.collect(Collectors.toList());
458+
switch (module.name) {
459+
case "Field":
460+
break;
461+
case "private_int_a":
462+
assertThat(tokens).containsExactly(//
463+
"private", "int", "a", ";");
464+
break;
465+
case "private_char_b":
466+
assertThat(tokens).containsExactly(//
467+
"private", "final", "char", "b", "=", "\'b\'", ";");//
468+
break;
469+
case "private_byte[]_c_d":
470+
assertThat(tokens).containsExactly(//
471+
"private", "byte", "[", "]", "c", ",", "d", ";");//
472+
break;
473+
case "private_short[]_e_f":
474+
assertThat(tokens).containsExactly(//
475+
"private", "short", "[", "]", "e", ",", "f", "=", //
476+
"{", "1", ",", "2", "}", ";");//
477+
break;
478+
case "public_long_g":
479+
assertThat(tokens).contains(//
480+
"public", "final", "long", "g", "=", "100l", ";");//
481+
break;
482+
case "void_method()":
483+
break;
484+
default:
485+
System.err.println(module.name);
486+
assertThat(true).isEqualTo(false);
487+
}
488+
}
489+
}
423490
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package finergit.ast.token;
2+
3+
4+
public class Field {
5+
6+
private int a;
7+
private final char b = 'b';
8+
private byte[] c, d;
9+
private short[] e, f = {1, 2};
10+
11+
/**
12+
* definition of g
13+
*/
14+
public final long g = 100l;
15+
16+
void method() {
17+
System.out.print(a);
18+
System.out.print(b);
19+
System.out.print(c);
20+
System.out.print(d);
21+
System.out.print(e);
22+
System.out.print(f);
23+
System.out.print(g);
24+
}
25+
}

src/test/resources/finergit/ast/token/GetterAndSetter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33

44
public class GetterAndSetter {
55

6-
String text;
6+
private String text;
77

8-
GetterAndSetter(String text) {
8+
public GetterAndSetter(String text) {
99
this.text = text;
1010
}
1111

12-
String getText() {
12+
public String getText() {
1313
return text;
1414
}
1515

16-
void setText(String text) {
16+
public void setText(String text) {
1717
this.text = text;
1818
}
1919
}

0 commit comments

Comments
 (0)