/*
* Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.twosigma.beaker.groovy.autocomplete;
import com.twosigma.beaker.autocomplete.AutocompleteCandidate;
import com.twosigma.beaker.autocomplete.AutocompleteRegistry;
import com.twosigma.beaker.autocomplete.ClassUtils;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.AssignmentExpressionContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.ClassNameExpressionContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.DeclarationRuleContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.ExpressionContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.ListConstructorContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.MapConstructorContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.NewInstanceRuleContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.PathExpressionContext;
import com.twosigma.beaker.groovy.autocomplete.GroovyParser.TypeDeclarationContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GroovyNameBuilder extends GroovyAbstractListener{
private static final Logger logger = LoggerFactory.getLogger(GroovyNameBuilder.class.getName());
private AutocompleteRegistry registry;
private ClassUtils classUtils;
public GroovyNameBuilder(AutocompleteRegistry r, ClassUtils cu) {
registry = r;
classUtils = cu;
}
@Override
public void exitDeclarationRule(DeclarationRuleContext ctx) {
if(ctx.getChildCount()==4 &&
ctx.getChild(0) instanceof TypeDeclarationContext &&
ctx.getChild(3) instanceof ExpressionContext &&
ctx.getChild(3).getChildCount()>0) {
if(!ctx.getChild(1).getText().contains(".")) {
if(ctx.getChild(3).getChild(0) instanceof PathExpressionContext) {
String typpen = ctx.getChild(3).getChild(0).getText().trim();
AutocompleteCandidate c = new AutocompleteCandidate(GroovyCompletionTypes.NAME, ctx.getChild(1).getText());
registry.addCandidate(c);
if(GroovyCompletionTypes.debug) logger.info("define variable of type "+ctx.getChild(1).getText()+" "+typpen);
if(classUtils.getVariableType(typpen)!=null) {
classUtils.defineVariable(ctx.getChild(1).getText(), classUtils.getVariableType(typpen));
}
} else if(ctx.getChild(3).getChild(0) instanceof NewInstanceRuleContext) {
ParseTree t = findChildrenByType(ctx.getChild(3).getChild(0),ClassNameExpressionContext.class);
if(t!=null) {
String ttype = t.getText().trim();
AutocompleteCandidate c = new AutocompleteCandidate(GroovyCompletionTypes.NAME, ctx.getChild(1).getText());
registry.addCandidate(c);
if(GroovyCompletionTypes.debug) logger.info("define variable of type "+ctx.getChild(1).getText()+" "+ttype);
if(ttype!=null)
classUtils.defineVariable(ctx.getChild(1).getText(), ttype);
}
} else {
if(GroovyCompletionTypes.debug) System.out.println(((ExpressionContext)ctx.getChild(3)).getStart().getType());
String typpen = null;
if(ctx.getChild(3) instanceof ListConstructorContext)
typpen="Array";
else if(ctx.getChild(3) instanceof MapConstructorContext)
typpen="Map";
else {
switch(((ExpressionContext)ctx.getChild(3)).getStart().getType()) {
case GroovyLexer.STRING: typpen="String"; break;
case GroovyLexer.INTEGER: typpen="Integer"; break;
case GroovyLexer.DECIMAL: typpen="Double"; break;
}
}
AutocompleteCandidate c = new AutocompleteCandidate(GroovyCompletionTypes.NAME, ctx.getChild(1).getText());
registry.addCandidate(c);
if(GroovyCompletionTypes.debug) logger.info("define variable of type "+ctx.getChild(1).getText()+" "+typpen);
if(typpen!=null)
classUtils.defineVariable(ctx.getChild(1).getText(), typpen);
}
}
}
}
@Override
public void exitAssignmentExpression(AssignmentExpressionContext ctx) {
if(ctx.getChildCount()==3 &&
ctx.getChild(1).getText().equals("=") &&
!ctx.getChild(0).getText().contains(".")) {
if(ctx.getChild(2).getChild(0) instanceof PathExpressionContext) {
String typpen = ctx.getChild(2).getChild(0).getText().trim();
AutocompleteCandidate c = new AutocompleteCandidate(GroovyCompletionTypes.NAME, ctx.getChild(0).getText());
registry.addCandidate(c);
if(GroovyCompletionTypes.debug) logger.info("define variable of type "+ctx.getChild(0).getText()+" "+typpen);
if(classUtils.getVariableType(typpen)!=null) {
classUtils.defineVariable(ctx.getChild(0).getText(), classUtils.getVariableType(typpen));
}
} else if(ctx.getChild(2).getChild(0) instanceof NewInstanceRuleContext) {
ParseTree t = findChildrenByType(ctx.getChild(2).getChild(0),ClassNameExpressionContext.class);
if(t!=null) {
String ttype = t.getText().trim();
AutocompleteCandidate c = new AutocompleteCandidate(GroovyCompletionTypes.NAME, ctx.getChild(0).getText());
registry.addCandidate(c);
if(GroovyCompletionTypes.debug) logger.info("define variable of type "+ctx.getChild(0).getText()+" "+ttype);
if(ttype!=null)
classUtils.defineVariable(ctx.getChild(0).getText(), ttype);
}
} else {
if(GroovyCompletionTypes.debug) System.out.println(((ExpressionContext)ctx.getChild(2)).getStart().getType());
String typpen = null;
switch(((ExpressionContext)ctx.getChild(2)).getStart().getType()) {
case GroovyLexer.STRING: typpen="String"; break;
case GroovyLexer.INTEGER: typpen="Integer"; break;
case GroovyLexer.DECIMAL: typpen="Double"; break;
}
AutocompleteCandidate c = new AutocompleteCandidate(GroovyCompletionTypes.NAME, ctx.getChild(0).getText());
registry.addCandidate(c);
if(GroovyCompletionTypes.debug) logger.info("define variable of type "+ctx.getChild(0).getText()+" "+typpen);
if(typpen!=null)
classUtils.defineVariable(ctx.getChild(0).getText(), typpen);
}
}
}
private ParseTree findChildrenByType(ParseTree parseTree, Class<?> classtype) {
for(int i=0; i<parseTree.getChildCount(); i++) {
ParseTree chl = parseTree.getChild(i);
if(chl.getClass().equals(classtype)) {
return chl;
}
}
return null;
}
}