diff --git a/java/openapi/src/com/intellij/psi/JavaPsiFacade.java b/java/openapi/src/com/intellij/psi/JavaPsiFacade.java
index 75f11b58d01d..61fdd8bfd26a 100644
--- a/java/openapi/src/com/intellij/psi/JavaPsiFacade.java
+++ b/java/openapi/src/com/intellij/psi/JavaPsiFacade.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -175,7 +175,8 @@ public abstract class JavaPsiFacade {
*/
public abstract boolean isPartOfPackagePrefix(String packageName);
- /* Checks if the specified PSI element belongs to the specified package.
+ /**
+ * Checks if the specified PSI element belongs to the specified package.
*
* @param element the element to check the package for.
* @param aPackage the package to check.
diff --git a/java/openapi/src/com/intellij/psi/codeStyle/JavaCodeStyleManager.java b/java/openapi/src/com/intellij/psi/codeStyle/JavaCodeStyleManager.java
index 712e64f30ebd..236eb7539a3a 100644
--- a/java/openapi/src/com/intellij/psi/codeStyle/JavaCodeStyleManager.java
+++ b/java/openapi/src/com/intellij/psi/codeStyle/JavaCodeStyleManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -116,7 +116,7 @@ public abstract class JavaCodeStyleManager {
*
* @param name the name of the variable.
* @param variableKind the kind of the variable.
- * @return the stipped-down name.
+ * @return the stripped-down name.
*/
public abstract String variableNameToPropertyName(@NonNls String name, VariableKind variableKind);
@@ -146,7 +146,7 @@ public abstract class JavaCodeStyleManager {
* @param baseNameInfo the base name info for the variable.
* @param place the location where the variable will be used.
* @param lookForward if true, the existing variables are searched in both directions; if false - only backward
- * @return the generated unique name,
+ * @return the generated unique name
*/
@NotNull
public SuggestedNameInfo suggestUniqueVariableName(@NotNull SuggestedNameInfo baseNameInfo,
@@ -163,6 +163,7 @@ public abstract class JavaCodeStyleManager {
* @param place the location where the variable will be used.
* @param ignorePlaceName if true and place is PsiNamedElement, place.getName() would be still treated as unique name
* @param lookForward if true, the existing variables are searched in both directions; if false - only backward @return the generated unique name,
+ * @return the generated unique name
*/
@NotNull public abstract SuggestedNameInfo suggestUniqueVariableName(@NotNull SuggestedNameInfo baseNameInfo,
PsiElement place,
diff --git a/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java b/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java
index 2d86919346a4..7435213e577b 100644
--- a/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java
+++ b/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,12 +29,16 @@ public interface JavadocTagInfo {
@NonNls String getName();
boolean isInline();
+
boolean isValidInContext(PsiElement element);
Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix);
/**
- * Checks the tag value for correctnes. Returns null if correct. Error message otherwise.
+ * Checks the tag value for correctness.
+ *
+ * @param value Doc tag to check.
+ * @return Returns null if correct, error message otherwise.
*/
@Nullable
String checkTagValue(PsiDocTagValue value);
diff --git a/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java b/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java
index 4e54b98a5ffb..8e2656131128 100644
--- a/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/components/PersistentStateComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2011 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,8 @@ import com.intellij.util.xmlb.XmlSerializer;
* Every component which would like to persist its state across IDEA restarts
* should implement this interface.
*
- * todo: describe registration procedures
+ * See JetBrains WIKI
+ * for detailed description.
*/
public interface PersistentStateComponent {
/**
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java
index 0b366bc3cc88..9d1dc4bfd5e8 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMapType.java
@@ -24,10 +24,15 @@ import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import java.util.*;
+import java.util.HashSet;
/**
* @author peter
@@ -67,6 +72,31 @@ public class GrMapType extends GrLiteralClassType {
facade.findClass(JAVA_UTIL_LINKED_HASH_MAP, scope) != null ? JAVA_UTIL_LINKED_HASH_MAP : CommonClassNames.JAVA_UTIL_MAP;
}
+ public GrMapType(JavaPsiFacade facade, GlobalSearchScope scope, GrNamedArgument[] args) {
+ super(LanguageLevel.JDK_1_5, scope, facade);
+
+ myJavaClassName =
+ facade.findClass(JAVA_UTIL_LINKED_HASH_MAP, scope) != null ? JAVA_UTIL_LINKED_HASH_MAP : CommonClassNames.JAVA_UTIL_MAP;
+
+ myStringEntries = new HashMap();
+ myOtherEntries=new ArrayList>();
+
+ for (GrNamedArgument arg : args) {
+ GrArgumentLabel label = arg.getLabel();
+ if (label == null) continue;
+ GrExpression expression = arg.getExpression();
+ if (expression == null || expression.getType() == null) continue;
+
+ if (label.getName() != null) {
+ myStringEntries.put(label.getName(), expression.getType());
+ }
+ else if (label.getExpression() != null) {
+ PsiType type = label.getExpression().getType();
+ myOtherEntries.add(new Pair(type, expression.getType()));
+ }
+ }
+ }
+
@NotNull
@Override
public PsiClassType rawType() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java
index e2e8662af8b9..a31c2767ed0d 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java
@@ -364,8 +364,6 @@ public class TypesUtil {
public static PsiType getLeastUpperBoundNullable(@Nullable PsiType type1, @Nullable PsiType type2, PsiManager manager) {
if (type1 == null) return type2;
if (type2 == null) return type1;
- if (type1.isAssignableFrom(type2)) return type1;
- if (type2.isAssignableFrom(type1)) return type2;
return getLeastUpperBound(type1, type2, manager);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java
index 3edd4b55a4f4..ce36af40c433 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.types;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureUtil;
@@ -41,6 +42,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCurriedClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
+import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
@@ -645,4 +647,56 @@ public class GrClosureSignatureUtil {
@NotNull GrClosureSignature signature) {
return generateAllMethodSignaturesByClosureSignature(name, signature, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
}
+
+ @Nullable
+ public static PsiType getTypeByTypeArg(ArgInfo arg, PsiManager manager, GlobalSearchScope resolveScope) {
+ if (arg.isMultiArg) {
+ if (arg.args.size() == 0) return PsiType.getJavaLangObject(manager, resolveScope).createArrayType();
+ PsiType leastUpperBound = null;
+
+ for (PsiType type : arg.args) {
+ leastUpperBound = TypesUtil.getLeastUpperBoundNullable(leastUpperBound, type, manager);
+ }
+ if (leastUpperBound == null) return null;
+ return leastUpperBound.createArrayType();
+ }
+ else {
+ if (arg.args.size() > 0) return arg.args.get(0);
+ return null;
+ }
+ }
+
+ @Nullable
+ public static PsiType getTypeByArg(ArgInfo arg, PsiManager manager, GlobalSearchScope resolveScope) {
+ if (arg.isMultiArg) {
+ if (arg.args.size() == 0) return PsiType.getJavaLangObject(manager, resolveScope).createArrayType();
+ PsiType leastUpperBound = null;
+ PsiElement first = arg.args.get(0);
+ if (first instanceof GrNamedArgument) {
+ GrNamedArgument[] args=new GrNamedArgument[arg.args.size()];
+ for (int i = 0, size = arg.args.size(); i < size; i++) {
+ args[i] = (GrNamedArgument)arg.args.get(i);
+ }
+ return new GrMapType(JavaPsiFacade.getInstance(manager.getProject()), resolveScope, args);
+ }
+ else {
+ for (PsiElement elem : arg.args) {
+ if (elem instanceof GrExpression) {
+ leastUpperBound = TypesUtil.getLeastUpperBoundNullable(leastUpperBound, ((GrExpression)elem).getType(), manager);
+ }
+ }
+ if (leastUpperBound == null) return null;
+ return leastUpperBound.createArrayType();
+ }
+ }
+ else {
+ if (arg.args.size() == 0) return null;
+ PsiElement elem = arg.args.get(0);
+ if (elem instanceof GrExpression) {
+ return ((GrExpression)elem).getType();
+ }
+ return null;
+ }
+ }
+
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnnotationGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnnotationGenerator.java
index 0bbbed408b9d..c3e4dc4e74bd 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnnotationGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnnotationGenerator.java
@@ -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);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java
index a080c47e4260..9314c88f6eb9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/AnonymousFromMapGenerator.java
@@ -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();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java
index 3da9d806a7b2..ee6a88305a62 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassGenerator.java
@@ -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 = psiMethod.getReturnType();
+ if (type != null && superType != null && !superType.isAssignableFrom(type)) {
return false;
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
index 307b32f2a019..2f2c343e0b51 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ClassItemGeneratorImpl.java
@@ -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());
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java
index ec00a8787943..6bcb3aee7aea 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java
@@ -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;");
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java
index 0a6c86c9e329..8ebe7347b37a 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java
@@ -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 myStatements = new ArrayList();
Set myUsedVarNames;
LocalVarAnalyzer.Result analyzedVars = LocalVarAnalyzer.initialResult();
+ TypeProvider typeProvider;
Project project;
private Map myProps = new HashMap();
private static final String myShouldInsertCurlyBrackets = "shouldInsertCurly";
private static final String myInAnonymousContext = "inAnonymousContext";
- ExpressionContext(Project project, Set usedVarNames) {
+ private ExpressionContext(Project project, Set usedVarNames) {
this.project = project;
myUsedVarNames = usedVarNames;
}
ExpressionContext(Project project) {
this(project, new HashSet());
+ 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;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java
index 6d09a6d5ad59..262352fd4390 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java
@@ -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
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
index 335b3db02152..a7bc173522fa 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java
@@ -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;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java
index f324e11de872..b387ebb03f78 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ModifierListGenerator.java
@@ -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);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
index 44bd0dabf4b5..d13d56a72ddf 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StubGenerator.java
@@ -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 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) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java
index 24879e233640..19fbe1d225d3 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/TypeProvider.java
@@ -15,38 +15,39 @@
*/
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 com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.searches.MethodReferencesSearch;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.HashMap;
+import gnu.trove.TIntArrayList;
+import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
+import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
+import java.util.Map;
+
/**
* @author Medvedev Max
*/
public class TypeProvider {
+ private final Map inferredTypes = new HashMap();
- 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 +60,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 +72,77 @@ public class TypeProvider {
}
@NotNull
- public static PsiType getParameterType(PsiParameter parameter) {
- return parameter.getType(); //todo make smarter
+ public PsiType getParameterType(PsiParameter parameter) {
+ if (!(parameter instanceof GrParameter)) {
+ return parameter.getType();
+ }
+ /*GrTypeElement typeElementGroovy = ((GrParameter)parameter).getTypeElementGroovy();
+ if (typeElementGroovy != null) {
+ return parameter.getType();
+ }*/
+
+ PsiElement parent = parameter.getParent();
+ if (!(parent instanceof GrParameterList)) return parameter.getType();
+
+ PsiElement pparent = parent.getParent();
+ if (!(pparent instanceof GrMethod)) return parameter.getType();
+
+ PsiType[] types = inferMethodParameters((GrMethod)pparent);
+ return types[((GrParameterList)parent).getParameterNumber((GrParameter)parameter)];
+ }
+
+ private PsiType[] inferMethodParameters(GrMethod method) {
+ PsiType[] psiTypes = inferredTypes.get(method);
+ if (psiTypes != null) return psiTypes;
+
+ final GrParameter[] parameters = method.getParameters();
+
+ final TIntArrayList paramInds = new TIntArrayList(parameters.length);
+ final PsiType[] types = new PsiType[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ if (parameters[i].getTypeElementGroovy() == null) {
+ paramInds.add(i);
+ } else {
+ types[i] = parameters[i].getType();
+ }
+ }
+
+ if (paramInds.size() > 0) {
+ final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY);
+ MethodReferencesSearch.search(method, true).forEach(new Processor() {
+ @Override
+ public boolean process(PsiReference psiReference) {
+ final PsiElement element = psiReference.getElement();
+ final PsiManager manager = element.getManager();
+ final GlobalSearchScope resolveScope = element.getResolveScope();
+
+ if (element instanceof GrReferenceExpression) {
+ final GrCall call = (GrCall)element.getParent();
+ final GrClosureSignatureUtil.ArgInfo[] argInfos = GrClosureSignatureUtil
+ .mapParametersToArguments(signature, call.getArgumentList(), ((GrReferenceExpression)element), call.getClosureArguments());
+
+ if (argInfos == null) return true;
+ paramInds.forEach(new TIntProcedure() {
+ @Override
+ public boolean execute(int i) {
+ PsiType type = GrClosureSignatureUtil.getTypeByArg(argInfos[i], manager, resolveScope);
+ types[i] = TypesUtil.getLeastUpperBoundNullable(type, types[i], manager);
+ return true;
+ }
+ });
+ }
+ return true;
+ }
+ });
+ }
+ paramInds.forEach(new TIntProcedure() {
+ @Override
+ public boolean execute(int i) {
+ if (types[i]==null) types[i] = parameters[i].getType();
+ return true;
+ }
+ });
+ inferredTypes.put(method, types);
+ return types;
}
}
diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/concurency.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/concurency.java
index 398d6e05b5d9..c5ef7999ca54 100644
--- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/concurency.java
+++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/concurency.java
@@ -32,7 +32,7 @@ return null;
}
-public synchronized void out(java.lang.Object message) {
+public synchronized void out(groovy.lang.GString message) {
println(message);
}