Merge remote branch 'origin/master'

This commit is contained in:
Alex Tkachman
2011-12-29 17:53:20 +02:00
40 changed files with 344 additions and 136 deletions
+1
View File
@@ -12,6 +12,7 @@
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" />
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" />
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
<module fileurl="file://$PROJECT_DIR$/testlib/testlib.iml" filepath="$PROJECT_DIR$/testlib/testlib.iml" />
</modules>
</component>
</project>
+5 -2
View File
@@ -1,4 +1,4 @@
<project name="Jet CI Bootstrap" default="unzipIdeaSDK">
<project name="Jet CI Bootstrap" default="unzipDependencies">
<macrodef name="echoprop">
<attribute name="prop"/>
<sequential>
@@ -16,9 +16,12 @@
<echoprop prop="user.home"/>
<echoprop prop="user.dir"/>
<target name="unzipIdeaSDK">
<target name="unzipDependencies">
<unzip dest="ideaSDK">
<fileset dir="ideaSDK" includes="ideaIC*.zip"/>
</unzip>
<unzip dest="bootstrap.compiler">
<fileset dir="bootstrap.compiler" includes="kotlin*.zip"/>
</unzip>
</target>
</project>
+5 -6
View File
@@ -72,12 +72,11 @@
<target name="dist" depends="clean,jarRT,jar">
<zip destfile="${output}/${output.name}.zip">
<zipfileset prefix="${output.name}/bin" filemode="755" dir="${basedir}/compiler/cli/bin"/>
<zipfileset prefix="${output.name}/lib" dir="${basedir}/ideaSDK"/>
<zipfileset prefix="${output.name}/lib" dir="${basedir}/lib"/>
<zipfileset prefix="${output.name}/lib" dir="${output}" includes="*.jar"/>
<zipfileset prefix="${output.name}/examples" dir="${basedir}/examples/src"/>
<zipfileset prefix="kotlinc/bin" filemode="755" dir="${basedir}/compiler/cli/bin"/>
<zipfileset prefix="kotlinc/lib" dir="${basedir}/ideaSDK"/>
<zipfileset prefix="kotlinc/lib" dir="${basedir}/lib"/>
<zipfileset prefix="kotlinc/lib" dir="${output}" includes="*.jar"/>
<zipfileset prefix="kotlinc/examples" dir="${basedir}/examples/src"/>
</zip>
</target>
</project>
@@ -83,6 +83,9 @@ public interface Errors {
SimpleDiagnosticFactory LABEL_NAME_CLASH = SimpleDiagnosticFactory.create(WARNING, "There is more than one label with such a name in this scope");
SimpleDiagnosticFactory EXPRESSION_EXPECTED_NAMESPACE_FOUND = SimpleDiagnosticFactory.create(ERROR, "Expression expected, but a namespace name found");
SimpleDiagnosticFactory CANNOT_IMPORT_OBJECT_MEMBERS = SimpleDiagnosticFactory.create(ERROR, "Cannot import members of object separately, use full paths or try to move members to namespace level");
SimpleDiagnosticFactory CANNOT_IMPORT_VARIABLE_MEMBERS = SimpleDiagnosticFactory.create(ERROR, "Cannot import members of variable separately, use full paths");
SimpleDiagnosticFactory CANNOT_INFER_PARAMETER_TYPE = SimpleDiagnosticFactory.create(ERROR, "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation");
SimpleDiagnosticFactory NO_BACKING_FIELD_ABSTRACT_PROPERTY = SimpleDiagnosticFactory.create(ERROR, "This property doesn't have a backing field, because it's abstract");
@@ -53,12 +53,15 @@ public class ImportsResolver {
}
public static class ImportResolver {
private BindingTrace trace;
private boolean firstPhase;
private final BindingTrace trace;
private final boolean firstPhase;
// flag is used not to invoke code that resolves members from objects and variables; functionality is under discuss so far, see KT-876
private final boolean importMembersFromObjectsAndVars;
public ImportResolver(BindingTrace trace, boolean firstPhase) {
this.trace = trace;
this.firstPhase = firstPhase;
this.importMembersFromObjectsAndVars = false;
}
public void processImportReference(JetImportDirective importDirective, WritableScope namespaceScope, JetScope outerScope) {
@@ -77,6 +80,7 @@ public class ImportsResolver {
JetScope scope = importDirective.isAllUnder() ? namespaceScope : outerScope;
descriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) importedReference, scope);
}
JetSimpleNameExpression referenceExpression = getLastReference(importedReference);
if (importDirective.isAllUnder()) {
for (DeclarationDescriptor descriptor : descriptors) {
if (firstPhase) {
@@ -85,18 +89,25 @@ public class ImportsResolver {
}
}
else if (descriptor instanceof VariableDescriptor) {
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_OBJECT_MEMBERS.on(referenceExpression != null ? referenceExpression : importedReference));
continue;
}
JetType type = ((VariableDescriptor) descriptor).getOutType();
if (type != null) {
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, type.getMemberScope()));
}
}
else if (descriptor instanceof ClassDescriptor) {
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_VARIABLE_MEMBERS.on(referenceExpression != null ? referenceExpression : importedReference));
continue;
}
namespaceScope.importScope(ScopeBoundToReceiver.create(descriptor, ((ClassDescriptor) descriptor).getDefaultType().getMemberScope()));
}
}
return;
}
JetSimpleNameExpression referenceExpression = getLastReference(importedReference);
String aliasName = importDirective.getAliasName();
if (aliasName == null) {
@@ -149,10 +160,10 @@ public class ImportsResolver {
assert receiverExpression instanceof JetSimpleNameExpression;
declarationDescriptors = lookupDescriptorsForSimpleNameReference((JetSimpleNameExpression) receiverExpression, outerScope);
}
JetExpression selectorExpression = importedReference.getSelectorExpression();
assert selectorExpression instanceof JetSimpleNameExpression;
JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression;
for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
JetExpression selectorExpression = importedReference.getSelectorExpression();
assert selectorExpression instanceof JetSimpleNameExpression;
JetSimpleNameExpression selector = (JetSimpleNameExpression) selectorExpression;
if (declarationDescriptor instanceof NamespaceDescriptor) {
return lookupDescriptorsForSimpleNameReference(selector, ((NamespaceDescriptor) declarationDescriptor).getMemberScope());
}
@@ -177,7 +188,12 @@ public class ImportsResolver {
trace.report(NO_CLASS_OBJECT.on(classReference, classDescriptor));
return Collections.emptyList();
}
return addBoundToReceiver(lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope()), classDescriptor);
Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, classObjectType.getMemberScope());
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_OBJECT_MEMBERS.on(memberReference));
return Collections.emptyList();
}
return addBoundToReceiver(members, classDescriptor);
}
@NotNull
@@ -186,7 +202,12 @@ public class ImportsResolver {
JetType variableType = variableDescriptor.getReturnType();
if (variableType == null) return Collections.emptyList();
return addBoundToReceiver(lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope()), variableDescriptor);
Collection<DeclarationDescriptor> members = lookupDescriptorsForSimpleNameReference(memberReference, variableType.getMemberScope());
if (!importMembersFromObjectsAndVars) {
trace.report(CANNOT_IMPORT_VARIABLE_MEMBERS.on(memberReference));
return Collections.emptyList();
}
return addBoundToReceiver(members, variableDescriptor);
}
@NotNull
@@ -5,22 +5,23 @@ import b.B //class
import b.foo //function
import b.ext //extension function
import b.value //property
import b.C.bar //function from class object
import b.C.cValue //property from class object
import b.constant.fff //function from val
import b.constant.dValue //property from val
import b.E.f //val from class object
import b.C.<!CANNOT_IMPORT_OBJECT_MEMBERS!>bar<!> //function from class object
import b.C.<!CANNOT_IMPORT_OBJECT_MEMBERS!>cValue<!> //property from class object
import b.constant.<!CANNOT_IMPORT_VARIABLE_MEMBERS!>fff<!> //function from val
import b.constant.<!CANNOT_IMPORT_VARIABLE_MEMBERS!>dValue<!> //property from val
import b.E.<!CANNOT_IMPORT_OBJECT_MEMBERS!>f<!> //val from class object
import <!UNRESOLVED_REFERENCE!>smth<!>.illegal
fun test(arg: B) {
foo(value)
arg.ext()
bar()
foo(cValue)
<!UNRESOLVED_REFERENCE!>bar<!>()
foo(<!UNRESOLVED_REFERENCE!>cValue<!>)
fff(dValue)
<!UNRESOLVED_REFERENCE!>fff<!>(<!UNRESOLVED_REFERENCE!>dValue<!>)
f.f()
<!UNRESOLVED_REFERENCE!>f<!>.f()
}
// FILE:b.kt
@@ -61,14 +62,14 @@ class F() {
//FILE:c.kt
package c
import C.*
import <!CANNOT_IMPORT_OBJECT_MEMBERS!>C<!>.*
object C {
fun a() {
fun f() {
}
val b = 3
val i = 3
}
fun foo() {
if (b == 3) a()
if (<!UNRESOLVED_REFERENCE!>i<!> == 3) <!UNRESOLVED_REFERENCE!>f<!>()
}
@@ -4,14 +4,12 @@ import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.DeferredType;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.*;
import java.util.LinkedList;
@@ -41,7 +39,7 @@ public class JetPluginUtil {
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
LinkedList<String> fullName = Lists.newLinkedList();
while (declarationDescriptor != null) {
while (declarationDescriptor != null && !(declarationDescriptor instanceof ModuleDescriptor)) {
fullName.addFirst(declarationDescriptor.getName());
declarationDescriptor = declarationDescriptor.getContainingDeclaration();
}
@@ -53,6 +51,11 @@ public class JetPluginUtil {
}
public static boolean checkTypeIsStandard(JetType type, Project project) {
if (JetStandardClasses.isAny(type) || JetStandardClasses.isNothingOrNullableNothing(type) || JetStandardClasses.isUnit(type) ||
JetStandardClasses.isTupleType(type) || JetStandardClasses.isFunctionType(type)) {
return true;
}
LinkedList<String> fullName = computeTypeFullNameList(type);
if (fullName.size() == 3 && fullName.getFirst().equals("java") && fullName.get(1).equals("lang")) {
return true;
@@ -13,8 +13,10 @@ import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.plugin.quickfix.ImportClassHelper;
import javax.swing.*;
@@ -138,9 +140,11 @@ public class JetAddImportAction implements QuestionAction {
public void run() {
// TODO: See {@link com.intellij.codeInsight.daemon.impl.actions.AddImportAction#_addImport} for more ideas.
// TODO: Optimize imports
PsiFile file = element.getContainingFile();
if (!(file instanceof JetFile)) return;
ImportClassHelper.addImportDirective(
selectedImport,
ImportClassHelper.findOuterNamespace(element)
(JetFile)file
);
}
});
@@ -3,18 +3,17 @@ package org.jetbrains.jet.plugin.completion;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.CommentUtil;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.filters.AndFilter;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.NotFilter;
import com.intellij.psi.filters.TextFilter;
import com.intellij.psi.filters.*;
import com.intellij.psi.filters.position.FilterPattern;
import com.intellij.psi.filters.position.LeftNeighbour;
import com.intellij.psi.filters.position.PositionElementFilter;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
@@ -35,12 +34,51 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private final static InsertHandler<LookupElement> KEYWORDS_INSERT_HANDLER = new JetKeywordInsertHandler();
private final static InsertHandler<LookupElement> FUNCTION_INSERT_HANDLER = new JetFunctionInsertHandler(
JetFunctionInsertHandler.CaretPosition.AFTER_BRACKETS);
private final static ElementFilter GENERAL_FILTER = new NotFilter(new OrFilter(
new CommentFilter(), // or
new ParentFilter(new ClassFilter(JetLiteralStringTemplateEntry.class)), // or
new ParentFilter(new ClassFilter(JetConstantExpression.class)), // or
new LeftNeighbour(new TextFilter("."))
));
private final static List<String> FUNCTION_KEYWORDS = Lists.newArrayList("get", "set");
private static class CommentFilter implements ElementFilter {
@Override
public boolean isAcceptable(Object element, PsiElement context) {
if (!(element instanceof PsiElement)) {
return false;
}
return CommentUtil.isComment((PsiElement) element);
}
@Override
public boolean isClassAcceptable(Class hintClass) {
return true;
}
}
private static class ParentFilter extends PositionElementFilter {
public ParentFilter(ElementFilter filter) {
setFilter(filter);
}
@Override
public boolean isAcceptable(Object element, PsiElement context) {
if (!(element instanceof PsiElement)) {
return false;
}
PsiElement parent = ((PsiElement) element).getParent();
return parent != null && getFilter().isAcceptable(parent, context);
}
}
private static class InTopFilter implements ElementFilter {
@Override
public boolean isAcceptable(Object element, PsiElement context) {
//noinspection unchecked
return PsiTreeUtil.getParentOfType(context, JetFile.class, false, JetClass.class, JetFunction.class) != null;
}
@@ -53,8 +91,8 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private static class InNonClassBlockFilter implements ElementFilter {
@Override
public boolean isAcceptable(Object element, PsiElement context) {
return PsiTreeUtil.getParentOfType(context, JetFunction.class, true, JetClass.class) != null &&
PsiTreeUtil.getParentOfType(context, JetBlockExpression.class, true, JetFunction.class) != null;
//noinspection unchecked
return PsiTreeUtil.getParentOfType(context, JetBlockExpression.class, true, JetClassBody.class) != null;
}
@Override
@@ -78,7 +116,8 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private static class InClassBodyFilter implements ElementFilter {
@Override
public boolean isAcceptable(Object element, PsiElement context) {
return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true, JetFunction.class) != null;
//noinspection unchecked
return PsiTreeUtil.getParentOfType(context, JetClassBody.class, true, JetBlockExpression.class) != null;
}
@Override
@@ -126,8 +165,6 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
}
}
public JetKeywordCompletionContributor() {
registerScopeKeywordsCompletion(new InTopFilter(),
"abstract", "class", "enum", "final", "fun", "get", "import", "inline",
@@ -135,8 +172,8 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
"trait", "type", "val", "var");
registerScopeKeywordsCompletion(new InClassBodyFilter(),
"abstract", "class", "enum", "final", "fun", "inline", "internal", "get",
"open", "override", "private", "protected", "public", "set", "trait",
"abstract", "class", "enum", "final", "fun", "get", "inline", "internal",
"object", "open", "override", "private", "protected", "public", "set", "trait",
"type", "val", "var");
registerScopeKeywordsCompletion(new InNonClassBlockFilter(),
@@ -157,6 +194,6 @@ public class JetKeywordCompletionContributor extends CompletionContributor {
private static ElementPattern<PsiElement> getPlacePattern(final ElementFilter placeFilter) {
return PlatformPatterns.psiElement().and(
new FilterPattern(new AndFilter(new NotFilter(new LeftNeighbour(new TextFilter("."))), placeFilter)));
new FilterPattern(new AndFilter(GENERAL_FILTER, placeFilter)));
}
}
@@ -11,6 +11,8 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticParameters;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.JetBundle;
@@ -37,8 +39,14 @@ public class AddReturnTypeFix extends JetIntentionAction<JetNamedDeclaration> {
return JetBundle.message("add.return.type");
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return super.isAvailable(project, editor, file) && !ErrorUtils.isErrorType(type);
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!(file instanceof JetFile)) return;
PsiElement newElement;
if (element instanceof JetProperty) {
newElement = addPropertyType(project, (JetProperty) element, type);
@@ -47,7 +55,8 @@ public class AddReturnTypeFix extends JetIntentionAction<JetNamedDeclaration> {
assert element instanceof JetFunction;
newElement = addFunctionType(project, (JetFunction) element, type);
}
ImportClassHelper.perform(type, element, newElement);
ImportClassHelper.addImportDirectiveIfNeeded(type, (JetFile)file);
element.replace(newElement);
}
@Override
@@ -10,10 +10,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.diagnostics.DiagnosticParameters;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters;
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.JetBundle;
@@ -57,7 +54,7 @@ public class ChangeAccessorTypeFix extends JetIntentionAction<JetPropertyAccesso
assert typeReference != null;
CodeEditUtil.replaceChild(parameter.getNode(), typeReference.getNode(), newTypeReference.getNode());
}
ImportClassHelper.perform(type, element, newElement);
element.replace(newElement);
}
public static JetIntentionActionFactory<JetPropertyAccessor> createFactory() {
@@ -80,21 +80,9 @@ public class ChangeVariableMutabilityFix implements IntentionAction {
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
JetProperty property = getCorrespondingProperty(editor, (JetFile)file);
assert property != null && !property.isVar();
JetProperty newElement = (JetProperty) property.copy();
if (newElement.isVar()) {
PsiElement varElement = newElement.getNode().findChildByType(JetTokens.VAR_KEYWORD).getPsi();
JetProperty valProperty = JetPsiFactory.createProperty(project, "x", "Any", false);
PsiElement valElement = valProperty.getNode().findChildByType(JetTokens.VAL_KEYWORD).getPsi();
CodeEditUtil.replaceChild(newElement.getNode(), varElement.getNode(), valElement.getNode());
}
else {
PsiElement valElement = newElement.getNode().findChildByType(JetTokens.VAL_KEYWORD).getPsi();
JetProperty varProperty = JetPsiFactory.createProperty(project, "x", "Any", true);
PsiElement varElement = varProperty.getNode().findChildByType(JetTokens.VAR_KEYWORD).getPsi();
CodeEditUtil.replaceChild(newElement.getNode(), valElement.getNode(), varElement.getNode());
}
JetProperty newElement = JetPsiFactory.createProperty(project, property.getText().replaceFirst(
property.isVar() ? "var" : "val", property.isVar() ? "val" : "var"));
property.replace(newElement);
}
@@ -2,11 +2,12 @@ package org.jetbrains.jet.plugin.quickfix;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.JetPluginUtil;
@@ -17,48 +18,34 @@ import java.util.List;
* @author svtk
*/
public class ImportClassHelper {
public static void perform(@NotNull JetType type, @NotNull PsiElement elementToReplace, @NotNull PsiElement newElement) {
if (JetPluginUtil.checkTypeIsStandard(type, elementToReplace.getProject()) || ErrorUtils.isError(type.getMemberScope().getContainingDeclaration())) {
elementToReplace.replace(newElement);
/**
* Add import directive corresponding to a type to file when it is needed.
*
* @param type type to import
* @param file file where import directive should be added
*/
public static void addImportDirectiveIfNeeded(@NotNull JetType type, @NotNull JetFile file) {
if (JetPluginUtil.checkTypeIsStandard(type, file.getProject()) || ErrorUtils.isErrorType(type)) {
return;
}
perform(JetPluginUtil.computeTypeFullName(type), elementToReplace, newElement);
}
public static void perform(@NotNull String typeFullName, @NotNull JetFile namespace) {
perform(typeFullName, namespace, null, null);
}
/**
* Get the outer namespace PSI element for given element in the tree.
*
* @param element Some element in the tree.
* @return A namespace element in the tree.
*/
public static JetFile findOuterNamespace(@NotNull PsiElement element) {
PsiElement parent = element;
while (!(parent instanceof JetFile)) {
parent = parent.getParent();
assert parent != null;
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(file, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
PsiElement element = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, type.getMemberScope().getContainingDeclaration());
if (element != null && element.getContainingFile() == file) { //declaration is in the same file, so no import is needed
return;
}
return (JetFile) parent;
}
public static void perform(@NotNull String typeFullName, @NotNull PsiElement elementToReplace, @NotNull PsiElement newElement) {
perform(typeFullName, findOuterNamespace(elementToReplace), elementToReplace, newElement);
addImportDirective(JetPluginUtil.computeTypeFullName(type), file);
}
/**
* Add import directive into the PSI tree for the given namespace.
*
* @param importString full name of the import. Can contain .* if necessary.
* @param namespace Namespace where directive should be added.
* @param file File where directive should be added.
*/
public static void addImportDirective(@NotNull String importString, @NotNull JetFile namespace) {
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
public static void addImportDirective(@NotNull String importString, @NotNull JetFile file) {
List<JetImportDirective> importDirectives = file.getImportDirectives();
JetImportDirective newDirective = JetPsiFactory.createImportDirective(namespace.getProject(), importString);
JetImportDirective newDirective = JetPsiFactory.createImportDirective(file.getProject(), importString);
String lineSeparator = System.getProperty("line.separator");
if (!importDirectives.isEmpty()) {
@@ -72,22 +59,14 @@ public class ImportClassHelper {
JetImportDirective lastDirective = importDirectives.get(importDirectives.size() - 1);
lastDirective.getParent().addAfter(newDirective, lastDirective);
lastDirective.getParent().addAfter(JetPsiFactory.createWhiteSpace(namespace.getProject(), lineSeparator), lastDirective);
lastDirective.getParent().addAfter(JetPsiFactory.createWhiteSpace(file.getProject(), lineSeparator), lastDirective);
}
else {
List<JetDeclaration> declarations = namespace.getDeclarations();
List<JetDeclaration> declarations = file.getDeclarations();
assert !declarations.isEmpty();
JetDeclaration firstDeclaration = declarations.iterator().next();
firstDeclaration.getParent().addBefore(newDirective, firstDeclaration);
firstDeclaration.getParent().addBefore(JetPsiFactory.createWhiteSpace(namespace.getProject(), lineSeparator + lineSeparator), firstDeclaration);
}
}
public static void perform(@NotNull String typeFullName, @NotNull JetFile namespace, @Nullable PsiElement elementToReplace, @Nullable PsiElement newElement) {
addImportDirective(typeFullName, namespace);
if (elementToReplace != null && newElement != null && elementToReplace != newElement) {
elementToReplace.replace(newElement);
firstDeclaration.getParent().addBefore(JetPsiFactory.createWhiteSpace(file.getProject(), lineSeparator + lineSeparator), firstDeclaration);
}
}
}
@@ -78,6 +78,7 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!(file instanceof JetFile)) return;
JetProperty newElement = (JetProperty) element.copy();
JetPropertyAccessor getter = newElement.getGetter();
if (removeGetter && getter != null) {
@@ -102,10 +103,9 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
}
}
if (needImport) {
ImportClassHelper.perform(type, element, newElement);
} else {
element.replace(newElement);
ImportClassHelper.addImportDirectiveIfNeeded(type, (JetFile)file);
}
element.replace(newElement);
}
public static JetIntentionActionFactory<JetProperty> createFactory() {
@@ -10,16 +10,17 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetBinaryExpressionWithTypeRHS;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.plugin.JetBundle;
/**
* @author svtk
*/
public abstract class ReplaceOperationInBinaryExpressionFix<T extends JetExpression> extends JetIntentionAction<T> {
private final String expressionWithNecessaryOperation;
public ReplaceOperationInBinaryExpressionFix(@NotNull T element, String expressionWithNecessaryOperation) {
private final String operation;
public ReplaceOperationInBinaryExpressionFix(@NotNull T element, String operation) {
super(element);
this.expressionWithNecessaryOperation = expressionWithNecessaryOperation;
this.operation = operation;
}
@NotNull
@@ -31,12 +32,12 @@ public abstract class ReplaceOperationInBinaryExpressionFix<T extends JetExpress
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (element instanceof JetBinaryExpressionWithTypeRHS) {
JetBinaryExpressionWithTypeRHS expression = (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, expressionWithNecessaryOperation);
JetBinaryExpressionWithTypeRHS newElement = (JetBinaryExpressionWithTypeRHS) element.copy();
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getOperationSign().getNode(), expression.getOperationSign().getNode());
element.replace(newElement);
JetExpression left = ((JetBinaryExpressionWithTypeRHS) element).getLeft();
JetTypeReference right = ((JetBinaryExpressionWithTypeRHS) element).getRight();
if (right != null) {
JetExpression expression = JetPsiFactory.createExpression(project, left.getText() + operation + right.getText());
element.replace(expression);
}
}
}
@@ -45,7 +46,7 @@ public abstract class ReplaceOperationInBinaryExpressionFix<T extends JetExpress
@Override
public JetIntentionAction<JetBinaryExpressionWithTypeRHS> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetBinaryExpressionWithTypeRHS;
return new ReplaceOperationInBinaryExpressionFix<JetBinaryExpressionWithTypeRHS>((JetBinaryExpressionWithTypeRHS) diagnostic.getPsiElement(), "2 : Int") {
return new ReplaceOperationInBinaryExpressionFix<JetBinaryExpressionWithTypeRHS>((JetBinaryExpressionWithTypeRHS) diagnostic.getPsiElement(), " : ") {
@NotNull
@Override
public String getText() {
@@ -8,7 +8,8 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.plugin.JetMainDetector;
@@ -17,24 +18,26 @@ import org.jetbrains.jet.plugin.JetMainDetector;
* @author yole
*/
public class JetRunConfigurationProducer extends RuntimeConfigurationProducer implements Cloneable {
@Nullable
private PsiElement mySourceElement;
public JetRunConfigurationProducer() {
super(JetRunConfigurationType.getInstance());
}
@Nullable
@Override
public PsiElement getSourceElement() {
return mySourceElement;
}
@Override
protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext configurationContext) {
JetClass containingClass = (JetClass) location.getParentElement(JetClass.class);
if (containingClass != null && JetMainDetector.hasMain(containingClass.getDeclarations())) {
mySourceElement = containingClass;
return createConfigurationByQName(location.getModule(), configurationContext, JetPsiUtil.getFQName(containingClass));
protected RunnerAndConfigurationSettings createConfigurationByElement(@NotNull Location location, ConfigurationContext configurationContext) {
final Module module = location.getModule();
if (module == null) {
return null;
}
PsiFile psiFile = location.getPsiElement().getContainingFile();
if (psiFile instanceof JetFile) {
JetFile jetFile = (JetFile) psiFile;
@@ -42,13 +45,17 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im
mySourceElement = jetFile;
String fqName = JetPsiUtil.getFQName(jetFile);
String className = fqName.length() == 0 ? "namespace" : fqName + ".namespace";
return createConfigurationByQName(location.getModule(), configurationContext, className);
return createConfigurationByQName(module, configurationContext, className);
}
}
return null;
}
private RunnerAndConfigurationSettings createConfigurationByQName(Module module, ConfigurationContext context, String fqName) {
private RunnerAndConfigurationSettings createConfigurationByQName(
@NotNull Module module,
ConfigurationContext context,
@NotNull String fqName
) {
RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(module.getProject(), context);
JetRunConfiguration configuration = (JetRunConfiguration) settings.getConfiguration();
configuration.setModule(module);
@@ -0,0 +1,12 @@
class TestClass {
/* <caret> */
fun test() {
'<caret>'
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in, inline
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
@@ -0,0 +1,11 @@
class TestClass {
fun test() {
'<caret>'
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in, inline
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
@@ -0,0 +1,59 @@
public class Test {
<caret>
fun test() {
}
}
// EXIST: abstract
// ?ABSENT: annotation
// ABSENT: as
// ABSENT: break
// ABSENT: by
// ABSENT: catch
// EXIST: class
// ABSENT: continue
// ABSENT: default
// ABSENT: do
// ABSENT: else
// EXIST: enum
// ABSENT: false
// EXIST: final
// ABSENT: finally
// ABSENT: for
// EXIST: fun
// EXIST: get
// ABSENT: if
// ABSENT: import
// ABSENT: in
// EXIST: inline
// EXIST: internal
// ABSENT: is
// ABSENT: null
// EXIST: object
// EXIST: open
// ABSENT: out
// EXIST: override
// ABSENT: package
// EXIST: private
// EXIST: protected
// EXIST: public
// ABSENT: ref
// ABSENT: return
// EXIST: set
// ABSENT: super
// ABSENT: This
// ABSENT: this
// ABSENT: throw
// EXIST: trait
// ABSENT: true
// ABSENT: try
// EXIST: type
// EXIST: val
// EXIST: var
// ABSENT: vararg
// ABSENT: when
// ABSENT: where
// ABSENT: while
@@ -27,7 +27,7 @@ class TestClass {
// EXIST: internal
// ABSENT: is
// ABSENT: null
// ABSENT: object
// EXIST: object
// EXIST: open
// ABSENT: out
// EXIST: override
@@ -0,0 +1,11 @@
class TestClass {
fun test() {
"<caret>"
}
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in, inline
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
@@ -0,0 +1,9 @@
class TestClass {
// <caret>
}
// ABSENT: abstract, annotation, as, break, by, catch, class, continue, default, do
// ABSENT: else, enum, false, final, finally, for, fun, get, if, import, in, inline
// ABSENT: internal, is, null, object, open, out, override, package, private, protected, public
// ABSENT: ref, return, set, super, This, this, throw, trait, true, try, type, val, var
// ABSENT: vararg, when, where, while
@@ -0,0 +1,7 @@
class Some {
val a : Int
<caret>
}
// EXIST: get
// EXIST: set
@@ -0,0 +1,5 @@
class Test {
class <caret>
}
// EXIST: object
@@ -0,0 +1,5 @@
// "Add return type declaration" "false"
class A() {
public val <caret>t = foo()
}
@@ -0,0 +1,9 @@
// "Add return type declaration" "true"
package a
import b.B
class A() {
public val <caret>a : B = b.foo()
}
@@ -0,0 +1,7 @@
// "Add return type declaration" "true"
class A() {}
class B() {
public val <caret>a : A = A()
}
@@ -0,0 +1,5 @@
package b
class B() {}
fun foo() = B()
@@ -0,0 +1,7 @@
// "Add return type declaration" "true"
package a
class A() {
public val <caret>a = b.foo()
}
@@ -0,0 +1,7 @@
// "Add return type declaration" "true"
class A() {}
class B() {
public val <caret>a = A()
}
@@ -1,5 +1,6 @@
// "Make variable mutable" "true"
class A() {
var a: Int = 0
<caret>set(v: Int) {}
set(v: Int) {
}
}
@@ -147,7 +147,7 @@ public class JetPsiCheckerMultifileTest extends DaemonAnalyzerTestCase {
}
});
final ArrayList<File> fileResult = new ArrayList<File>(allTestFiles);
final ArrayList<File> fileResult = new ArrayList<File>(mainFiles);
fileResult.addAll(dataFiles);
return fileResult;