diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java index e86a45a7165..8268cf6fa79 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java @@ -9,7 +9,8 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.ErrorHandler; -import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lexer.JetTokens; /** @@ -28,6 +29,11 @@ public class JetReferenceExpression extends JetExpression { return node == null ? null : node.getText(); } + @Nullable @IfNotParsed + public PsiElement getReferencedNameElement() { + return findChildByType(REFERENCE_TOKENS); + } + @Override public void accept(JetVisitor visitor) { visitor.visitReferenceExpression(this); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index f11a18d5e82..2f2cb3dd038 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -25,7 +25,7 @@ public class AnalyzingUtils { BindingTraceContext bindingTraceContext = new BindingTraceContext(); JavaSemanticServices javaSemanticServices = new JavaSemanticServices(project, semanticServices, bindingTraceContext); - ScopeWithImports scope = new ScopeWithImports(semanticServices.getStandardLibrary().getLibraryScope()); + WritableScope scope = new WritableScope(semanticServices.getStandardLibrary().getLibraryScope()); scope.importScope(new JavaPackageScope("", javaSemanticServices)); scope.importScope(new JavaPackageScope("java.lang", javaSemanticServices)); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index fe25304891b..ee17da72625 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -135,7 +135,7 @@ public class ClassDescriptorResolver { JetExpression bodyExpression = function.getBodyExpression(); assert bodyExpression != null : "No type, no body"; // TODO // TODO : Recursion possible - returnType = semanticServices.getTypeInferrer().getType(parameterScope, bodyExpression, function.hasBlockBody()); + returnType = semanticServices.getTypeInferrer().safeGetType(parameterScope, bodyExpression, function.hasBlockBody()); } FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl( diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithImports.java b/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithImports.java deleted file mode 100644 index 4b36c36c72e..00000000000 --- a/idea/src/org/jetbrains/jet/lang/resolve/ScopeWithImports.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.jetbrains.jet.lang.resolve; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.types.*; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author abreslav - */ -public class ScopeWithImports implements JetScope { - - private final List imports = new ArrayList(); - private final JetScope scope; - - public ScopeWithImports(JetScope scope) { - this.scope = scope; - } - - public void importScope(JetScope imported) { - imports.add(0, imported); - } - - @Override - public ClassDescriptor getClass(@NotNull String name) { - ClassDescriptor descriptor = scope.getClass(name); - if (descriptor != null) return descriptor; - for (JetScope imported : imports) { - ClassDescriptor importedClass = imported.getClass(name); - if (importedClass != null) { - return importedClass; - } - } - return null; - } - - @Override - public PropertyDescriptor getProperty(@NotNull String name) { - PropertyDescriptor descriptor = scope.getProperty(name); - if (descriptor != null) return descriptor; - for (JetScope imported : imports) { - PropertyDescriptor importedDescriptor = imported.getProperty(name); - if (importedDescriptor != null) { - return importedDescriptor; - } - } - return null; - } - - @Override - public ExtensionDescriptor getExtension(@NotNull String name) { - throw new UnsupportedOperationException(); // TODO - } - - @Override - public NamespaceDescriptor getNamespace(@NotNull String name) { - NamespaceDescriptor descriptor = scope.getNamespace(name); - if (descriptor != null) return descriptor; - for (JetScope imported : imports) { - NamespaceDescriptor importedDescriptor = imported.getNamespace(name); - if (importedDescriptor != null) { - return importedDescriptor; - } - } - return null; - } - - @Override - public TypeParameterDescriptor getTypeParameter(@NotNull String name) { - return scope.getTypeParameter(name); - } - - @NotNull - @Override - public Type getThisType() { - return scope.getThisType(); - } - - @NotNull - @Override - public FunctionGroup getFunctionGroup(@NotNull String name) { - return scope.getFunctionGroup(name); // TODO - } -} diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 63b416af0e3..2bfe0a5e1c2 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -13,6 +13,7 @@ import java.util.*; public class TopDownAnalyzer { private final Map classes = new LinkedHashMap(); + private final Map namespaceScopes = new LinkedHashMap(); private final Map functions = new HashMap(); private final Map declaringScopes = new HashMap(); @@ -56,7 +57,8 @@ public class TopDownAnalyzer { public void visitNamespace(JetNamespace namespace) { List importDirectives = namespace.getImportDirectives(); - ScopeWithImports scopeWithImports = new ScopeWithImports(declaringScope); + WritableScope namespaceScope = new WritableScope(declaringScope); + namespaceScopes.put(namespace, namespaceScope); for (JetImportDirective importDirective : importDirectives) { if (importDirective.isAbsoluteInRootNamespace()) { @@ -64,15 +66,15 @@ public class TopDownAnalyzer { } if (importDirective.isAllUnder()) { JetExpression importedReference = importDirective.getImportedReference(); - Type type = semanticServices.getTypeInferrer(trace).getType(scopeWithImports, importedReference, false); + Type type = semanticServices.getTypeInferrer(trace).getType(namespaceScope, importedReference, false); if (type != null) { - scopeWithImports.importScope(type.getMemberScope()); + namespaceScope.importScope(type.getMemberScope()); } } else { throw new UnsupportedOperationException(); } } - WritableScope namespaceScope = new WritableScope(scopeWithImports); + collectTypeDeclarators(namespaceScope, namespace.getDeclarations()); } @@ -138,7 +140,8 @@ public class TopDownAnalyzer { @Override public void visitNamespace(JetNamespace namespace) { - collectBehaviorDeclarators(declaringScope, namespace.getDeclarations()); + WritableScope namespaceScope = namespaceScopes.get(namespace); + collectBehaviorDeclarators(namespaceScope, namespace.getDeclarations()); } @Override diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 73efea33728..6138aadb5ff 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -180,7 +180,11 @@ public class TypeResolver { return classDescriptor.getMemberScope(resolveTypeProjections(scope, classDescriptor.getTypeConstructor(), userType.getTypeArguments())); } - return resolveNamespace(scope, userType).getMemberScope(); + NamespaceDescriptor namespaceDescriptor = resolveNamespace(scope, userType); + if (namespaceDescriptor == null) { + return JetScope.EMPTY; + } + return namespaceDescriptor.getMemberScope(); } @Nullable @@ -199,7 +203,9 @@ public class TypeResolver { } NamespaceDescriptor namespace = scope.getNamespace(userType.getReferencedName()); - trace.recordReferenceResolution(userType.getReferenceExpression(), namespace); + if (namespace != null) { + trace.recordReferenceResolution(userType.getReferenceExpression(), namespace); + } return namespace; } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java b/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java index ce10ea0472e..77accc53570 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/WritableScope.java @@ -4,7 +4,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.types.*; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -21,11 +23,25 @@ public class WritableScope extends JetScopeAdapter { private Map classDescriptors; @Nullable private Type thisType; + @Nullable + private List imports; public WritableScope(JetScope scope) { super(scope); } + public void importScope(JetScope imported) { + getImports().add(0, imported); + } + + @NotNull + private List getImports() { + if (imports == null) { + imports = new ArrayList(); + } + return imports; + } + @NotNull private Map getPropertyDescriptors() { if (propertyDescriptors == null) { @@ -50,7 +66,17 @@ public class WritableScope extends JetScopeAdapter { if (propertyDescriptor != null) { return propertyDescriptor; } - return super.getProperty(name); + propertyDescriptor = super.getProperty(name); + if (propertyDescriptor != null) { + return propertyDescriptor; + } + for (JetScope imported : getImports()) { + PropertyDescriptor importedDescriptor = imported.getProperty(name); + if (importedDescriptor != null) { + return importedDescriptor; + } + } + return null; } @NotNull @@ -77,11 +103,20 @@ public class WritableScope extends JetScopeAdapter { @Override @NotNull public FunctionGroup getFunctionGroup(@NotNull String name) { - WritableFunctionGroup functionGroup = getFunctionGroups().get(name); + FunctionGroup functionGroup = getFunctionGroups().get(name); if (functionGroup != null && !functionGroup.isEmpty()) { return functionGroup; } - return super.getFunctionGroup(name); + // TODO : this logic is questionable + functionGroup = super.getFunctionGroup(name); + if (!functionGroup.isEmpty()) return functionGroup; + for (JetScope imported : getImports()) { + FunctionGroup importedDescriptor = imported.getFunctionGroup(name); + if (!importedDescriptor.isEmpty()) { + return importedDescriptor; + } + } + return functionGroup; } @NotNull @@ -132,10 +167,17 @@ public class WritableScope extends JetScopeAdapter { @Override public ClassDescriptor getClass(@NotNull String name) { ClassDescriptor classDescriptor = getClassDescriptors().get(name); - if (classDescriptor != null) { - return classDescriptor; + if (classDescriptor != null) return classDescriptor; + + classDescriptor = super.getClass(name); + if (classDescriptor != null) return classDescriptor; + for (JetScope imported : getImports()) { + ClassDescriptor importedClass = imported.getClass(name); + if (importedClass != null) { + return importedClass; + } } - return super.getClass(name); + return null; } @NotNull @@ -149,7 +191,15 @@ public class WritableScope extends JetScopeAdapter { @Override public NamespaceDescriptor getNamespace(@NotNull String name) { - return super.getNamespace(name); // TODO + NamespaceDescriptor namespace = super.getNamespace(name); + if (namespace != null) return namespace; + for (JetScope imported : getImports()) { + NamespaceDescriptor importedDescriptor = imported.getNamespace(name); + if (importedDescriptor != null) { + return importedDescriptor; + } + } + return null; } @Override diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index afeb4d1c417..ae8c9a2030f 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -28,20 +28,16 @@ public class JetTypeInferrer { this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, trace); } - /* - : "new" constructorInvocation + @NotNull + public Type safeGetType(@NotNull final JetScope scope, @NotNull JetExpression expression, final boolean preferBlock) { + Type type = getType(scope, expression, preferBlock); + if (type != null) { + return type; + } + return ErrorType.createErrorType("Type for " + expression.getText()); + } - : objectLiteral - - : SimpleName - - : "typeof" "(" expression ")" - - : functionLiteral - - : declaration - : "namespace" // for the root namespace - */ + @Nullable public Type getType(@NotNull final JetScope scope, @NotNull JetExpression expression, final boolean preferBlock) { final Type[] result = new Type[1]; expression.accept(new JetVisitor() { diff --git a/idea/testData/resolve/ResolveToJava.jet b/idea/testData/resolve/ResolveToJava.jet new file mode 100644 index 00000000000..d8b5bd82049 --- /dev/null +++ b/idea/testData/resolve/ResolveToJava.jet @@ -0,0 +1,31 @@ +import `java::java`java.* +import `java::java.util`util.* + +fun foo(o : `java::java.lang.Object`Object, l : `java::java.util`util.`java::java.util.List`List) : `java::java.util.List`List {} + +~A~class A { + fun f(a : `java::java.util`util.`java::java.util.List`List) {} + fun f(a : `java::java.util.List`List) {} + +} + +class B : `java::java.lang.Object`Object { + fun bar(~o~o : `java::java.lang.Object`Object) { + `java::java.lang.System`System.`java::java.lang.System.out`out.`java::java.io.PrintStream.print(Object)`print(`o`o) + } + + fun f(a : `java::java.util`util.`java::java.util.List`List) {} + fun f(a : `java::java.util.List`List) {} + + + ~foo~fun foo(abc : `A`A) : `A`A { + `java::java`java.`java::java.lang`lang.`java::java.lang.System`System.`java::java.lang.System.out`out.`java::java.io.PrintStream.print(Int)`print(1) + `java::java.util`util.`java::java.util.Collections`Collections.`java::java.util.Collections.emptyList()`emptyList() + `java::java`java.`!`Foo + `java::java.util.Collections`Collections.`java::java.util.Collections.emptyList()`emptyList() + } + + fun barrr() : `std::Int`Int { + `foo`foo(new `A`A()) + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java index 17974f7f845..47d6f78abae 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java +++ b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java @@ -10,15 +10,11 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.*; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertSame; +import static junit.framework.Assert.*; /** * @author abreslav @@ -28,16 +24,24 @@ public class ExpectedResolveData { private final Map declarationToPosition = new HashMap(); private final Map positionToReference = new HashMap(); private final Map positionToType = new HashMap(); + private final Map nameToDescriptor; + private final Map nameToPsiElement; - public ExpectedResolveData(final Document document) { + + public ExpectedResolveData(Map nameToDescriptor, Map nameToPsiElement) { + this.nameToDescriptor = nameToDescriptor; + this.nameToPsiElement = nameToPsiElement; + } + + public void extractData(final Document document) { new WriteCommandAction.Simple(null) { public void run() { - extractData(document); + doExtractData(document); } }.execute().throwException(); } - private void extractData(Document document) { + private void doExtractData(Document document) { String text = document.getText(); Pattern pattern = Pattern.compile("(~[^~]+~)|(`[^`]+`)"); @@ -71,12 +75,16 @@ public class ExpectedResolveData { } public void checkResult(JetFile file) { - JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject(), ErrorHandler.THROW_EXCEPTION); + final Set unresolvedReferences = new HashSet(); + JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject(), new ErrorHandler() { + @Override + public void unresolvedReference(JetReferenceExpression referenceExpression) { + unresolvedReferences.add(referenceExpression.getReferencedNameElement()); + } + }); JetStandardLibrary lib = semanticServices.getStandardLibrary(); - Map nameToDescriptor = new HashMap(); - nameToDescriptor.put("std::Int.plus(Int)", standardFunction(lib.getInt(), "plus", lib.getIntType())); - BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, ErrorHandler.THROW_EXCEPTION); + BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, semanticServices.getErrorHandler()); Map nameToDeclaration = new HashMap(); @@ -96,7 +104,15 @@ public class ExpectedResolveData { String name = entry.getValue(); PsiElement element = file.findElementAt(position); - JetDeclaration expected = nameToDeclaration.get(name); + if ("!".equals(name)) { + assertTrue("Must have been unresolved: " + element, unresolvedReferences.contains(element)); + continue; + } + + PsiElement expected = nameToDeclaration.get(name); + if (expected == null) { + expected = nameToPsiElement.get(name); + } JetReferenceExpression reference = getAncestorOfType(JetReferenceExpression.class, element); if (expected == null && name.startsWith("std::")) { @@ -158,17 +174,6 @@ public class ExpectedResolveData { } } - private DeclarationDescriptor standardFunction(ClassDescriptor classDescriptor, String name, Type parameterType) { - FunctionGroup functionGroup = classDescriptor.getMemberScope(Collections.emptyList()).getFunctionGroup(name); - Collection functions = functionGroup.getPossiblyApplicableFunctions(Collections.emptyList(), Collections.singletonList(parameterType)); - for (FunctionDescriptor function : functions) { - if (function.getUnsubstitutedValueParameters().get(0).getType().equals(parameterType)) { - return function; - } - } - throw new IllegalArgumentException("Not found: std::" + classDescriptor.getName() + "." + name + "(" + parameterType + ")"); - } - private T getAncestorOfType(Class type, PsiElement element) { while (element != null && !type.isInstance(element)) { element = element.getParent(); diff --git a/idea/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java b/idea/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java index 4023520cb78..ae0e9342e25 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java +++ b/idea/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java @@ -28,17 +28,21 @@ import java.util.List; */ public abstract class ExtensibleResolveTestCase extends LightCodeInsightTestCase { private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter(); + private ExpectedResolveData expectedResolveData; @Override protected void setUp() throws Exception { super.setUp(); + expectedResolveData = getExpectedResolveData(); ((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(getProject())).prepareForTest(true); DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false); } + protected abstract ExpectedResolveData getExpectedResolveData(); + @Override protected void tearDown() throws Exception { - ((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(true); // has to cleanup by hand since light project does not get disposed any time soon + ((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(); // has to cleanup by hand since light project does not get disposed any time soon super.tearDown(); } @@ -69,7 +73,7 @@ public abstract class ExtensibleResolveTestCase extends LightCodeInsightTestCase getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE); // ExpectedHighlightingData expectedData = new ExpectedHighlightingData(getEditor().getDocument(), checkWarnings, checkInfos); - ExpectedResolveData expectedData = new ExpectedResolveData(getEditor().getDocument()); + expectedResolveData.extractData(getEditor().getDocument()); PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); getFile().getText(); //to load text @@ -80,7 +84,7 @@ public abstract class ExtensibleResolveTestCase extends LightCodeInsightTestCase getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE); - expectedData.checkResult((JetFile) getFile()); + expectedResolveData.checkResult((JetFile) getFile()); } @NotNull diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java index 95a52094388..c195a8a5c92 100644 --- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -1,9 +1,21 @@ package org.jetbrains.jet.resolve; import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.search.GlobalSearchScope; +import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.parsing.JetParsingTest; import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.*; /** * @author abreslav @@ -11,8 +23,55 @@ import java.io.File; public class JetResolveTest extends ExtensibleResolveTestCase { @Override - public void setUp() throws Exception { - super.setUp(); + protected ExpectedResolveData getExpectedResolveData() { + Project project = getProject(); + JetStandardLibrary lib = JetStandardLibrary.getJetStandardLibrary(project); + Map nameToDescriptor = new HashMap(); + nameToDescriptor.put("std::Int.plus(Int)", standardFunction(lib.getInt(), "plus", lib.getIntType())); + + Map nameToDeclaration = new HashMap(); + nameToDeclaration.put("java::java.util.Collections.emptyList()", findMethod(findClass(project, "java.util.Collections"), "emptyList")); + nameToDeclaration.put("java::java.util.Collections", findClass(project, "java.util.Collections")); + nameToDeclaration.put("java::java.util.List", findClass(project, "java.util.List")); + nameToDeclaration.put("java::java", findPackage(project, "java")); + nameToDeclaration.put("java::java.util", findPackage(project, "java.util")); + nameToDeclaration.put("java::java.lang", findPackage(project, "java.lang")); + nameToDeclaration.put("java::java.lang.Object", findClass(project, "java.lang.Object")); + nameToDeclaration.put("java::java.lang.System", findClass(project, "java.lang.System")); + PsiMethod[] methods = findClass(project, "java.io.PrintStream").findMethodsByName("print", true); + nameToDeclaration.put("java::java.io.PrintStream.print(Object)", methods[8]); + nameToDeclaration.put("java::java.io.PrintStream.print(Int)", methods[2]); + nameToDeclaration.put("java::java.lang.System.out", findClass(project, "java.lang.System").findFieldByName("out", true)); + + + return new ExpectedResolveData(nameToDescriptor, nameToDeclaration); + } + + private PsiElement findPackage(Project project, String qualifiedName) { + JavaPsiFacade javaFacade = JavaPsiFacade.getInstance(project); + return javaFacade.findPackage(qualifiedName); + } + + private PsiMethod findMethod(PsiClass collections, String name) { + PsiMethod[] emptyLists = collections.findMethodsByName(name, true); + return emptyLists[0]; + } + + private PsiClass findClass(Project project, String qualifiedName) { + JavaPsiFacade javaFacade = JavaPsiFacade.getInstance(project); + GlobalSearchScope javaSearchScope = GlobalSearchScope.allScope(project); + return javaFacade.findClass(qualifiedName, javaSearchScope); + } + + private DeclarationDescriptor standardFunction(ClassDescriptor classDescriptor, String name, Type parameterType) { + FunctionGroup functionGroup = classDescriptor.getMemberScope(Collections.emptyList()).getFunctionGroup(name); + Collection functions = functionGroup.getPossiblyApplicableFunctions(Collections.emptyList(), Collections.singletonList(parameterType)); + for (FunctionDescriptor function : functions) { + if (function.getUnsubstitutedValueParameters().get(0).getType().equals(parameterType)) { + return function; + } + } + throw new IllegalArgumentException("Not found: std::" + classDescriptor.getName() + "." + name + "(" + parameterType + ")"); } @Override @@ -20,6 +79,18 @@ public class JetResolveTest extends ExtensibleResolveTestCase { return getHomeDirectory() + "/idea/testData"; } + @Override + protected Sdk getProjectJDK() { + Properties properties = new Properties(); + try { + properties.load(new FileReader(getHomeDirectory() + "/idea/idea.properties")); + } catch (IOException e) { + throw new RuntimeException(e); + } + String home = properties.getProperty("idea.home"); + return new JavaSdkImpl().createJdk("JDK", home + "/java/mockJDK-1.7/jre", true); + } + private static String getHomeDirectory() { return new File(PathManager.getResourceRoot(JetParsingTest.class, "/org/jetbrains/jet/parsing/JetParsingTest.class")).getParentFile().getParentFile().getParent(); } @@ -28,4 +99,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase { doTest("/resolve/Basic.jet", true, true); } + public void testResolveToJava() throws Exception { + doTest("/resolve/ResolveToJava.jet", true, true); + } + } \ No newline at end of file