Source code: mijava/Interface.java
1 /*
2 @(#) $Id: Interface.java,v 1.7 2002/03/27 18:50:29 hobb0001 Exp $
3 Copyright 2002 Michael Hobbs
4
5 This file is part of MIJava.
6
7 MIJava is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 MIJava is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with MIJava; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 package mijava;
23
24 import java.util.Collection;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.HashSet;
29 import java.util.regex.Pattern;
30 import java.util.regex.Matcher;
31
32
33
34 class Interface
35 {
36
37 public static DiffString generate
38 (Parser.ClassInfo clazz, Parser.Result parseResult)
39 {
40 Interface iface = new Interface(clazz, parseResult);
41 return iface.ds;
42 }
43
44 private DiffString ds;
45 private DiffString parsedDS;
46
47 private Interface(Parser.ClassInfo clazz, Parser.Result parseResult)
48 {
49 parsedDS = parseResult.parsedString;
50 ds = new DiffString(parsedDS.getOriginal());
51 for (Iterator i=parseResult.classes.iterator(); i.hasNext(); ) {
52 Parser.ClassInfo fileClass = (Parser.ClassInfo) i.next();
53 if (fileClass != clazz) {
54 // Remove this class from the interface file.
55 ds.delete(fileClass.modifierText.start, fileClass.bodyText.end,
56 parsedDS);
57 } else {
58 modClass(fileClass);
59 }
60 }
61 }
62
63 private void modClass(Parser.ClassInfo clazz)
64 {
65 // Remove the modifiers 'abstract' and 'final' from the interface
66 // declaration.
67 removeModifiers(clazz.modifierText, new String[]{"abstract", "final"});
68 ds.replace(clazz.classText, parsedDS, "interface");
69 modExtends(clazz);
70 ds.delete(clazz.implementsText, parsedDS);
71 int prevMethodEnd = clazz.bodyText.start + 1;
72 for (Iterator i=clazz.members.iterator(); i.hasNext(); ) {
73 Object member = i.next();
74 if (member instanceof Parser.MethodInfo) {
75 Parser.MethodInfo method = (Parser.MethodInfo) member;
76 // Remove everything between this method and the previous one.
77 ds.replace(prevMethodEnd, method.modifierText.start, parsedDS, "\n");
78 modMethod(method);
79 prevMethodEnd = method.bodyText.end;
80 }
81 }
82 // Remove everything after the last method.
83 ds.replace(prevMethodEnd, clazz.bodyText.end - 1, parsedDS,
84 "\nstatic final boolean $isMIClass$ = true;\n");
85 ds.insert(clazz.bodyText.end - 1, parsedDS,
86 "void $set$" + clazz.name + "(" + clazz.name + " o);\n");
87 }
88
89 private void modExtends(Parser.ClassInfo clazz)
90 {
91 if (clazz.interfaces.size() == 0) return;
92 CharSequence implementedIfaces = genList(clazz.interfaces);
93 if (clazz.extendsText.start != clazz.extendsText.end) {
94 ds.insert(clazz.extendsText.end, parsedDS, "," + implementedIfaces);
95 } else {
96 ds.insert(clazz.extendsText.start, parsedDS,
97 " extends " + implementedIfaces);
98 }
99 }
100
101 private void modMethod(Parser.MethodInfo method)
102 {
103 // If methodInfo.type == "", then the method is actually a constructor.
104 if (method.type.length() == 0 ||
105 method.modifiers.contains("private")) {
106 // Remove this method from the interface declaration.
107 ds.delete(method.modifierText.start, method.bodyText.end, parsedDS);
108 return;
109 }
110 // No class method modifiers really apply to interface methods.
111 ds.delete(method.modifierText, parsedDS);
112 ds.replace(method.bodyText, parsedDS, ";");
113 if (method.modifiers.contains("static")) {
114 ds.insert(method.nameText.start, parsedDS, "$static$");
115 }
116 }
117
118 private static final Pattern wordP = Pattern.compile("[a-z]+");
119
120 private void removeModifiers
121 (DiffString.Range modifierText, String[] modifiers)
122 {
123 Matcher m = wordP.matcher(parsedDS.subSequence(modifierText.start,
124 modifierText.end));
125 for (int start=0; m.find(start); start=m.end()) {
126 // Assume that the 'modifiers' array is short.
127 modifier:
128 for (int i=0; i<modifiers.length; ++i) {
129 if (m.group().equals(modifiers[i])) {
130 int begin = modifierText.start + m.start();
131 int end = modifierText.start + m.end();
132 ds.delete(begin, end, parsedDS);
133 break modifier;
134 }
135 }
136 }
137 }
138
139 private static CharSequence genList(Collection c)
140 {
141 StringBuffer result = new StringBuffer();
142 boolean first = true;
143 for (Iterator i=c.iterator(); i.hasNext(); first=false) {
144 if (!first) {
145 result.append(",");
146 }
147 result.append(i.next());
148 }
149 return result;
150 }
151
152 private static final String _ID_ =
153 "@(#) $Id: Interface.java,v 1.7 2002/03/27 18:50:29 hobb0001 Exp $";
154 }