instance type provider, expression context

This commit is contained in:
Maxim Medvedev
2011-05-14 13:12:42 +04:00
parent 5be15ea958
commit 78f92a3339
11 changed files with 53 additions and 51 deletions
@@ -29,9 +29,9 @@ public class AnnotationGenerator extends Generator {
private final ExpressionContext context;
private final ExpressionGenerator expressionGenerator;
public AnnotationGenerator(StringBuilder builder, Project project) {
public AnnotationGenerator(StringBuilder builder, ExpressionContext context) {
this.builder = builder;
this.context = new ExpressionContext(project);
this.context = context.extend();
expressionGenerator = new ExpressionGenerator(builder, context);
}
@@ -105,7 +105,7 @@ public class AnonymousFromMapGenerator {
PsiType returnType;
if (found != null) {
returnType = substitutor.substitute(TypeProvider.getReturnType(found));
returnType = substitutor.substitute(context.typeProvider.getReturnType(found));
}
else {
returnType = signature.getReturnType();
@@ -186,9 +186,9 @@ public class ClassGenerator {
private static boolean shouldBeGenerated(PsiMethod method) {
for (PsiMethod psiMethod : method.findSuperMethods()) {
if (!psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
final PsiType type = TypeProvider.getReturnType(method);
final PsiType superType = TypeProvider.getReturnType(psiMethod);
if (!superType.isAssignableFrom(type)) {
final PsiType type = method.getReturnType();
final PsiType superType = method.getReturnType();
if (type != null && superType != null && !superType.isAssignableFrom(type)) {
return false;
}
}
@@ -120,7 +120,7 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
//append return type
if (!method.isConstructor()) {
PsiType retType = TypeProvider.getReturnType(method);
PsiType retType = context.typeProvider.getReturnType(method);
/*
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
@@ -161,7 +161,7 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
builder.append("default ");
GrAnnotationMemberValue defaultValue = defaultAnnotationValue.getDefaultValue();
if (defaultValue != null) {
defaultValue.accept(new AnnotationGenerator(builder, context.project));
defaultValue.accept(new AnnotationGenerator(builder, context));
}
}
}
@@ -206,7 +206,7 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
builder.append("this");
}
else {
if (TypeProvider.getReturnType(method) != PsiType.VOID) {
if (context.typeProvider.getReturnType(method) != PsiType.VOID) {
builder.append("return ");
}
builder.append(method.getName());
@@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.util.containers.hash.HashSet;
import org.codehaus.groovy.util.ManagedConcurrentMap;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
@@ -91,7 +90,7 @@ public class CodeBlockGenerator extends Generator {
boolean shouldInsertReturnNull = false;
myExitPoints.clear();
PsiType returnType = TypeProvider.getReturnType(method);
PsiType returnType = context.typeProvider.getReturnType(method);
if (!method.isConstructor() && returnType != PsiType.VOID) {
myExitPoints.addAll(ControlFlowUtils.collectReturns(block));
shouldInsertReturnNull = !(returnType instanceof PsiPrimitiveType) &&
@@ -121,7 +120,7 @@ public class CodeBlockGenerator extends Generator {
for (GrParameter parameter : parameters) {
if (context.analyzedVars.toWrap(parameter)) {
StringBuilder typeText = new StringBuilder(GroovyCommonClassNames.GROOVY_LANG_REFERENCE);
GenerationUtil.writeTypeParameters(typeText, new PsiType[]{TypeProvider.getParameterType(parameter)}, method,
GenerationUtil.writeTypeParameters(typeText, new PsiType[]{context.typeProvider.getParameterType(parameter)}, method,
new GeneratorClassNameProvider());
builder.append("final ").append(typeText).append(' ').append(context.analyzedVars.toVarName(parameter))
.append(" = new ").append(typeText).append('(').append(parameter.getName()).append(");\n");
@@ -193,7 +192,7 @@ public class CodeBlockGenerator extends Generator {
return;
}
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(context.project);
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(context);
returnValue.accept(expressionGenerator);
StringBuilder builder = new StringBuilder();
builder.append("return ").append(expressionGenerator.getBuilder()).append(";"); //todo add casts to return type
@@ -209,7 +208,7 @@ public class CodeBlockGenerator extends Generator {
@Override
public void visitAssertStatement(GrAssertStatement assertStatement) {
final GrExpression assertion = assertStatement.getAssertion();
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(context.project);
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(context);
assertion.accept(expressionGenerator);
final StringBuilder builder = new StringBuilder("assert ").append(expressionGenerator.getBuilder()).append(";");
writeStatement(builder, assertStatement, expressionGenerator.getContext());
@@ -218,7 +217,7 @@ public class CodeBlockGenerator extends Generator {
@Override
public void visitThrowStatement(GrThrowStatement throwStatement) {
final GrExpression exception = throwStatement.getException();
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(context.project);
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(context);
exception.accept(expressionGenerator);
final StringBuilder builder =
new StringBuilder("throw ").append(expressionGenerator.getBuilder()).append(";"); //todo add exception to method 'throws' list
@@ -307,7 +306,7 @@ public class CodeBlockGenerator extends Generator {
final GrVariable declaredVariable = clause.getDeclaredVariable();
LOG.assertTrue(declaredVariable != null);
writeVariableWithoutSemicolonAndInitializer(builder, declaredVariable);
writeVariableWithoutSemicolonAndInitializer(builder, declaredVariable, context);
builder.append(" : ");
if (expression != null) {
final ExpressionContext context = forContext.copy();
@@ -322,7 +321,7 @@ public class CodeBlockGenerator extends Generator {
if (initialization instanceof GrParameter) {
StringBuilder partBuilder = new StringBuilder();
writeVariableWithoutSemicolonAndInitializer(partBuilder, (GrParameter)initialization);
writeVariableWithoutSemicolonAndInitializer(partBuilder, (GrParameter)initialization, context);
final GrExpression initializer = ((GrParameter)initialization).getDefaultInitializer();
if (initializer != null) {
final ExpressionContext partContext = forContext.copy();
@@ -371,9 +370,9 @@ public class CodeBlockGenerator extends Generator {
builder.append(visitor.getBuilder());
}
private static void writeVariableWithoutSemicolonAndInitializer(StringBuilder builder, GrVariable var) {
private static void writeVariableWithoutSemicolonAndInitializer(StringBuilder builder, GrVariable var, ExpressionContext context) {
ModifierListGenerator.writeModifiers(builder, var.getModifierList());
GenerationUtil.writeType(builder, TypeProvider.getVarType(var), var);
GenerationUtil.writeType(builder, context.typeProvider.getVarType(var), var);
builder.append(" ").append(var.getName());
}
@@ -422,7 +421,7 @@ public class CodeBlockGenerator extends Generator {
public void visitCatchClause(GrCatchClause catchClause) {
final GrParameter parameter = catchClause.getParameter();
builder.append("catch (");
writeVariableWithoutSemicolonAndInitializer(builder, parameter);
writeVariableWithoutSemicolonAndInitializer(builder, parameter, context);
builder.append(") ");
final GrOpenBlock body = catchClause.getBody();
if (body != null) {
@@ -494,7 +493,7 @@ public class CodeBlockGenerator extends Generator {
final GrModifierList modifierList = variableDeclaration.getModifierList();
for (final GrVariable v : variables) {
ModifierListGenerator.writeModifiers(builder, modifierList);
final PsiType type = TypeProvider.getVarType(v);
final PsiType type = context.typeProvider.getVarType(v);
GenerationUtil.writeType(builder, type, variableDeclaration);
builder.append(" ").append(v.getName());
builder.append(" = ").append(iteratorName).append(".hasNext() ? ").append(iteratorName).append(".next() : null;");
@@ -15,7 +15,6 @@
*/
package org.jetbrains.plugins.groovy.refactoring.convertToJava;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.containers.hash.HashSet;
@@ -30,19 +29,21 @@ class ExpressionContext implements Cloneable {
List<String> myStatements = new ArrayList<String>();
Set<String> myUsedVarNames;
LocalVarAnalyzer.Result analyzedVars = LocalVarAnalyzer.initialResult();
TypeProvider typeProvider;
Project project;
private Map<String, Boolean> myProps = new HashMap<String, Boolean>();
private static final String myShouldInsertCurlyBrackets = "shouldInsertCurly";
private static final String myInAnonymousContext = "inAnonymousContext";
ExpressionContext(Project project, Set<String> usedVarNames) {
private ExpressionContext(Project project, Set<String> usedVarNames) {
this.project = project;
myUsedVarNames = usedVarNames;
}
ExpressionContext(Project project) {
this(project, new HashSet<String>());
typeProvider = new TypeProvider();
}
@Override
@@ -54,6 +55,7 @@ class ExpressionContext implements Cloneable {
final ExpressionContext expressionContext = new ExpressionContext(project, myUsedVarNames);
expressionContext.myProps.putAll(myProps);
expressionContext.analyzedVars = analyzedVars;
expressionContext.typeProvider = typeProvider;
return expressionContext;
}
@@ -63,6 +65,7 @@ class ExpressionContext implements Cloneable {
final ExpressionContext expressionContext = new ExpressionContext(project, usedVarNames);
expressionContext.myProps.putAll(myProps);
expressionContext.analyzedVars = analyzedVars;
expressionContext.typeProvider = typeProvider;
return expressionContext;
}
@@ -16,7 +16,6 @@
package org.jetbrains.plugins.groovy.refactoring.convertToJava;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightElement;
@@ -82,8 +81,11 @@ public class ExpressionGenerator extends Generator {
factory = GroovyPsiElementFactory.getInstance(context.project);
}
public ExpressionGenerator(Project project) {
this(new StringBuilder(), new ExpressionContext(project));
public ExpressionGenerator(ExpressionContext context) {
this.builder = new StringBuilder();
this.context = context;
factory = GroovyPsiElementFactory.getInstance(context.project);
}
@Override
@@ -289,10 +289,15 @@ public class GenerationUtil {
if (!classNameProvider.forStubs()) {
ModifierListGenerator.writeModifiers(text, parameter.getModifierList(), ModifierListGenerator.JAVA_MODIFIERS, true);
}
if (context != null && context.analyzedVars.toMakeFinal(parameter)) {
text.append(PsiModifier.FINAL).append(' ');
if (context != null) {
if (context.analyzedVars.toMakeFinal(parameter)) {
text.append(PsiModifier.FINAL).append(' ');
}
writeType(text, context.typeProvider.getParameterType(parameter), parameter, classNameProvider);
}
else {
writeType(text, parameter.getType(), parameter, classNameProvider);
}
writeType(text, TypeProvider.getParameterType(parameter), parameter, classNameProvider);
text.append(" ");
text.append(parameter.getName());
@@ -425,7 +430,7 @@ public class GenerationUtil {
}
static void writeVariableSeparately(GrVariable variable, StringBuilder builder, ExpressionContext expressionContext) {
PsiType type = TypeProvider.getVarType(variable);
PsiType type = expressionContext.typeProvider.getVarType(variable);
ModifierListGenerator.writeModifiers(builder, variable.getModifierList());
PsiType originalType = type;
@@ -83,7 +83,7 @@ public class ModifierListGenerator {
if (writeAnnotations && modifierList instanceof GrModifierList) {
GrAnnotation[] annotations = ((GrModifierList)modifierList).getAnnotations();
AnnotationGenerator annotationGenerator = new AnnotationGenerator(builder, modifierList.getProject());
AnnotationGenerator annotationGenerator = new AnnotationGenerator(builder, new ExpressionContext(modifierList.getProject()));
wasAddedModifiers = annotations.length > 0;
for (GrAnnotation annotation : annotations) {
annotation.accept(annotationGenerator);
@@ -40,6 +40,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrCo
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import java.util.*;
@@ -97,7 +98,7 @@ public class StubGenerator implements ClassItemGenerator {
for (int j = 0; j < superParams.length; j++) {
if (j > 0) text.append(", ");
text.append("(");
final PsiType type = TypeProvider.getParameterType(superParams[j]);
final PsiType type = superParams[j].getType();
writeType(text, substitutor.substitute(type), invocation, classNameProvider);
text.append(")").append(GroovyToJavaGenerator.getDefaultValueText(type.getCanonicalText()));
}
@@ -185,7 +186,10 @@ public class StubGenerator implements ClassItemGenerator {
}
//append return type
PsiType retType = TypeProvider.getReturnType(method, true);
PsiType retType = method.getReturnType();
if (retType == null) {
retType = TypesUtil.getJavaLangObject(method);
}
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
final List<MethodSignatureBackedByPsiMethod> superSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
@@ -320,7 +324,7 @@ public class StubGenerator implements ClassItemGenerator {
final LightMethodBuilder builder = new LightMethodBuilder(method.getManager(), method.getName());
substitutor = substitutor.putAll(TypeConversionUtil.getSuperClassSubstitutor(baseClass, typeDefinition, PsiSubstitutor.EMPTY));
for (PsiParameter parameter : method.getParameterList().getParameters()) {
builder.addParameter(StringUtil.notNullize(parameter.getName()), substitutor.substitute(TypeProvider.getParameterType(parameter)));
builder.addParameter(StringUtil.notNullize(parameter.getName()), substitutor.substitute(parameter.getType()));
}
builder.setReturnType(substitutor.substitute(method.getReturnType()));
for (String modifier : STUB_MODIFIERS) {
@@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
@@ -30,23 +29,11 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
* @author Medvedev Max
*/
public class TypeProvider {
private TypeProvider() {
public TypeProvider() {
}
@NotNull
public static PsiType getReturnType(PsiMethod method) {
return getReturnType(method, false);
}
@NotNull
public static PsiType getReturnType(PsiMethod method, boolean forStubs) {
if (forStubs) {
PsiType returnType = method.getReturnType();
if (returnType != null) return returnType;
return TypesUtil.getJavaLangObject(method);
}
public PsiType getReturnType(PsiMethod method) {
if (method instanceof GrMethod) {
GrTypeElement typeElement = ((GrMethod)method).getReturnTypeElementGroovy();
if (typeElement != null) return typeElement.getType();
@@ -59,7 +46,7 @@ public class TypeProvider {
}
@NotNull
public static PsiType getVarType(GrVariable variable) {
public PsiType getVarType(GrVariable variable) {
PsiType type = variable.getDeclaredType();
if (type == null) {
type = variable.getTypeGroovy();
@@ -71,7 +58,9 @@ public class TypeProvider {
}
@NotNull
public static PsiType getParameterType(PsiParameter parameter) {
public PsiType getParameterType(PsiParameter parameter) {
return parameter.getType(); //todo make smarter
}
}