|
13 | 13 |
|
14 | 14 | package net.sf.j2s.core.astvisitors; |
15 | 15 |
|
| 16 | +import java.util.ArrayList; |
16 | 17 | import java.util.Arrays; |
17 | 18 | import java.util.HashSet; |
18 | 19 | import java.util.Iterator; |
|
23 | 24 | import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; |
24 | 25 | import org.eclipse.jdt.core.dom.ArrayCreation; |
25 | 26 | import org.eclipse.jdt.core.dom.ArrayType; |
| 27 | +import org.eclipse.jdt.core.dom.Block; |
| 28 | +import org.eclipse.jdt.core.dom.CatchClause; |
26 | 29 | import org.eclipse.jdt.core.dom.ClassInstanceCreation; |
| 30 | +import org.eclipse.jdt.core.dom.Comment; |
27 | 31 | import org.eclipse.jdt.core.dom.CompilationUnit; |
28 | 32 | import org.eclipse.jdt.core.dom.EnumDeclaration; |
29 | 33 | import org.eclipse.jdt.core.dom.Expression; |
|
32 | 36 | import org.eclipse.jdt.core.dom.IMethodBinding; |
33 | 37 | import org.eclipse.jdt.core.dom.ITypeBinding; |
34 | 38 | import org.eclipse.jdt.core.dom.IVariableBinding; |
| 39 | +import org.eclipse.jdt.core.dom.IfStatement; |
35 | 40 | import org.eclipse.jdt.core.dom.Initializer; |
36 | 41 | import org.eclipse.jdt.core.dom.Javadoc; |
| 42 | +import org.eclipse.jdt.core.dom.MethodDeclaration; |
37 | 43 | import org.eclipse.jdt.core.dom.MethodInvocation; |
38 | 44 | import org.eclipse.jdt.core.dom.Modifier; |
39 | 45 | import org.eclipse.jdt.core.dom.Name; |
40 | 46 | import org.eclipse.jdt.core.dom.PackageDeclaration; |
41 | 47 | import org.eclipse.jdt.core.dom.SimpleName; |
| 48 | +import org.eclipse.jdt.core.dom.Statement; |
42 | 49 | import org.eclipse.jdt.core.dom.TagElement; |
43 | 50 | import org.eclipse.jdt.core.dom.TextElement; |
44 | 51 | import org.eclipse.jdt.core.dom.Type; |
@@ -67,7 +74,14 @@ public class DependencyASTVisitor extends ASTVisitor { |
67 | 74 | protected Set optionals = new HashSet(); |
68 | 75 |
|
69 | 76 | protected Set ignores = new HashSet(); |
| 77 | + |
| 78 | + private boolean isDebugging = false; |
| 79 | + |
| 80 | + private Javadoc[] nativeJavadoc = null; |
70 | 81 |
|
| 82 | + private ASTNode javadocRoot = null; |
| 83 | + |
| 84 | + protected boolean toCompileVariableName = true; |
71 | 85 |
|
72 | 86 | public DependencyASTVisitor() { |
73 | 87 | super(); |
@@ -509,15 +523,34 @@ public boolean visit(EnumDeclaration node) { |
509 | 523 | return super.visit(node); |
510 | 524 | } |
511 | 525 |
|
| 526 | + public boolean isClassKnown(String qualifiedName) { |
| 527 | + String[] knownClasses = new String[] { |
| 528 | + "java.lang.Object", |
| 529 | + "java.lang.Class", |
| 530 | + "java.lang.String", |
| 531 | + "java.io.Serializable", |
| 532 | + "java.lang.Iterable", |
| 533 | + "java.lang.CharSequence", |
| 534 | + "java.lang.Cloneable", |
| 535 | + "java.lang.Comparable", |
| 536 | + "java.lang.Runnable", |
| 537 | + "java.util.Comparator", |
| 538 | + "java.lang.System", |
| 539 | + "java.io.PrintStream", |
| 540 | + "java.lang.Math", |
| 541 | + "java.lang.Integer" |
| 542 | + }; |
| 543 | + |
| 544 | + for (int i = 0; i < knownClasses.length; i++) { |
| 545 | + if (knownClasses[i].equals(qualifiedName)) { |
| 546 | + return true; |
| 547 | + } |
| 548 | + } |
| 549 | + return false; |
| 550 | + } |
512 | 551 | public boolean isQualifiedNameOK(String qualifiedName, ASTNode node) { |
513 | 552 | if (qualifiedName != null |
514 | | - && !"java.lang.Object".equals(qualifiedName) |
515 | | - && !"java.lang.Class".equals(qualifiedName) |
516 | | - && !"java.lang.String".equals(qualifiedName) |
517 | | - && !"java.lang.System".equals(qualifiedName) |
518 | | - && !"java.io.PrintStream".equals(qualifiedName) |
519 | | - && !"java.lang.Math".equals(qualifiedName) |
520 | | - && !"java.lang.Integer".equals(qualifiedName) |
| 553 | + && !isClassKnown(qualifiedName) |
521 | 554 | && !qualifiedName.startsWith("org.w3c.dom.") |
522 | 555 | && !qualifiedName.startsWith("org.eclipse.swt.internal.xhtml.")) { |
523 | 556 | ASTNode root = node.getRoot(); |
@@ -804,7 +837,79 @@ public boolean visit(MethodInvocation node) { |
804 | 837 | } |
805 | 838 | return super.visit(node); |
806 | 839 | } |
| 840 | + |
| 841 | + public boolean isDebugging() { |
| 842 | + return isDebugging; |
| 843 | + } |
| 844 | + |
| 845 | + public void setDebugging(boolean isDebugging) { |
| 846 | + this.isDebugging = isDebugging; |
| 847 | + } |
| 848 | + |
| 849 | + public boolean isToCompileVariableName() { |
| 850 | + return toCompileVariableName; |
| 851 | + } |
| 852 | + |
| 853 | + public void setToCompileVariableName(boolean toCompileVariableName) { |
| 854 | + this.toCompileVariableName = toCompileVariableName; |
| 855 | + } |
807 | 856 |
|
| 857 | + public boolean visit(MethodDeclaration node) { |
| 858 | + Javadoc javadoc = node.getJavadoc(); |
| 859 | + if (javadoc != null) { |
| 860 | + List tags = javadoc.tags(); |
| 861 | + if (tags.size() != 0) { |
| 862 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 863 | + TagElement tagEl = (TagElement) iter.next(); |
| 864 | + if ("@j2sIgnore".equals(tagEl.getTagName())) { |
| 865 | + return false; |
| 866 | + } |
| 867 | + } |
| 868 | + } |
| 869 | + } |
| 870 | + |
| 871 | + if (node.getBody() == null) { |
| 872 | + /* |
| 873 | + * Abstract or native method |
| 874 | + */ |
| 875 | + boolean isJ2S = false; |
| 876 | + if ((node.getModifiers() & Modifier.NATIVE) != 0) { |
| 877 | + if (javadoc != null) { |
| 878 | + List tags = javadoc.tags(); |
| 879 | + if (tags.size() != 0) { |
| 880 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 881 | + TagElement tagEl = (TagElement) iter.next(); |
| 882 | + if ("@j2sIgnore".equals(tagEl.getTagName())) { |
| 883 | + return false; |
| 884 | + } |
| 885 | + } |
| 886 | + if (isDebugging()) { |
| 887 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 888 | + TagElement tagEl = (TagElement) iter.next(); |
| 889 | + if ("@j2sDebug".equals(tagEl.getTagName())) { |
| 890 | + isJ2S = true; |
| 891 | + break; |
| 892 | + } |
| 893 | + } |
| 894 | + } |
| 895 | + if (!isJ2S) { |
| 896 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 897 | + TagElement tagEl = (TagElement) iter.next(); |
| 898 | + if ("@j2sNative".equals(tagEl.getTagName())) { |
| 899 | + isJ2S = true; |
| 900 | + break; |
| 901 | + } |
| 902 | + } |
| 903 | + } |
| 904 | + } |
| 905 | + } |
| 906 | + } |
| 907 | + if (!isJ2S) { |
| 908 | + return false; |
| 909 | + } |
| 910 | + } |
| 911 | + return super.visit(node); |
| 912 | + } |
808 | 913 | /* (non-Javadoc) |
809 | 914 | * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldAccess) |
810 | 915 | */ |
@@ -837,6 +942,206 @@ public boolean visit(FieldAccess node) { |
837 | 942 | } |
838 | 943 | return super.visit(node); |
839 | 944 | } |
| 945 | + |
| 946 | + public boolean visit(Block node) { |
| 947 | + ASTNode parent = node.getParent(); |
| 948 | + if (parent instanceof MethodDeclaration) { |
| 949 | + MethodDeclaration method = (MethodDeclaration) parent; |
| 950 | + Javadoc javadoc = method.getJavadoc(); |
| 951 | + /* |
| 952 | + * if comment contains "@j2sNative", then output the given native |
| 953 | + * JavaScript codes directly. |
| 954 | + */ |
| 955 | + if (visitNativeJavadoc(javadoc, node, true) == false) { |
| 956 | + return false; |
| 957 | + } |
| 958 | + } else if (parent instanceof Initializer) { |
| 959 | + Initializer initializer = (Initializer) parent; |
| 960 | + Javadoc javadoc = initializer.getJavadoc(); |
| 961 | + /* |
| 962 | + * if comment contains "@j2sNative", then output the given native |
| 963 | + * JavaScript codes directly. |
| 964 | + */ |
| 965 | + if (visitNativeJavadoc(javadoc, node, true) == false) { |
| 966 | + return false; |
| 967 | + } |
| 968 | + } |
| 969 | + int blockStart = node.getStartPosition(); |
| 970 | + int previousStart = getPreviousStartPosition(node); |
| 971 | + ASTNode root = node.getRoot(); |
| 972 | + checkJavadocs(root); |
| 973 | + //for (int i = 0; i < nativeJavadoc.length; i++) { |
| 974 | + for (int i = nativeJavadoc.length - 1; i >= 0; i--) { |
| 975 | + Javadoc javadoc = nativeJavadoc[i]; |
| 976 | + int commentStart = javadoc.getStartPosition(); |
| 977 | + if (commentStart > previousStart && commentStart < blockStart) { |
| 978 | + /* |
| 979 | + * if the block's leading comment contains "@j2sNative", |
| 980 | + * then output the given native JavaScript codes directly. |
| 981 | + */ |
| 982 | + if (visitNativeJavadoc(javadoc, node, true) == false) { |
| 983 | + return false; |
| 984 | + } |
| 985 | + } |
| 986 | + } |
| 987 | + return super.visit(node); |
| 988 | + } |
| 989 | + |
| 990 | + boolean visitNativeJavadoc(Javadoc javadoc, Block node, boolean superVisit) { |
| 991 | + if (javadoc != null) { |
| 992 | + List tags = javadoc.tags(); |
| 993 | + if (tags.size() != 0) { |
| 994 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 995 | + TagElement tagEl = (TagElement) iter.next(); |
| 996 | + if ("@j2sIgnore".equals(tagEl.getTagName())) { |
| 997 | + if (superVisit) super.visit(node); |
| 998 | + return false; |
| 999 | + } |
| 1000 | + } |
| 1001 | + if (isDebugging) { |
| 1002 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 1003 | + TagElement tagEl = (TagElement) iter.next(); |
| 1004 | + if ("@j2sDebug".equals(tagEl.getTagName())) { |
| 1005 | + if (superVisit) super.visit(node); |
| 1006 | + List fragments = tagEl.fragments(); |
| 1007 | + boolean isFirstLine = true; |
| 1008 | + for (Iterator iterator = fragments.iterator(); iterator |
| 1009 | + .hasNext();) { |
| 1010 | + TextElement commentEl = (TextElement) iterator.next(); |
| 1011 | + String text = commentEl.getText().trim(); |
| 1012 | + if (isFirstLine) { |
| 1013 | + if (text.length() == 0) { |
| 1014 | + continue; |
| 1015 | + } |
| 1016 | + } |
| 1017 | + buffer.append(text); |
| 1018 | + buffer.append("\r\n"); |
| 1019 | + } |
| 1020 | + return false; |
| 1021 | + } |
| 1022 | + } |
| 1023 | + } |
| 1024 | + if (!toCompileVariableName) { |
| 1025 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 1026 | + TagElement tagEl = (TagElement) iter.next(); |
| 1027 | + if ("@j2sNativeSrc".equals(tagEl.getTagName())) { |
| 1028 | + if (superVisit) super.visit(node); |
| 1029 | + List fragments = tagEl.fragments(); |
| 1030 | + boolean isFirstLine = true; |
| 1031 | + for (Iterator iterator = fragments.iterator(); iterator |
| 1032 | + .hasNext();) { |
| 1033 | + TextElement commentEl = (TextElement) iterator.next(); |
| 1034 | + String text = commentEl.getText().trim(); |
| 1035 | + if (isFirstLine) { |
| 1036 | + if (text.length() == 0) { |
| 1037 | + continue; |
| 1038 | + } |
| 1039 | + } |
| 1040 | + buffer.append(text); |
| 1041 | + buffer.append("\r\n"); |
| 1042 | + } |
| 1043 | + return false; |
| 1044 | + } |
| 1045 | + } |
| 1046 | + } |
| 1047 | + for (Iterator iter = tags.iterator(); iter.hasNext();) { |
| 1048 | + TagElement tagEl = (TagElement) iter.next(); |
| 1049 | + if ("@j2sNative".equals(tagEl.getTagName())) { |
| 1050 | + if (superVisit) super.visit(node); |
| 1051 | + List fragments = tagEl.fragments(); |
| 1052 | + boolean isFirstLine = true; |
| 1053 | + for (Iterator iterator = fragments.iterator(); iterator |
| 1054 | + .hasNext();) { |
| 1055 | + TextElement commentEl = (TextElement) iterator.next(); |
| 1056 | + String text = commentEl.getText().trim(); |
| 1057 | + if (isFirstLine) { |
| 1058 | + if (text.length() == 0) { |
| 1059 | + continue; |
| 1060 | + } |
| 1061 | + } |
| 1062 | + buffer.append(text); |
| 1063 | + buffer.append("\r\n"); |
| 1064 | + } |
| 1065 | + return false; |
| 1066 | + } |
| 1067 | + } |
| 1068 | + } |
| 1069 | + } |
| 1070 | + return true; |
| 1071 | + } |
| 1072 | + |
| 1073 | + private void checkJavadocs(ASTNode root) { |
| 1074 | + if (root != javadocRoot) { |
| 1075 | + nativeJavadoc = null; |
| 1076 | + javadocRoot = root; |
| 1077 | + } |
| 1078 | + if (nativeJavadoc == null) { |
| 1079 | + nativeJavadoc = new Javadoc[0]; |
| 1080 | + if (root instanceof CompilationUnit) { |
| 1081 | + CompilationUnit unit = (CompilationUnit) root; |
| 1082 | + List commentList = unit.getCommentList(); |
| 1083 | + ArrayList list = new ArrayList(); |
| 1084 | + for (Iterator iter = commentList.iterator(); iter.hasNext();) { |
| 1085 | + Comment comment = (Comment) iter.next(); |
| 1086 | + if (comment instanceof Javadoc) { |
| 1087 | + Javadoc javadoc = (Javadoc) comment; |
| 1088 | + List tags = javadoc.tags(); |
| 1089 | + if (tags.size() != 0) { |
| 1090 | + for (Iterator itr = tags.iterator(); itr.hasNext();) { |
| 1091 | + TagElement tagEl = (TagElement) itr.next(); |
| 1092 | + String tagName = tagEl.getTagName(); |
| 1093 | + if ("@j2sIgnore".equals(tagName) |
| 1094 | + || "@j2sDebug".equals(tagName) |
| 1095 | + || "@j2sNative".equals(tagName)) { |
| 1096 | + list.add(comment); |
| 1097 | + } |
| 1098 | + } |
| 1099 | + } |
| 1100 | + } |
| 1101 | + } |
| 1102 | + nativeJavadoc = (Javadoc[]) list.toArray(nativeJavadoc); |
| 1103 | + } |
| 1104 | + } |
| 1105 | + } |
| 1106 | + |
| 1107 | + private int getPreviousStartPosition(Block node) { |
| 1108 | + int previousStart = 0; |
| 1109 | + ASTNode blockParent = node.getParent(); |
| 1110 | + if (blockParent != null) { |
| 1111 | + if (blockParent instanceof Statement) { |
| 1112 | + Statement sttmt = (Statement) blockParent; |
| 1113 | + previousStart = sttmt.getStartPosition(); |
| 1114 | + if (sttmt instanceof Block) { |
| 1115 | + Block parentBlock = (Block) sttmt; |
| 1116 | + for (Iterator iter = parentBlock.statements().iterator(); iter.hasNext();) { |
| 1117 | + Statement element = (Statement) iter.next(); |
| 1118 | + if (element == node) { |
| 1119 | + break; |
| 1120 | + } |
| 1121 | + previousStart = element.getStartPosition() + element.getLength(); |
| 1122 | + } |
| 1123 | + } else if (sttmt instanceof IfStatement) { |
| 1124 | + IfStatement ifSttmt = (IfStatement) sttmt; |
| 1125 | + if (ifSttmt.getElseStatement() == node) { |
| 1126 | + Statement thenSttmt = ifSttmt.getThenStatement(); |
| 1127 | + previousStart = thenSttmt.getStartPosition() + thenSttmt.getLength(); |
| 1128 | + } |
| 1129 | + } |
| 1130 | + } else if (blockParent instanceof MethodDeclaration) { |
| 1131 | + MethodDeclaration method = (MethodDeclaration) blockParent; |
| 1132 | + previousStart = method.getStartPosition(); |
| 1133 | + } else if (blockParent instanceof Initializer) { |
| 1134 | + Initializer initializer = (Initializer) blockParent; |
| 1135 | + previousStart = initializer.getStartPosition(); |
| 1136 | + } else if (blockParent instanceof CatchClause) { |
| 1137 | + CatchClause catchClause = (CatchClause) blockParent; |
| 1138 | + previousStart = catchClause.getStartPosition(); |
| 1139 | + } |
| 1140 | + } |
| 1141 | + return previousStart; |
| 1142 | + } |
| 1143 | + |
| 1144 | + |
840 | 1145 | } |
841 | 1146 |
|
842 | 1147 | class QNTypeBinding { |
|
0 commit comments