1212package net .sf .j2s .core .astvisitors ;
1313
1414import java .util .ArrayList ;
15+ import java .util .HashSet ;
1516import java .util .Iterator ;
1617import java .util .List ;
18+ import java .util .Set ;
1719import java .util .regex .Pattern ;
1820
1921import org .eclipse .jdt .core .dom .ASTNode ;
@@ -173,6 +175,14 @@ boolean visitNativeJavadoc(Javadoc javadoc, Block node, boolean superVisit) {
173175 return false ;
174176 }
175177 }
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+ }
176186 }
177187 }
178188 return true ;
@@ -196,6 +206,267 @@ private void visitJavadocJ2SSource(TagElement tagEl) {
196206 }
197207 buffer .append (fixCommentBlock (buf .toString ()));
198208 }
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+
199470 /*
200471 * Read JavaScript sources from @j2sNative, @J2SPrefix or others
201472 */
@@ -217,6 +488,7 @@ boolean readSources(BodyDeclaration node, String tagName, String prefix, String
217488 TextElement commentEl = (TextElement ) iterator .next ();
218489 String text = commentEl .getText ().trim ();
219490 if (isFirstLine ) {
491+ isFirstLine = false ;
220492 if (text .length () == 0 ) {
221493 continue ;
222494 }
@@ -225,6 +497,7 @@ boolean readSources(BodyDeclaration node, String tagName, String prefix, String
225497 buf .append ("\r \n " );
226498 }
227499 String sources = buf .toString ().trim ();
500+ // embed block comments and Javadoc @
228501 sources = sources .replaceAll ("(\\ /)-\\ *|\\ *-(\\ /)" , "$1*$2" ).replaceAll ("<@>" , "@" );
229502 buffer .append (prefix + sources + suffix );
230503 existed = true ;
@@ -309,7 +582,11 @@ private void checkJavadocs(ASTNode root) {
309582 String tagName = tagEl .getTagName ();
310583 if ("@j2sIgnore" .equals (tagName )
311584 || "@j2sDebug" .equals (tagName )
312- || "@j2sNative" .equals (tagName )) {
585+ || "@j2sNative" .equals (tagName )
586+ || "@j2sNativeSrc" .equals (tagName )
587+ || "@j2sXHTML" .equals (tagName )
588+ || "@j2sXCSS" .equals (tagName )
589+ ) {
313590 list .add (comment );
314591 }
315592 }
@@ -413,6 +690,15 @@ protected boolean isMethodNativeIgnored(MethodDeclaration node) {
413690 if (getJ2STag (node , "@j2sNative" ) != null ) {
414691 return false ;
415692 }
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+ }
416702 return true ;
417703 }
418704 return true ; // interface!
0 commit comments