001    package railo.transformer.cfml.script;
002    
003    import railo.commons.lang.ParserString;
004    import railo.commons.lang.StringUtil;
005    import railo.transformer.bytecode.expression.Expression;
006    import railo.transformer.bytecode.literal.LitBoolean;
007    import railo.transformer.bytecode.literal.LitString;
008    import railo.transformer.bytecode.statement.tag.Attribute;
009    
010    public class DocCommentTransformer {
011            
012            public synchronized DocComment transform(String str){
013                    try{
014                            DocComment dc = new DocComment();
015                            str=str.trim();
016                            if(str.startsWith("/**")) str=str.substring(3);
017                            if(str.endsWith("*/")) str=str.substring(0,str.length()-2);
018                            ParserString ps=new ParserString(str);
019                            transform(dc,ps);
020                            dc.getHint();// TODO do different -> make sure internal structure is valid
021                            return dc;
022                    }
023                    catch(Throwable t){
024                            return null;
025                    }
026            }
027    
028            private void transform(DocComment dc, ParserString ps) {
029                    while(ps.isValidIndex()){
030                            asterix(ps);
031                            ps.removeSpace();
032                            // param
033                            if(ps.forwardIfCurrent('@')){
034                                    dc.addParam(param(ps));
035                            }
036                            // hint
037                            else {
038                                    while(ps.isValidIndex() && ps.getCurrent()!='\n'){
039                                            dc.addHint(ps.getCurrent());
040                                            ps.next();
041                                    }
042                                    dc.addHint('\n');
043                            }
044                            ps.removeSpace();
045                    }
046            }
047    
048            private Attribute param(ParserString ps) {
049                    String name=paramName(ps);
050                    if(name==null) return new Attribute(true,"@",LitBoolean.TRUE,"boolean");
051                    
052                    // white space
053                    while(ps.isValidIndex() && ps.isCurrentWhiteSpace()){
054                            if(ps.getCurrent()=='\n')
055                                    return new Attribute(true,name,LitBoolean.TRUE,"boolean");
056                            ps.next();
057                    }
058                    Expression value = paramValue(ps);
059                    return new Attribute(true,name, value,value instanceof LitBoolean?"boolean":"string");
060            }
061    
062            private String paramName(ParserString ps) {
063                    StringBuilder sb=new StringBuilder();
064                    while(ps.isValidIndex() && !ps.isCurrentWhiteSpace()){
065                            sb.append(ps.getCurrent());
066                            ps.next();
067                    }
068                    if(sb.length()==0) return null;
069                    return sb.toString();
070            }
071    
072            private Expression paramValue(ParserString ps) {
073                    StringBuilder sb=new StringBuilder();
074                    while(ps.isValidIndex() && ps.getCurrent()!='\n'){
075                            sb.append(ps.getCurrent());
076                            ps.next();
077                    }
078                    if(sb.length()==0) return LitBoolean.TRUE;
079                    return LitString.toExprString(unwrap(sb.toString()));
080            }
081    
082            public static String unwrap(String str) {
083                    str = str.trim();
084                    if(StringUtil.startsWith(str, '"') && StringUtil.endsWith(str, '"'))
085                            str=str.substring(1,str.length()-1);
086                    if(StringUtil.startsWith(str, '\'') && StringUtil.endsWith(str, '\''))
087                            str=str.substring(1,str.length()-1);
088                    return str;
089            }
090    
091            private void asterix(ParserString ps) {
092                    do {
093                            ps.removeSpace();
094                    }while(ps.forwardIfCurrent('*'));
095                    
096            }
097            
098    }