Skip to content

Commit eda1ace

Browse files
authored
Merge pull request #143 from codellm-devkit/lexical-printer-error
Lexical printer error
2 parents 7dbfded + 1b278d1 commit eda1ace

File tree

3 files changed

+181
-1
lines changed

3 files changed

+181
-1
lines changed

src/main/java/com/ibm/cldk/SymbolTable.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.github.javaparser.ast.stmt.*;
1212
import com.github.javaparser.ast.type.ReferenceType;
1313
import com.github.javaparser.ast.type.Type;
14+
import com.github.javaparser.printer.DefaultPrettyPrinter;
1415
import com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter;
1516
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
1617
import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration;
@@ -554,7 +555,15 @@ private static Pair<String, Callable> processCallableDeclaration(CallableDeclara
554555
callableNode.setStartLine(callableDecl.getRange().isPresent() ? callableDecl.getRange().get().begin.line : -1);
555556
callableNode.setEndLine(callableDecl.getRange().isPresent() ? callableDecl.getRange().get().end.line : -1);
556557
callableNode.setReferencedTypes(getReferencedTypes(body));
557-
callableNode.setCode(body.isPresent() ? LexicalPreservingPrinter.print(body.get()) : "");
558+
try {
559+
callableNode.setCode(body.isPresent() ? LexicalPreservingPrinter.print(body.get()) : "");
560+
} catch (UnsupportedOperationException uoe) {
561+
Log.warn("LexicalPreservingPrinter.print() failed on method " + callableDecl.getSignature() +
562+
" of type "+typeName);
563+
Log.warn("Reverting to default printing");
564+
Log.warn(body.get().toString());
565+
callableNode.setCode(body.get().toString());
566+
}
558567
callableNode.setCodeStartLine(body.isPresent()? body.get().getBegin().get().line : -1);
559568

560569
callableNode.setAccessedFields(getAccessedFields(body, classFields, typeName));

src/test/java/com/ibm/cldk/SymbolTableTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ public void testExtractSingleMissingNodeRange() throws IOException {
5656
Assertions.assertEquals(2, typeDeclaration.size());
5757
}
5858

59+
@Test
60+
public void testExtractSingleDefaultKeywordMethodDecl() throws IOException {
61+
String javaCode = getJavaCodeForTestResource("test-applications/default-keyword-method-decl/IndexExtractor.java");
62+
Map<String, JavaCompilationUnit> symbolTable = SymbolTable.extractSingle(javaCode).getLeft();
63+
Assertions.assertEquals(1, symbolTable.size());
64+
Map<String, Type> typeDeclaration = symbolTable.values().iterator().next().getTypeDeclarations();
65+
Assertions.assertEquals(1, typeDeclaration.size());
66+
Map<String, Callable> callables = typeDeclaration.values().iterator().next().getCallableDeclarations();
67+
Assertions.assertEquals(5, callables.size());
68+
}
69+
5970
@Test
6071
public void testCallSiteArgumentExpression() throws IOException {
6172
String javaCode = getJavaCodeForTestResource("test-applications/generics-varargs-duplicate-signature-test/Validate.java");
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import java.util.Arrays;
2+
import java.util.BitSet;
3+
import java.util.Objects;
4+
import java.util.function.IntPredicate;
5+
import java.util.function.LongPredicate;
6+
7+
/**
8+
* An object that produces indices of a Bloom filter.
9+
* <p><em>
10+
* The default implementation of {@code asIndexArray} is slow. Implementers should reimplement the
11+
* method where possible.</em></p>
12+
*
13+
* @since 4.5.0-M2
14+
*/
15+
@FunctionalInterface
16+
public interface IndexExtractor {
17+
18+
/**
19+
* Creates an IndexExtractor from a {@code BitMapExtractor}.
20+
*
21+
* @param bitMapExtractor the {@code BitMapExtractor}
22+
* @return a new {@code IndexExtractor}.
23+
*/
24+
static IndexExtractor fromBitMapExtractor(final BitMapExtractor bitMapExtractor) {
25+
Objects.requireNonNull(bitMapExtractor, "bitMapExtractor");
26+
return consumer -> {
27+
final LongPredicate longPredicate = new LongPredicate() {
28+
int wordIdx;
29+
30+
@Override
31+
public boolean test(long word) {
32+
int i = wordIdx;
33+
while (word != 0) {
34+
if ((word & 1) == 1 && !consumer.test(i)) {
35+
return false;
36+
}
37+
word >>>= 1;
38+
i++;
39+
}
40+
wordIdx += 64;
41+
return true;
42+
}
43+
};
44+
return bitMapExtractor.processBitMaps(longPredicate::test);
45+
};
46+
}
47+
48+
/**
49+
* Creates an IndexExtractor from an array of integers.
50+
*
51+
* @param values the index values
52+
* @return an IndexExtractor that uses the values.
53+
*/
54+
static IndexExtractor fromIndexArray(final int... values) {
55+
return new IndexExtractor() {
56+
57+
@Override
58+
public int[] asIndexArray() {
59+
return values.clone();
60+
}
61+
62+
@Override
63+
public boolean processIndices(final IntPredicate predicate) {
64+
for (final int value : values) {
65+
if (!predicate.test(value)) {
66+
return false;
67+
}
68+
}
69+
return true;
70+
}
71+
};
72+
}
73+
74+
/**
75+
* Return a copy of the IndexExtractor data as an int array.
76+
*
77+
* <p>Indices ordering and uniqueness is not guaranteed.</p>
78+
*
79+
* <p><em>
80+
* The default implementation of this method creates an array and populates
81+
* it. Implementations that have access to an index array should consider
82+
* returning a copy of that array if possible.
83+
* </em></p>
84+
*
85+
* @return An int array of the data.
86+
*/
87+
default int[] asIndexArray() {
88+
final class Indices {
89+
private int[] data = new int[32];
90+
private int size;
91+
92+
boolean add(final int index) {
93+
data = IndexUtils.ensureCapacityForAdd(data, size);
94+
data[size++] = index;
95+
return true;
96+
}
97+
98+
int[] toArray() {
99+
// Edge case to avoid a large array copy
100+
return size == data.length ? data : Arrays.copyOf(data, size);
101+
}
102+
}
103+
final Indices indices = new Indices();
104+
processIndices(indices::add);
105+
return indices.toArray();
106+
}
107+
108+
/**
109+
* Each index is passed to the predicate. The predicate is applied to each
110+
* index value, if the predicate returns {@code false} the execution is stopped, {@code false}
111+
* is returned, and no further indices are processed.
112+
*
113+
* <p>Any exceptions thrown by the action are relayed to the caller.</p>
114+
*
115+
* <p>Indices ordering and uniqueness is not guaranteed.</p>
116+
*
117+
* @param predicate the action to be performed for each non-zero bit index.
118+
* @return {@code true} if all indexes return true from consumer, {@code false} otherwise.
119+
* @throws NullPointerException if the specified action is null
120+
*/
121+
boolean processIndices(IntPredicate predicate);
122+
123+
/**
124+
* Creates an IndexExtractor comprising the unique indices for this extractor.
125+
*
126+
* <p>By default creates a new extractor with some overhead to remove
127+
* duplicates. IndexExtractors that return unique indices by default
128+
* should override this to return {@code this}.</p>
129+
*
130+
* <p>The default implementation will filter the indices from this instance
131+
* and return them in ascending order.</p>
132+
*
133+
* @return the IndexExtractor of unique values.
134+
* @throws IndexOutOfBoundsException if any index is less than zero.
135+
*/
136+
default IndexExtractor uniqueIndices() {
137+
final BitSet bitSet = new BitSet();
138+
processIndices(i -> {
139+
bitSet.set(i);
140+
return true;
141+
});
142+
143+
return new IndexExtractor() {
144+
@Override
145+
public boolean processIndices(final IntPredicate predicate) {
146+
for (int idx = bitSet.nextSetBit(0); idx >= 0; idx = bitSet.nextSetBit(idx + 1)) {
147+
if (!predicate.test(idx)) {
148+
return false;
149+
}
150+
}
151+
return true;
152+
}
153+
154+
@Override
155+
public IndexExtractor uniqueIndices() {
156+
return this;
157+
}
158+
};
159+
}
160+
}

0 commit comments

Comments
 (0)