package com.redhat.ceylon.eclipse.code.correct; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.swt.graphics.Image; import com.redhat.ceylon.compiler.typechecker.tree.Node; import com.redhat.ceylon.compiler.typechecker.tree.Tree; import com.redhat.ceylon.ide.common.util.escaping_; import com.redhat.ceylon.model.typechecker.model.Declaration; import com.redhat.ceylon.model.typechecker.model.Type; import com.redhat.ceylon.model.typechecker.model.TypeDeclaration; import com.redhat.ceylon.model.typechecker.model.TypeParameter; import com.redhat.ceylon.model.typechecker.model.Unit; public abstract class DefinitionGenerator { abstract String generateShared(String indent, String delim); abstract String generate(String indent, String delim); abstract String generateSharedFormal(String indent, String delim); abstract boolean isFormalSupported(); abstract Set<Declaration> getImports(); abstract String getBrokenName(); abstract String getDescription(); abstract Type getReturnType(); abstract Map<String, Type> getParameters(); abstract Image getImage(); abstract Tree.CompilationUnit getRootNode(); abstract Node getNode(); static void appendParameters( Map<String,Type> parameters, StringBuffer buffer, TypeDeclaration supertype) { if (parameters.isEmpty()) { buffer.append("()"); } else { buffer.append("("); for (Map.Entry<String,Type> e: parameters.entrySet()) { Declaration member = supertype.getMember(e.getKey(), null, false); if (member==null || !member.isFormal()) { buffer.append(e.getValue().asString()) .append(" "); } buffer.append(e.getKey()).append(", "); } buffer.setLength(buffer.length()-2); buffer.append(")"); } } private static String parameterName( Tree.Expression e, Type et) { Tree.Term term = e.getTerm(); if (term instanceof Tree.StaticMemberOrTypeExpression) { Tree.StaticMemberOrTypeExpression smte = (Tree.StaticMemberOrTypeExpression) term; String id = smte.getIdentifier() .getText(); return escaping_.get_().toInitialLowercase(id); } else { if (et.isClassOrInterface() || et.isTypeParameter()) { String tn = et.getDeclaration().getName(); return escaping_.get_().toInitialLowercase(tn); } else { return "it"; } } } private static Type parameterType( Node arg, Tree.Expression e) { Unit unit = arg.getUnit(); Type et = e==null ? null : e.getTypeModel(); return et == null ? unit.getAnythingType() : unit.denotableType(et); } static LinkedHashMap<String,Type> getParametersFromPositionalArgs( Tree.PositionalArgumentList pal) { LinkedHashMap<String,Type> types = new LinkedHashMap<String,Type>(); int i=0; for (Tree.PositionalArgument pa: pal.getPositionalArguments()) { if (pa instanceof Tree.ListedArgument) { Tree.ListedArgument la = (Tree.ListedArgument) pa; Tree.Expression e = la.getExpression(); Type type = parameterType(pa, e); String name = parameterName(e, type); if (types.containsKey(name)) { name = name + ++i; } types.put(name, type); } } return types; } static LinkedHashMap<String,Type> getParametersFromNamedArgs(Tree.NamedArgumentList nal) { LinkedHashMap<String,Type> types = new LinkedHashMap<String,Type>(); int i=0; for (Tree.NamedArgument a: nal.getNamedArguments()) { if (a instanceof Tree.SpecifiedArgument) { Tree.SpecifiedArgument na = (Tree.SpecifiedArgument) a; Tree.Expression e = na.getSpecifierExpression() .getExpression(); Tree.Identifier id = na.getIdentifier(); Type type = parameterType(a, e); String name = id==null ? parameterName(e, type) : id.getText(); if (types.containsKey(name)) { name = name + ++i; } types.put(name, type); } } return types; } static void appendTypeParams( List<TypeParameter> typeParams, StringBuilder typeParamDef, StringBuilder typeParamConstDef, TypeParameter typeParam) { if (typeParams.contains(typeParam)) { return; } else { typeParams.add(typeParam); } if (typeParam.isContravariant()) { typeParamDef.append("in "); } if (typeParam.isCovariant()) { typeParamDef.append("out "); } typeParamDef.append(typeParam.getName()); Type dta = typeParam.getDefaultTypeArgument(); if (typeParam.isDefaulted() && dta!=null) { typeParamDef.append("="); typeParamDef.append(dta.asString()); } typeParamDef.append(","); if (typeParam.isConstrained()) { typeParamConstDef.append(" given "); typeParamConstDef.append(typeParam.getName()); List<Type> satisfiedTypes = typeParam.getSatisfiedTypes(); if (satisfiedTypes != null && !satisfiedTypes.isEmpty()) { typeParamConstDef.append(" satisfies "); boolean firstSatisfiedType = true; for (Type satisfiedType : satisfiedTypes) { if (firstSatisfiedType) { firstSatisfiedType = false; } else { typeParamConstDef.append("&"); } typeParamConstDef.append(satisfiedType.asString()); } } List<Type> caseTypes = typeParam.getCaseTypes(); if (caseTypes != null && !caseTypes.isEmpty()) { typeParamConstDef.append(" of "); boolean firstCaseType = true; for (Type caseType : caseTypes) { if (firstCaseType) { firstCaseType = false; } else { typeParamConstDef.append("|"); } typeParamConstDef.append(caseType.asString()); } } } } static void appendTypeParams( List<TypeParameter> typeParams, StringBuilder typeParamDef, StringBuilder typeParamConstDef, Type pt) { if (pt != null) { if (pt.isUnion()) { DefinitionGenerator.appendTypeParams(typeParams, typeParamDef, typeParamConstDef, pt.getCaseTypes()); } else if (pt.isIntersection()) { DefinitionGenerator.appendTypeParams(typeParams, typeParamDef, typeParamConstDef, pt.getSatisfiedTypes()); } else if (pt.isTypeParameter()) { appendTypeParams(typeParams, typeParamDef, typeParamConstDef, (TypeParameter) pt.getDeclaration()); } } } static void appendTypeParams(List<TypeParameter> typeParams, StringBuilder typeParamDef, StringBuilder typeParamConstDef, Collection<Type> parameterTypes) { if (parameterTypes != null) { for (Type pt: parameterTypes) { appendTypeParams(typeParams, typeParamDef, typeParamConstDef, pt); } } } // static LinkedHashMap<String,Type> getParameters( // FindArgumentsVisitor fav) { // if (fav.positionalArgs!=null) { // return getParametersFromPositionalArgs( // fav.positionalArgs); // } // else if (fav.namedArgs!=null) { // return getParametersFromNamedArgs( // fav.namedArgs); // } // else { // return null; // } // } }