12
12
package net .sf .j2s .core .astvisitors ;
13
13
14
14
import java .util .ArrayList ;
15
+ import java .util .HashSet ;
15
16
import java .util .Iterator ;
16
17
import java .util .List ;
18
+ import java .util .Set ;
17
19
import java .util .regex .Pattern ;
18
20
19
21
import org .eclipse .jdt .core .dom .ASTNode ;
@@ -173,6 +175,14 @@ boolean visitNativeJavadoc(Javadoc javadoc, Block node, boolean superVisit) {
173
175
return false ;
174
176
}
175
177
}
178
+ for (Iterator iter = tags .iterator (); iter .hasNext ();) {
179
+ TagElement tagEl = (TagElement ) iter .next ();
180
+ if ("@j2sXHTML" .equals (tagEl .getTagName ()) || "@j2sXCSS" .equals (tagEl .getTagName ())) {
181
+ if (superVisit ) super .visit (node );
182
+ visitJavadocXStringSource (tagEl , tagEl .getTagName ());
183
+ return false ;
184
+ }
185
+ }
176
186
}
177
187
}
178
188
return true ;
@@ -196,6 +206,267 @@ private void visitJavadocJ2SSource(TagElement tagEl) {
196
206
}
197
207
buffer .append (fixCommentBlock (buf .toString ()));
198
208
}
209
+
210
+ private void visitJavadocXStringSource (TagElement tagEl , String tagName ) {
211
+ List fragments = tagEl .fragments ();
212
+ boolean isFirstLine = true ;
213
+ StringBuffer buf = new StringBuffer ();
214
+ String firstLine = null ;
215
+ for (Iterator iterator = fragments .iterator (); iterator
216
+ .hasNext ();) {
217
+ TextElement commentEl = (TextElement ) iterator .next ();
218
+ String text = commentEl .getText ().trim ();
219
+ if (isFirstLine ) {
220
+ if (text .length () == 0 ) {
221
+ continue ;
222
+ }
223
+ firstLine = text .trim ();
224
+ isFirstLine = false ;
225
+ continue ;
226
+ }
227
+ buf .append (text );
228
+ buf .append ("\r \n " );
229
+ }
230
+ String sources = buf .toString ().trim ();
231
+ sources = buildXSource (tagName , firstLine , sources );
232
+ buffer .append (sources );
233
+ }
234
+
235
+ private Set <String > parseXTag (String sources ) {
236
+ Set <String > vars = new HashSet <String >();
237
+ String key = "{$" ;
238
+ int index = sources .indexOf (key , 0 );
239
+ while (index != -1 ) {
240
+ int idx = sources .indexOf ("}" , index + key .length ());
241
+ if (idx == -1 ) {
242
+ break ;
243
+ }
244
+ String var = sources .substring (index + key .length () - 1 , idx ); // with prefix $
245
+ if (var .indexOf (' ' ) == -1 ) {
246
+ vars .add (var );
247
+ }
248
+ index = sources .indexOf (key , idx + 1 );
249
+ }
250
+ key = "<!--" ;
251
+ index = sources .indexOf (key , 0 );
252
+ while (index != -1 ) {
253
+ int idx = sources .indexOf ("-->" , index + key .length ());
254
+ if (idx == -1 ) {
255
+ break ;
256
+ }
257
+ String comment = sources .substring (index + key .length (), idx ).trim ();
258
+ if (comment .startsWith ("$" ) && comment .indexOf (' ' ) == -1 ) {
259
+ vars .add (comment );
260
+ }
261
+ index = sources .indexOf (key , idx + 3 ); // 3: "-->".length()
262
+ }
263
+ key = "id" ;
264
+ index = sources .indexOf (key , 0 );
265
+ while (index > 0 ) {
266
+ char last = sources .charAt (index - 1 );
267
+ if (!(last == ' ' || last == '\t' || last == '\n' || last == '\r' )) {
268
+ index = sources .indexOf (key , index + key .length ());
269
+ continue ;
270
+ }
271
+ int idxEqual = index + key .length ();
272
+ do {
273
+ char c = sources .charAt (idxEqual );
274
+ if (c == '=' ) {
275
+ break ;
276
+ } else if (c == ' ' || c == '\t' ) {
277
+ idxEqual ++;
278
+ if (idxEqual == sources .length () - 1 ) {
279
+ idxEqual = -1 ;
280
+ break ;
281
+ }
282
+ } else {
283
+ idxEqual = -1 ;
284
+ break ;
285
+ }
286
+ } while (true );
287
+ if (idxEqual == -1 || idxEqual == sources .length () - 1 ) {
288
+ break ;
289
+ }
290
+ char quote = 0 ;
291
+ int idxQuoteStart = idxEqual + 1 ;
292
+ do {
293
+ char c = sources .charAt (idxQuoteStart );
294
+ if (c == '\'' || c == '\"' ) {
295
+ quote = c ;
296
+ break ;
297
+ } else if (c == ' ' || c == '\t' ) {
298
+ idxQuoteStart ++;
299
+ if (idxQuoteStart == sources .length () - 1 ) {
300
+ idxQuoteStart = -1 ;
301
+ break ;
302
+ }
303
+ } else {
304
+ idxQuoteStart = -1 ;
305
+ break ;
306
+ }
307
+ } while (true );
308
+ if (idxQuoteStart == -1 || idxQuoteStart == sources .length () - 1 ) {
309
+ break ;
310
+ }
311
+ int idxQuoteEnd = sources .indexOf (quote , idxQuoteStart + 1 );
312
+ if (idxQuoteEnd == -1 || idxQuoteEnd == sources .length () - 1 ) {
313
+ break ;
314
+ }
315
+ String idStr = sources .substring (idxQuoteStart + 1 , idxQuoteEnd ).trim ();
316
+ if (idStr .startsWith ("$" ) && idStr .indexOf (' ' ) == -1 ) {
317
+ vars .add (idStr );
318
+ }
319
+ index = sources .indexOf (key , idxQuoteEnd + 1 );
320
+ }
321
+ return vars ;
322
+ }
323
+
324
+ private boolean containsBeginning (Set <String > set , String beginning ) {
325
+ for (String s : set ) {
326
+ if (s .startsWith (beginning )) {
327
+ return true ;
328
+ }
329
+ }
330
+ return false ;
331
+ }
332
+
333
+ private String buildXSource (String tagName , String firstLine , String sources ) {
334
+ if (firstLine != null && sources .length () > 0 ) {
335
+ Set <String > xTags = null ;
336
+ StringBuilder builder = new StringBuilder ();
337
+ if ("@j2sXHTML" .equals (tagName )) {
338
+ boolean shouldMergeFirstLine = false ;
339
+ if (firstLine .startsWith ("{$" ) || firstLine .contains ("<" ) || firstLine .contains (">" )) {
340
+ shouldMergeFirstLine = true ;
341
+ }
342
+ if (shouldMergeFirstLine ) {
343
+ sources = firstLine + "\r \n " + sources ;
344
+ firstLine = "" ;
345
+ }
346
+ xTags = parseXTag (sources );
347
+ sources = "\" " + sources .replaceAll ("\t " , "\\ \\ t" ).replaceAll ("\" " , "\\ \\ \" " ).replaceAll ("\r \n " , "\\ \\ r\\ \\ n\" +\r \n \" " ) + "\" " ;
348
+ String [] parts = firstLine .split ("(,| |\t )+" );
349
+ if (firstLine .length () == 0 ) {
350
+ builder .append ("Clazz.parseHTML(" );
351
+ } else if (parts == null || parts .length == 1 ) {
352
+ if ("return" .equals (firstLine )) {
353
+ builder .append ("return Clazz.parseHTML(" );
354
+ } else {
355
+ builder .append ("Clazz.parseHTML(" ).append (firstLine ).append (", " );
356
+ }
357
+ } else {
358
+ String firstVar = parts [0 ];
359
+ String leftStr = firstLine .substring (firstVar .length () + 1 ).replaceAll ("^(,| |\t )+" , "" );
360
+ if (leftStr .endsWith ("," )) {
361
+ leftStr = leftStr .substring (0 , leftStr .length () - 1 );
362
+ }
363
+ if ("return" .equals (firstVar )) {
364
+ builder .append ("return Clazz.parseHTML(" ).append (leftStr ).append (", " );
365
+ } else {
366
+ builder .append (firstVar ).append (" = Clazz.parseHTML(" ).append (leftStr ).append (", " );
367
+ }
368
+ }
369
+ } else { // @j2sXCSS
370
+ boolean shouldMergeFirstLine = false ;
371
+ if (firstLine .startsWith ("." ) || firstLine .contains ("#" ) || firstLine .contains (">" ) || firstLine .contains ("{" )) {
372
+ shouldMergeFirstLine = true ;
373
+ } else if (sources .startsWith ("{" )) {
374
+ shouldMergeFirstLine = true ;
375
+ }
376
+ if (shouldMergeFirstLine ) {
377
+ sources = firstLine + "\r \n " + sources ;
378
+ xTags = parseXTag (sources );
379
+ builder .append ("Clazz.parseCSS(" );
380
+ } else {
381
+ xTags = parseXTag (sources );
382
+ if (firstLine .endsWith ("," )) {
383
+ firstLine = firstLine .substring (0 , firstLine .length () - 1 );
384
+ }
385
+ builder .append ("Clazz.parseCSS(" ).append (firstLine ).append (", " );
386
+ }
387
+ sources = "\" " + sources .replaceAll ("\t " , "\\ \\ t" ).replaceAll ("\" " , "\\ \\ \" " ).replaceAll ("\r \n " , "\\ \\ r\\ \\ n\" +\r \n \" " ) + "\" " ;
388
+ }
389
+ boolean containsThis = containsBeginning (xTags , "$:" ) || containsBeginning (xTags , "$." );
390
+ boolean containsClass = containsBeginning (xTags , "$/" );
391
+ if (containsThis ) {
392
+ builder .append ("this, " );
393
+ } else if (containsClass ) {
394
+ String fullClassName = null ;
395
+ String packageName = ((ASTPackageVisitor ) getAdaptable (ASTPackageVisitor .class )).getPackageName ();
396
+ String className = ((ASTTypeVisitor ) getAdaptable (ASTTypeVisitor .class )).getClassName ();
397
+ if (packageName != null && packageName .length () != 0 ) {
398
+ fullClassName = packageName + '.' + className ;
399
+ } else {
400
+ fullClassName = className ;
401
+ }
402
+ builder .append (fullClassName ).append (", " );
403
+ }
404
+ boolean localStarted = false ;
405
+ for (String s : xTags ) {
406
+ if (s .startsWith ("$~" )) {
407
+ if (!localStarted ) {
408
+ builder .append ("{" );
409
+ localStarted = true ;
410
+ } else {
411
+ builder .append (", " );
412
+ }
413
+ String varName = s .substring (2 );
414
+ builder .append (varName ).append (": " ).append (varName );
415
+ }
416
+ }
417
+ if (localStarted ) {
418
+ builder .append ("}, " );
419
+ }
420
+ builder .append (sources ).append (");\r \n " );
421
+ return builder .toString ();
422
+ }
423
+ return sources ;
424
+ }
425
+
426
+ /*
427
+ * Read HTML/CSS sources from @j2sXHTML, @J2SXCSS or others
428
+ */
429
+ boolean readStringSources (BodyDeclaration node , String tagName , String prefix , String suffix , boolean both ) {
430
+ boolean existed = false ;
431
+ Javadoc javadoc = node .getJavadoc ();
432
+ if (javadoc != null ) {
433
+ List tags = javadoc .tags ();
434
+ if (tags .size () != 0 ) {
435
+ for (Iterator iter = tags .iterator (); iter .hasNext ();) {
436
+ TagElement tagEl = (TagElement ) iter .next ();
437
+ if (tagName .equals (tagEl .getTagName ())) {
438
+ if (tagEl != null ) {
439
+ List fragments = tagEl .fragments ();
440
+ StringBuffer buf = new StringBuffer ();
441
+ boolean isFirstLine = true ;
442
+ String firstLine = null ;
443
+ for (Iterator iterator = fragments .iterator (); iterator
444
+ .hasNext ();) {
445
+ TextElement commentEl = (TextElement ) iterator .next ();
446
+ String text = commentEl .getText ().trim ();
447
+ if (isFirstLine ) {
448
+ if (text .length () == 0 ) {
449
+ continue ;
450
+ }
451
+ firstLine = text .trim ();
452
+ isFirstLine = false ;
453
+ continue ;
454
+ }
455
+ buf .append (text );
456
+ buf .append ("\r \n " );
457
+ }
458
+ String sources = buf .toString ().trim ();
459
+ sources = buildXSource (tagName , firstLine , sources );
460
+ buffer .append (prefix + sources + suffix );
461
+ existed = true ;
462
+ }
463
+ }
464
+ }
465
+ }
466
+ }
467
+ return existed ;
468
+ }
469
+
199
470
/*
200
471
* Read JavaScript sources from @j2sNative, @J2SPrefix or others
201
472
*/
@@ -217,6 +488,7 @@ boolean readSources(BodyDeclaration node, String tagName, String prefix, String
217
488
TextElement commentEl = (TextElement ) iterator .next ();
218
489
String text = commentEl .getText ().trim ();
219
490
if (isFirstLine ) {
491
+ isFirstLine = false ;
220
492
if (text .length () == 0 ) {
221
493
continue ;
222
494
}
@@ -225,6 +497,7 @@ boolean readSources(BodyDeclaration node, String tagName, String prefix, String
225
497
buf .append ("\r \n " );
226
498
}
227
499
String sources = buf .toString ().trim ();
500
+ // embed block comments and Javadoc @
228
501
sources = sources .replaceAll ("(\\ /)-\\ *|\\ *-(\\ /)" , "$1*$2" ).replaceAll ("<@>" , "@" );
229
502
buffer .append (prefix + sources + suffix );
230
503
existed = true ;
@@ -309,7 +582,11 @@ private void checkJavadocs(ASTNode root) {
309
582
String tagName = tagEl .getTagName ();
310
583
if ("@j2sIgnore" .equals (tagName )
311
584
|| "@j2sDebug" .equals (tagName )
312
- || "@j2sNative" .equals (tagName )) {
585
+ || "@j2sNative" .equals (tagName )
586
+ || "@j2sNativeSrc" .equals (tagName )
587
+ || "@j2sXHTML" .equals (tagName )
588
+ || "@j2sXCSS" .equals (tagName )
589
+ ) {
313
590
list .add (comment );
314
591
}
315
592
}
@@ -413,6 +690,15 @@ protected boolean isMethodNativeIgnored(MethodDeclaration node) {
413
690
if (getJ2STag (node , "@j2sNative" ) != null ) {
414
691
return false ;
415
692
}
693
+ if (getJ2STag (node , "@j2sNativeSrc" ) != null ) {
694
+ return false ;
695
+ }
696
+ if (getJ2STag (node , "@j2sXHTML" ) != null ) {
697
+ return false ;
698
+ }
699
+ if (getJ2STag (node , "@j2sXCSS" ) != null ) {
700
+ return false ;
701
+ }
416
702
return true ;
417
703
}
418
704
return true ; // interface!
0 commit comments