Merge branch 'master' of git://github.com/JetBrains/kotlin
This commit is contained in:
@@ -151,6 +151,20 @@
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="generateStdlib" depends="compileTestlib" description="Generates the stdlib APIs for arrays and kotlin collections">
|
||||
<java classname="kotlin.tools.namespace" failonerror="true" fork="true">
|
||||
<classpath>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-runtime.jar"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-test.jar"/>
|
||||
<pathelement location="${basedir}/testlib/lib/junit-4.9.jar"/>
|
||||
<fileset dir="${basedir}/testlib/lib">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
<pathelement path="${output}/classes/testlib"/>
|
||||
</classpath>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="testlib" depends="compileTestlib">
|
||||
<mkdir dir="${output}/test-reports"/>
|
||||
|
||||
|
||||
+67
-50
@@ -282,14 +282,16 @@ public class JavaDescriptorResolver {
|
||||
ResolverBinaryClassData classData = new ResolverBinaryClassData();
|
||||
classDescriptorCache.put(psiClass.getQualifiedName(), classData);
|
||||
ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS;
|
||||
DeclarationDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
|
||||
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
|
||||
classData.classDescriptor = new MutableClassDescriptorLite(containingDeclaration, kind);
|
||||
classData.classDescriptor.setName(name);
|
||||
classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass));
|
||||
|
||||
List<JetType> supertypes = new ArrayList<JetType>();
|
||||
|
||||
TypeVariableResolverFromOuters outerTypeVariableByNameResolver = new TypeVariableResolverFromOuters(containingDeclaration);
|
||||
TypeVariableResolver outerTypeVariableByNameResolver = TypeVariableResolvers.classTypeVariableResolver(
|
||||
(ClassOrNamespaceDescriptor) classData.classDescriptor.getContainingDeclaration(),
|
||||
"class " + psiClass.getQualifiedName());
|
||||
|
||||
classData.typeParameters = createUninitializedClassTypeParameters(psiClass, classData, outerTypeVariableByNameResolver);
|
||||
|
||||
@@ -314,9 +316,11 @@ public class JavaDescriptorResolver {
|
||||
classData.classDescriptor.createTypeConstructor();
|
||||
classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false));
|
||||
|
||||
initializeTypeParameters(classData.typeParameters, new TypeVariableResolverFromTypeDescriptors(new ArrayList<TypeParameterDescriptor>(), outerTypeVariableByNameResolver));
|
||||
initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName());
|
||||
|
||||
TypeVariableResolverFromTypeDescriptors resolverForTypeParameters = new TypeVariableResolverFromTypeDescriptors(classData.getTypeParameters(), null);
|
||||
TypeVariableResolver resolverForTypeParameters = TypeVariableResolvers.classTypeVariableResolver(
|
||||
classData.classDescriptor,
|
||||
"class " + psiClass.getQualifiedName());
|
||||
|
||||
// TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
|
||||
supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData.classDescriptor, classData.getTypeParameters()));
|
||||
@@ -392,10 +396,10 @@ public class JavaDescriptorResolver {
|
||||
classData.classDescriptor,
|
||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||
false);
|
||||
String context = "constructor of class " + psiClass.getQualifiedName();
|
||||
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
|
||||
constructor.getParameters(),
|
||||
new TypeVariableResolverFromTypeDescriptors(classData.getTypeParameters(), null) // TODO: outer too
|
||||
);
|
||||
TypeVariableResolvers.classTypeVariableResolver(classData.classDescriptor, context));
|
||||
if (valueParameterDescriptors.receiverType != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
@@ -474,7 +478,7 @@ public class JavaDescriptorResolver {
|
||||
|
||||
if (jetClassAnnotation.signature().length() > 0) {
|
||||
return resolveClassTypeParametersFromJetSignature(
|
||||
jetClassAnnotation.signature(), psiClass, classData.classDescriptor, typeVariableResolver);
|
||||
jetClassAnnotation.signature(), psiClass, classData.classDescriptor);
|
||||
}
|
||||
|
||||
return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters());
|
||||
@@ -578,11 +582,14 @@ public class JavaDescriptorResolver {
|
||||
private final TypeVariableResolver typeVariableResolver;
|
||||
|
||||
|
||||
private JetSignatureTypeParametersVisitor(@NotNull TypeVariableResolver containerTypeVariableResolver, @NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameterListOwner psiOwner) {
|
||||
private JetSignatureTypeParametersVisitor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameterListOwner psiOwner, @NotNull String context) {
|
||||
this.containingDeclaration = containingDeclaration;
|
||||
this.psiOwner = psiOwner;
|
||||
|
||||
this.typeVariableResolver = new TypeVariableResolverFromTypeDescriptors(previousTypeParameters, containerTypeVariableResolver);
|
||||
this.typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(
|
||||
previousTypeParameters,
|
||||
containingDeclaration,
|
||||
context);
|
||||
}
|
||||
|
||||
private int formalTypeParameterIndex = 0;
|
||||
@@ -613,11 +620,12 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #resolveMethodTypeParametersFromJetSignature(String, com.intellij.psi.PsiMethod, org.jetbrains.jet.lang.descriptors.DeclarationDescriptor, TypeVariableResolver)
|
||||
* @see #resolveMethodTypeParametersFromJetSignature(String, com.intellij.psi.PsiMethod, org.jetbrains.jet.lang.descriptors.DeclarationDescriptor)
|
||||
*/
|
||||
private List<TypeParameterDescriptorInitialization> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz,
|
||||
final ClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) {
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(outerClassTypeVariableResolver, classDescriptor, clazz) {
|
||||
private List<TypeParameterDescriptorInitialization> resolveClassTypeParametersFromJetSignature(String jetSignature,
|
||||
final PsiClass clazz, final ClassDescriptor classDescriptor) {
|
||||
String context = "class " + clazz.getQualifiedName();
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(classDescriptor, clazz, context) {
|
||||
@Override
|
||||
public JetSignatureVisitor visitSuperclass() {
|
||||
// TODO
|
||||
@@ -634,7 +642,7 @@ public class JavaDescriptorResolver {
|
||||
return jetSignatureTypeParametersVisitor.r;
|
||||
}
|
||||
|
||||
private DeclarationDescriptor resolveParentDescriptor(PsiClass psiClass) {
|
||||
private ClassOrNamespaceDescriptor resolveParentDescriptor(PsiClass psiClass) {
|
||||
PsiClass containingClass = psiClass.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
return resolveClass(containingClass);
|
||||
@@ -704,19 +712,21 @@ public class JavaDescriptorResolver {
|
||||
typeParameterDescriptor.setInitialized();
|
||||
}
|
||||
|
||||
private void initializeTypeParameters(List<TypeParameterDescriptorInitialization> typeParametersInitialization, TypeVariableResolver typeVariableByPsiResolver) {
|
||||
private void initializeTypeParameters(List<TypeParameterDescriptorInitialization> typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) {
|
||||
List<TypeParameterDescriptor> prevTypeParameters = new ArrayList<TypeParameterDescriptor>();
|
||||
for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) {
|
||||
prevTypeParameters.add(psiTypeParameter.descriptor);
|
||||
initializeTypeParameter(psiTypeParameter, new TypeVariableResolverFromTypeDescriptors(prevTypeParameters, typeVariableByPsiResolver));
|
||||
initializeTypeParameter(psiTypeParameter, TypeVariableResolvers.typeVariableResolverFromTypeParameters(prevTypeParameters, typeParametersOwner, context));
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<JetType> getSupertypes(PsiClassWrapper psiClass, ClassDescriptor classDescriptor, List<TypeParameterDescriptor> typeParameters) {
|
||||
final List<JetType> result = new ArrayList<JetType>();
|
||||
|
||||
String context = "class " + psiClass.getQualifiedName();
|
||||
|
||||
if (psiClass.getJetClass().signature().length() > 0) {
|
||||
final TypeVariableResolver typeVariableResolver = new TypeVariableResolverFromTypeDescriptors(typeParameters, null);
|
||||
final TypeVariableResolver typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
|
||||
|
||||
new JetSignatureReader(psiClass.getJetClass().signature()).accept(new JetSignatureExceptionsAdapter() {
|
||||
@Override
|
||||
@@ -743,8 +753,9 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), new TypeVariableResolverFromTypeDescriptors(typeParameters, null), classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), new TypeVariableResolverFromTypeDescriptors(typeParameters, null), classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
||||
TypeVariableResolver typeVariableResolverForSupertypes = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
||||
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes, classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS);
|
||||
}
|
||||
|
||||
for (JetType supertype : result) {
|
||||
@@ -792,17 +803,27 @@ public class JavaDescriptorResolver {
|
||||
return resolveNamespace(psiPackage);
|
||||
}
|
||||
|
||||
public PsiClass findClass(String qualifiedName) {
|
||||
@Nullable
|
||||
public PsiClass findClass(@NotNull String qualifiedName) {
|
||||
PsiClass original = javaFacade.findClass(qualifiedName, javaSearchScope);
|
||||
PsiClass altClass = altClassFinder.findClass(qualifiedName);
|
||||
PsiClass result = original;
|
||||
if (altClass != null) {
|
||||
if (altClass instanceof ClsClassImpl) {
|
||||
altClass.putUserData(ClsClassImpl.DELEGATE_KEY, original);
|
||||
}
|
||||
|
||||
return altClass;
|
||||
result = altClass;
|
||||
}
|
||||
return original;
|
||||
|
||||
if (result != null) {
|
||||
String actualQualifiedName = result.getQualifiedName();
|
||||
if (!actualQualifiedName.equals(qualifiedName)) {
|
||||
throw new IllegalStateException("requested " + qualifiedName + ", got " + actualQualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*package*/ PsiPackage findPackage(String qualifiedName) {
|
||||
@@ -978,7 +999,7 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) {
|
||||
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, String fieldName, boolean staticMembers) {
|
||||
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
|
||||
|
||||
NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName);
|
||||
@@ -987,7 +1008,7 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
Set<VariableDescriptor> r = new HashSet<VariableDescriptor>();
|
||||
|
||||
resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, fieldName);
|
||||
resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, fieldName, "class or namespace " + psiClass.getQualifiedName());
|
||||
|
||||
r.addAll(namedMembers.propertyDescriptors);
|
||||
|
||||
@@ -999,7 +1020,7 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<VariableDescriptor> resolveFieldGroup(@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass, boolean staticMembers) {
|
||||
public Set<VariableDescriptor> resolveFieldGroup(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, boolean staticMembers) {
|
||||
|
||||
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
|
||||
|
||||
@@ -1013,7 +1034,7 @@ public class JavaDescriptorResolver {
|
||||
|
||||
String propertyName = entry.getKey();
|
||||
|
||||
resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, propertyName);
|
||||
resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, propertyName, "class or namespace " + psiClass.getQualifiedName());
|
||||
descriptors.addAll(namedMembers.propertyDescriptors);
|
||||
}
|
||||
|
||||
@@ -1060,7 +1081,9 @@ public class JavaDescriptorResolver {
|
||||
private void resolveNamedGroupProperties(
|
||||
@NotNull ClassOrNamespaceDescriptor owner,
|
||||
@NotNull ResolverScopeData scopeData,
|
||||
boolean staticMembers, NamedMembers namedMembers, String propertyName) {
|
||||
boolean staticMembers, @NotNull NamedMembers namedMembers, @NotNull String propertyName,
|
||||
@NotNull String context
|
||||
) {
|
||||
if (namedMembers.propertyDescriptors != null) {
|
||||
return;
|
||||
}
|
||||
@@ -1070,9 +1093,7 @@ public class JavaDescriptorResolver {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<TypeParameterDescriptor> classTypeParameterDescriptorInitialization = scopeData.getTypeParameters();
|
||||
|
||||
TypeVariableResolver typeVariableResolver = new TypeVariableResolverFromTypeDescriptors(scopeData.getTypeParameters(), null);
|
||||
TypeVariableResolver typeVariableResolver = TypeVariableResolvers.classTypeVariableResolver(owner, context);
|
||||
|
||||
class GroupingValue {
|
||||
PropertyAccessorData getter;
|
||||
@@ -1186,32 +1207,24 @@ public class JavaDescriptorResolver {
|
||||
|
||||
propertyDescriptor.initialize(getterDescriptor, setterDescriptor);
|
||||
|
||||
List<TypeParameterDescriptor> typeParametersInitialization = new ArrayList<TypeParameterDescriptor>(0);
|
||||
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(0);
|
||||
|
||||
if (members.setter != null) {
|
||||
PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember();
|
||||
|
||||
if (anyMember == members.setter) {
|
||||
typeParametersInitialization = resolveMethodTypeParameters(method, setterDescriptor, typeVariableResolver);
|
||||
typeParameters = resolveMethodTypeParameters(method, propertyDescriptor, typeVariableResolver);
|
||||
}
|
||||
}
|
||||
if (members.getter != null) {
|
||||
PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember();
|
||||
|
||||
if (anyMember == members.getter) {
|
||||
typeParametersInitialization = resolveMethodTypeParameters(method, getterDescriptor, typeVariableResolver);
|
||||
typeParameters = resolveMethodTypeParameters(method, propertyDescriptor, typeVariableResolver);
|
||||
}
|
||||
}
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>();
|
||||
for (TypeParameterDescriptor typeParameter : typeParametersInitialization) {
|
||||
typeParameters.add(typeParameter);
|
||||
}
|
||||
|
||||
List<TypeParameterDescriptor> typeParametersForReceiver = new ArrayList<TypeParameterDescriptor>();
|
||||
typeParametersForReceiver.addAll(classTypeParameterDescriptorInitialization);
|
||||
typeParametersForReceiver.addAll(typeParametersInitialization);
|
||||
TypeVariableResolver typeVariableResolverForPropertyInternals = new TypeVariableResolverFromTypeDescriptors(typeParametersForReceiver, null);
|
||||
TypeVariableResolver typeVariableResolverForPropertyInternals = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, propertyDescriptor, "property " + propertyName + " in " + context);
|
||||
|
||||
JetType propertyType;
|
||||
if (anyMember.getType().getTypeString().length() > 0) {
|
||||
@@ -1438,11 +1451,13 @@ public class JavaDescriptorResolver {
|
||||
CallableMemberDescriptor.Kind.DECLARATION
|
||||
);
|
||||
|
||||
final TypeVariableResolver typeVariableResolverForParameters = TypeVariableResolvers.classTypeVariableResolver(classDescriptor);
|
||||
String context = "method " + method.getName() + " in class " + psiClass.getQualifiedName();
|
||||
|
||||
final TypeVariableResolver typeVariableResolverForParameters = TypeVariableResolvers.classTypeVariableResolver(classDescriptor, context);
|
||||
|
||||
final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters);
|
||||
|
||||
TypeVariableResolver methodTypeVariableResolver = new TypeVariableResolverFromTypeDescriptors(methodTypeParameters, typeVariableResolverForParameters);
|
||||
TypeVariableResolver methodTypeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(methodTypeParameters, functionDescriptorImpl, context);
|
||||
|
||||
|
||||
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver);
|
||||
@@ -1544,12 +1559,13 @@ public class JavaDescriptorResolver {
|
||||
List<TypeParameterDescriptorInitialization> typeParametersIntialization;
|
||||
if (method.getJetMethod().typeParameters().length() > 0) {
|
||||
typeParametersIntialization = resolveMethodTypeParametersFromJetSignature(
|
||||
method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver);
|
||||
method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor);
|
||||
} else {
|
||||
typeParametersIntialization = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters());
|
||||
}
|
||||
|
||||
initializeTypeParameters(typeParametersIntialization, classTypeVariableResolver);
|
||||
String context = "method " + method.getName() + " in class " + method.getPsiMethod().getContainingClass().getQualifiedName();
|
||||
initializeTypeParameters(typeParametersIntialization, functionDescriptor, context);
|
||||
|
||||
List<TypeParameterDescriptor> typeParameters = Lists.newArrayListWithCapacity(typeParametersIntialization.size());
|
||||
|
||||
@@ -1561,12 +1577,13 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, org.jetbrains.jet.lang.descriptors.ClassDescriptor, TypeVariableResolver)
|
||||
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, org.jetbrains.jet.lang.descriptors.ClassDescriptor)
|
||||
*/
|
||||
private List<TypeParameterDescriptorInitialization> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method,
|
||||
final DeclarationDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver)
|
||||
private List<TypeParameterDescriptorInitialization> resolveMethodTypeParametersFromJetSignature(String jetSignature,
|
||||
final PsiMethod method, final DeclarationDescriptor functionDescriptor)
|
||||
{
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(classTypeVariableResolver, functionDescriptor, method);
|
||||
String context = "method " + method.getName() + " in class " + method.getContainingClass().getQualifiedName();
|
||||
JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(functionDescriptor, method, context);
|
||||
new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(jetSignatureTypeParametersVisitor);
|
||||
return jetSignatureTypeParametersVisitor.r;
|
||||
}
|
||||
|
||||
+4
-1
@@ -83,7 +83,10 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
|
||||
|
||||
@Override
|
||||
public void visitClassType(String name, boolean nullable, boolean forceReal) {
|
||||
String ourName = name.replace('/', '.');
|
||||
String ourName = name
|
||||
.replace('/', '.')
|
||||
.replace('$', '.') // TODO: not sure
|
||||
;
|
||||
|
||||
this.classDescriptor = null;
|
||||
if (this.classDescriptor == null && !forceReal) {
|
||||
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class TypeVariableResolverFromOuters implements TypeVariableResolver {
|
||||
|
||||
@NotNull
|
||||
private final DeclarationDescriptor outer;
|
||||
|
||||
public TypeVariableResolverFromOuters(@NotNull DeclarationDescriptor outer) {
|
||||
this.outer = outer;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
|
||||
DeclarationDescriptor outer = this.outer;
|
||||
for (;;) {
|
||||
if (outer instanceof NamespaceDescriptor) {
|
||||
throw new IllegalStateException("unresolve type parameter: " + name);
|
||||
} else if (outer instanceof ClassDescriptor) {
|
||||
for (TypeParameterDescriptor typeParameter : ((ClassDescriptor) outer).getTypeConstructor().getParameters()) {
|
||||
if (typeParameter.getName().equals(name)) {
|
||||
return typeParameter;
|
||||
}
|
||||
}
|
||||
outer = outer.getContainingDeclaration();
|
||||
} else {
|
||||
throw new IllegalStateException("unknown outer: " + outer.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
-7
@@ -18,6 +18,8 @@ package org.jetbrains.jet.lang.resolve.java;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
|
||||
import java.util.List;
|
||||
@@ -29,25 +31,52 @@ public class TypeVariableResolverFromTypeDescriptors implements TypeVariableReso
|
||||
|
||||
@NotNull
|
||||
private final List<TypeParameterDescriptor> typeParameters;
|
||||
@Nullable
|
||||
private final TypeVariableResolver parent;
|
||||
@NotNull
|
||||
private final DeclarationDescriptor typeParametersOwner;
|
||||
@NotNull
|
||||
private final String context;
|
||||
|
||||
public TypeVariableResolverFromTypeDescriptors(@NotNull List<TypeParameterDescriptor> typeParameters, @Nullable TypeVariableResolver parent) {
|
||||
public TypeVariableResolverFromTypeDescriptors(
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull DeclarationDescriptor owner,
|
||||
@NotNull String context) {
|
||||
this.typeParameters = typeParameters;
|
||||
this.parent = parent;
|
||||
this.typeParametersOwner = owner;
|
||||
this.context = context;
|
||||
|
||||
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
||||
if (typeParameter.getContainingDeclaration() != owner) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
|
||||
return getTypeVariable(name, typeParameters, typeParametersOwner, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TypeParameterDescriptor getTypeVariable(
|
||||
@NotNull String name,
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull DeclarationDescriptor owner,
|
||||
@NotNull String context) {
|
||||
for (TypeParameterDescriptor typeParameter : typeParameters) {
|
||||
if (typeParameter.getName().equals(name)) {
|
||||
return typeParameter;
|
||||
}
|
||||
}
|
||||
if (parent != null) {
|
||||
return parent.getTypeVariable(name);
|
||||
|
||||
DeclarationDescriptor containingDeclaration = owner.getContainingDeclaration();
|
||||
if (containingDeclaration != null) {
|
||||
return getTypeVariable(
|
||||
name,
|
||||
TypeVariableResolvers.getTypeParameterDescriptors((ClassOrNamespaceDescriptor) containingDeclaration),
|
||||
containingDeclaration,
|
||||
context);
|
||||
}
|
||||
throw new RuntimeException("type parameter not found by name " + name); // TODO report properly
|
||||
throw new RuntimeException("type parameter not found by name '" + name + "' in " + context);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-3
@@ -16,23 +16,41 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
|
||||
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.descriptors.TypeParameterDescriptor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class TypeVariableResolvers {
|
||||
|
||||
public static TypeVariableResolver classTypeVariableResolver(ClassOrNamespaceDescriptor clazz) {
|
||||
@NotNull
|
||||
public static List<TypeParameterDescriptor> getTypeParameterDescriptors(@NotNull ClassOrNamespaceDescriptor clazz) {
|
||||
if (clazz instanceof ClassDescriptor) {
|
||||
return new TypeVariableResolverFromTypeDescriptors(((ClassDescriptor) clazz).getTypeConstructor().getParameters(), new TypeVariableResolverFromOuters(clazz.getContainingDeclaration()));
|
||||
return ((ClassDescriptor) clazz).getTypeConstructor().getParameters();
|
||||
} else {
|
||||
return new TypeVariableResolverFromTypeDescriptors(new ArrayList<TypeParameterDescriptor>(0), null);
|
||||
return new ArrayList<TypeParameterDescriptor>(0);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TypeVariableResolver classTypeVariableResolver(@NotNull ClassOrNamespaceDescriptor clazz, @NotNull String context) {
|
||||
return typeVariableResolverFromTypeParameters(getTypeParameterDescriptors(clazz), clazz, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TypeVariableResolver typeVariableResolverFromTypeParameters(
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull DeclarationDescriptor owner, @NotNull String context) {
|
||||
|
||||
return new TypeVariableResolverFromTypeDescriptors(typeParameters, owner, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Collections;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ModuleDescriptor extends DeclarationDescriptorImpl {
|
||||
public class ModuleDescriptor extends DeclarationDescriptorImpl implements ClassOrNamespaceDescriptor {
|
||||
public ModuleDescriptor(String name) {
|
||||
super(null, Collections.<AnnotationDescriptor>emptyList(), name);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder {
|
||||
.between(IMPORT_DIRECTIVE, CLASS).blankLines(1)
|
||||
.between(IMPORT_DIRECTIVE, FUN).blankLines(1)
|
||||
.between(IMPORT_DIRECTIVE, PROPERTY).blankLines(1)
|
||||
.between(IMPORT_DIRECTIVE, OBJECT_DECLARATION).blankLines(1)
|
||||
|
||||
.before(FUN).lineBreakInCode()
|
||||
.before(PROPERTY).lineBreakInCode()
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
object some {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import java.util.HashSet
|
||||
|
||||
object some {
|
||||
}
|
||||
@@ -28,26 +28,19 @@ import java.io.IOException;
|
||||
*/
|
||||
public class ImportClassHelperTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testDoNotImportIfGeneralExist() {
|
||||
configureByFile(getTestName(false) + ".kt");
|
||||
ImportClassHelper.addImportDirective("jettesting.data.testFunction", (JetFile) getFile());
|
||||
checkResultByFile(getTestName(false) + ".kt.after");
|
||||
testImportInFile("jettesting.data.testFunction");
|
||||
}
|
||||
|
||||
public void testDoNotImportIfGeneralSpaceExist() {
|
||||
configureByFile(getTestName(false) + ".kt");
|
||||
ImportClassHelper.addImportDirective("jettesting.data.testFunction", (JetFile) getFile());
|
||||
checkResultByFile(getTestName(false) + ".kt.after");
|
||||
testImportInFile("jettesting.data.testFunction");
|
||||
}
|
||||
|
||||
public void testNoDefaultImport() {
|
||||
configureByFile(getTestName(false) + ".kt");
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ImportClassHelper.addImportDirective("std.io.println", (JetFile) getFile());
|
||||
}
|
||||
});
|
||||
checkResultByFile(getTestName(false) + ".kt.after");
|
||||
testImportInFile("std.io.println");
|
||||
}
|
||||
|
||||
public void testImportBeforeObject() {
|
||||
testImportInFile("java.util.HashSet");
|
||||
}
|
||||
|
||||
public void testInsertInEmptyFile() throws IOException {
|
||||
@@ -74,6 +67,17 @@ public class ImportClassHelperTest extends LightDaemonAnalyzerTestCase {
|
||||
checkResultByText("package some\n\nimport java.util.ArrayList");
|
||||
}
|
||||
|
||||
public void testImportInFile(final String importString) {
|
||||
configureByFile(getTestName(false) + ".kt");
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ImportClassHelper.addImportDirective(importString, (JetFile) getFile());
|
||||
}
|
||||
});
|
||||
checkResultByFile(getTestName(false) + ".kt.after");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return PluginTestCaseBase.getTestDataPathBase() + "/quickfix/importHelper/";
|
||||
|
||||
@@ -65,7 +65,7 @@ inline fun <T> expect(expected: T, message: String, block: ()-> T) {
|
||||
}
|
||||
|
||||
/** Asserts that given function block fails by throwing an exception */
|
||||
fun fails(block: ()-> Any): Exception? {
|
||||
fun fails(block: ()-> Unit): Exception? {
|
||||
try {
|
||||
block()
|
||||
Assert.fail("Expected an exception to be thrown")
|
||||
@@ -77,7 +77,7 @@ fun fails(block: ()-> Any): Exception? {
|
||||
}
|
||||
|
||||
/** Asserts that a block fails with a specific exception being thrown */
|
||||
fun <T: Exception> failsWith(block: ()-> Any) {
|
||||
fun <T: Exception> failsWith(block: ()-> Unit) {
|
||||
try {
|
||||
block()
|
||||
Assert.fail("Expected an exception to be thrown")
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package stdlib.testall;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
import test.collections.*;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class CollectionTestAllTest {
|
||||
public static TestSuite suite() {
|
||||
return new TestSuite(CollectionTest.class, MapTest.class);
|
||||
}
|
||||
}
|
||||
@@ -104,3 +104,5 @@ inline fun ByteArray.inputStream(offset: Int, length: Int) = ByteArrayInputStrea
|
||||
/** Returns true if the array is not empty */
|
||||
inline fun <T> Array<T>.notEmpty() : Boolean = this.size > 0
|
||||
|
||||
/** Returns true if the array is empty */
|
||||
inline fun <T> Array<T>.isEmpty() : Boolean = this.size == 0
|
||||
|
||||
@@ -8,17 +8,6 @@ Filters given iterator
|
||||
*/
|
||||
inline fun <T> java.util.Iterator<T>.filter(f: (T)-> Boolean) : java.util.Iterator<T> = FilterIterator<T>(this, f)
|
||||
|
||||
/*
|
||||
Adds filtered elements in to given container
|
||||
*/
|
||||
inline fun <T,U : Collection<in T>> java.lang.Iterable<T>.filterTo(var container: U, filter: (T)->Boolean) : U {
|
||||
for(element in this) {
|
||||
if(filter(element))
|
||||
container.add(element)
|
||||
}
|
||||
return container
|
||||
}
|
||||
|
||||
/*
|
||||
Create iterator filtering given java.lang.Iterable
|
||||
*/
|
||||
|
||||
@@ -2,16 +2,14 @@ package std.util
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new collection containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> java.util.Collection<T>.map(result: Collection<R> = ArrayList<R>(this.size), transform : (T) -> R) : Collection<R> {
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> java.util.Collection<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(this.size), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> java.util.Collection<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
}
|
||||
|
||||
/** Returns true if the collection is not empty */
|
||||
inline fun <T> java.util.Collection<T>.notEmpty() : Boolean = !this.isEmpty()
|
||||
|
||||
/** Converts the nullable collection into an empty collection if its null */
|
||||
inline fun <T> java.util.Collection<T>?.notNull() : Collection<T>
|
||||
= if (this != null) this else Collections.EMPTY_LIST as Collection<T>
|
||||
|
||||
@@ -41,8 +41,11 @@ inline fun <T> java.lang.Iterable<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.filter(result: Collection<T> = ArrayList<T>(), predicate: (T)-> Boolean) : Collection<T> {
|
||||
/** Returns a new List containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.filter(predicate: (T)-> Boolean) : Collection<T> = filterTo(java.util.ArrayList<T>(), predicate)
|
||||
|
||||
/** Filters all elements in this collection which match the given predicate into the given result collection */
|
||||
inline fun <T, C: Collection<in T>> java.lang.Iterable<T>.filterTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
result.add(elem)
|
||||
@@ -51,7 +54,10 @@ inline fun <T> java.lang.Iterable<T>.filter(result: Collection<T> = ArrayList<T>
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T> java.lang.Iterable<T>.filterNot(result: Collection<T> = ArrayList<T>(), predicate: (T)-> Boolean) : Collection<T> {
|
||||
inline fun <T> java.lang.Iterable<T>.filterNot(predicate: (T)-> Boolean) : Collection<T> = filterNotTo(ArrayList<T>(), predicate)
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T, C: Collection<in T>> java.lang.Iterable<T>.filterNotTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem))
|
||||
result.add(elem)
|
||||
|
||||
@@ -96,4 +96,10 @@ val <T> List<T>.last : T?
|
||||
get() = this.tail
|
||||
|
||||
|
||||
/** Returns true if the collection is not empty */
|
||||
inline fun <T> java.util.Collection<T>.notEmpty() : Boolean = !this.isEmpty()
|
||||
|
||||
/** Converts the nullable collection into an empty collection if its null */
|
||||
inline fun <T> java.util.Collection<T>?.notNull() : Collection<T>
|
||||
= if (this != null) this else Collections.EMPTY_LIST as Collection<T>
|
||||
|
||||
|
||||
+74
-7
@@ -65,22 +65,89 @@ set(value) {
|
||||
this.setAttribute("style", value)
|
||||
}
|
||||
|
||||
// TODO can we come up with a better name; 'class' is a reserved word?
|
||||
var Element.cssClass : String
|
||||
var Element.classes : String
|
||||
get() = this.getAttribute("class")?: ""
|
||||
set(value) {
|
||||
this.setAttribute("class", value)
|
||||
}
|
||||
|
||||
var Element.classSet : Set<String>
|
||||
get() {
|
||||
val answer = LinkedHashSet<String>()
|
||||
val array = this.classes.split("""\s""")
|
||||
for (s in array) {
|
||||
if (s != null && s.size > 0) {
|
||||
answer.add(s)
|
||||
}
|
||||
}
|
||||
return answer
|
||||
}
|
||||
set(value) {
|
||||
this.classes = value.join(" ")
|
||||
}
|
||||
|
||||
|
||||
// Helper methods
|
||||
|
||||
/** Returns true if the element has the given CSS class style in its 'class' attribute */
|
||||
fun Element.hasClass(cssClass: String): Boolean {
|
||||
val c = this.cssClass
|
||||
val c = this.classes
|
||||
return if (c != null)
|
||||
c.matches("""(^|\s+)$cssClass($|\s+)""")
|
||||
c.matches("""(^|.*\s+)$cssClass($|\s+.*)""")
|
||||
else false
|
||||
}
|
||||
|
||||
/** Adds the given CSS class to this element's 'class' attribute */
|
||||
fun Element.addClass(cssClass: String): Boolean {
|
||||
val classSet = this.classSet
|
||||
val answer = classSet.add(cssClass)
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Removes the given CSS class to this element's 'class' attribute */
|
||||
fun Element.removeClass(cssClass: String): Boolean {
|
||||
val classSet = this.classSet
|
||||
val answer = classSet.remove(cssClass)
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** TODO this approach generates compiler errors...
|
||||
|
||||
fun Element.addClass(varargs cssClasses: Array<String>): Boolean {
|
||||
val set = this.classSet
|
||||
var answer = false
|
||||
for (cs in cssClasses) {
|
||||
if (set.add(cs)) {
|
||||
answer = true
|
||||
}
|
||||
}
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
fun Element.removeClass(varargs cssClasses: Array<String>): Boolean {
|
||||
val set = this.classSet
|
||||
var answer = false
|
||||
for (cs in cssClasses) {
|
||||
if (set.remove(cs)) {
|
||||
answer = true
|
||||
}
|
||||
}
|
||||
if (answer) {
|
||||
this.classSet = classSet
|
||||
}
|
||||
return answer
|
||||
}
|
||||
*/
|
||||
|
||||
/** Searches for elements using the element name, an element ID (if prefixed with dot) or element class (if prefixed with #) */
|
||||
fun Document?.get(selector: String): List<Element> {
|
||||
val root = this?.getDocumentElement()
|
||||
@@ -123,9 +190,9 @@ fun Element.get(selector: String): List<Element> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the attribute value or null if its not present */
|
||||
inline fun Element?.attribute(name: String): String? {
|
||||
return this?.getAttribute(name)
|
||||
/** Returns the attribute value or empty string if its not present */
|
||||
inline fun Element.attribute(name: String): String {
|
||||
return this.getAttribute(name) ?: ""
|
||||
}
|
||||
|
||||
/** Returns the children of the element as a list */
|
||||
|
||||
@@ -3,8 +3,13 @@ package std
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new collection containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> Array<T>.map(result: Collection<R> = ArrayList<R>(this.size), transform : (T) -> R) : Collection<R> {
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> Array<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(this.size), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> Array<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// NOTE this file is auto-generated from stdlib/ktSrc/JavaIterables.kt
|
||||
package std
|
||||
|
||||
import std.util.*
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns true if any elements in the collection match the given predicate */
|
||||
@@ -23,6 +25,16 @@ inline fun <T> Array<T>.all(predicate: (T)-> Boolean) : Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
/** Returns the number of items which match the given predicate */
|
||||
inline fun <T> Array<T>.count(predicate: (T)-> Boolean) : Int {
|
||||
var answer = 0
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
answer += 1
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the first item in the collection which matches the given predicate or null if none matched */
|
||||
inline fun <T> Array<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
for (elem in this) {
|
||||
@@ -32,8 +44,11 @@ inline fun <T> Array<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> Array<T>.filter(result: Collection<T> = ArrayList<T>(), predicate: (T)-> Boolean) : Collection<T> {
|
||||
/** Returns a new List containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> Array<T>.filter(predicate: (T)-> Boolean) : Collection<T> = filterTo(java.util.ArrayList<T>(), predicate)
|
||||
|
||||
/** Filters all elements in this collection which match the given predicate into the given result collection */
|
||||
inline fun <T, C: Collection<in T>> Array<T>.filterTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
result.add(elem)
|
||||
@@ -42,7 +57,10 @@ inline fun <T> Array<T>.filter(result: Collection<T> = ArrayList<T>(), predicate
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T> Array<T>.filterNot(result: Collection<T> = ArrayList<T>(), predicate: (T)-> Boolean) : Collection<T> {
|
||||
inline fun <T> Array<T>.filterNot(predicate: (T)-> Boolean) : Collection<T> = filterNotTo(ArrayList<T>(), predicate)
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T, C: Collection<in T>> Array<T>.filterNotTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem))
|
||||
result.add(elem)
|
||||
@@ -72,6 +90,42 @@ inline fun <T> Array<T>.foreach(operation: (element: T) -> Unit) {
|
||||
operation(elem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from from left to right with the initial value to perform the operation on sequential pairs of values
|
||||
*
|
||||
* For example to sum together all numeric values in a collection of numbers it would be
|
||||
* {code}val total = numbers.fold(0){(a, b) -> a + b}{code}
|
||||
*/
|
||||
inline fun <T> Array<T>.fold(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
var answer = initial
|
||||
for (elem in this) {
|
||||
answer = operation(answer, elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from right to left with the initial value to perform the operation on sequential pairs of values
|
||||
*/
|
||||
inline fun <T> Array<T>.foldRight(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
val reversed = this.reverse()
|
||||
return reversed.fold(initial, operation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the collection performing the transformation on each element and using the result
|
||||
* as the key in a map to group elements by the result
|
||||
*/
|
||||
inline fun <T,K> Array<T>.groupBy(result: Map<K,List<T>> = HashMap<K,List<T>>(), toKey: (T)-> K) : Map<K,List<T>> {
|
||||
for (elem in this) {
|
||||
val key = toKey(elem)
|
||||
val list = result.getOrPut(key){ ArrayList<T>() }
|
||||
list.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */
|
||||
inline fun <T> Array<T>.join(separator: String, prefix: String = "", postfix: String = "") : String {
|
||||
val buffer = StringBuilder(prefix)
|
||||
@@ -87,18 +141,33 @@ inline fun <T> Array<T>.join(separator: String, prefix: String = "", postfix: St
|
||||
return buffer.toString().sure()
|
||||
}
|
||||
|
||||
/** Returns a reversed List of this collection */
|
||||
inline fun <T> Array<T>.reverse() : List<T> {
|
||||
val answer = LinkedList<T>()
|
||||
for (elem in this) {
|
||||
answer.addFirst(elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/* Copies the collection into the given collection */
|
||||
inline fun <T, C: Collection<T>> Array<T>.to(result: C) : C {
|
||||
for (elem in this)
|
||||
result.add(elem)
|
||||
return result
|
||||
}
|
||||
|
||||
/* Converts the collection into a LinkedList */
|
||||
inline fun <T> Array<T>.toLinkedList() : LinkedList<T> = this.to(LinkedList<T>())
|
||||
|
||||
/* Converts the collection into a List */
|
||||
inline fun <T> Array<T>.toList() : List<T> = this.to(ArrayList<T>())
|
||||
|
||||
/* Converts the collection into a Set */
|
||||
inline fun <T> Array<T>.toSet() : Set<T> = this.to(HashSet<T>())
|
||||
|
||||
/* Converts the collection into a SortedSet */
|
||||
inline fun <T> Array<T>.toSortedSet() : SortedSet<T> = this.to(TreeSet<T>())
|
||||
/**
|
||||
TODO figure out necessary variance/generics ninja stuff... :)
|
||||
inline fun <in T> Array<T>.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||
|
||||
@@ -3,8 +3,13 @@ package std.util
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new collection containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> java.lang.Iterable<T>.map(result: Collection<R> = ArrayList<R>(), transform : (T) -> R) : Collection<R> {
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> java.lang.Iterable<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> java.lang.Iterable<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
|
||||
@@ -3,8 +3,13 @@ package std
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns a new collection containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> Iterable<T>.map(result: Collection<R> = ArrayList<R>(), transform : (T) -> R) : Collection<R> {
|
||||
/** Returns a new List containing the results of applying the given function to each element in this collection */
|
||||
inline fun <T, R> Iterable<T>.map(transform : (T) -> R) : java.util.List<R> {
|
||||
return mapTo(java.util.ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/** Transforms each element of this collection with the given function then adds the results to the given collection */
|
||||
inline fun <T, R, C: Collection<in R>> Iterable<T>.mapTo(result: C, transform : (T) -> R) : C {
|
||||
for (item in this)
|
||||
result.add(transform(item))
|
||||
return result
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// NOTE this file is auto-generated from stdlib/ktSrc/JavaIterables.kt
|
||||
package std
|
||||
|
||||
import std.util.*
|
||||
|
||||
import java.util.*
|
||||
|
||||
/** Returns true if any elements in the collection match the given predicate */
|
||||
@@ -23,6 +25,16 @@ inline fun <T> Iterable<T>.all(predicate: (T)-> Boolean) : Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
/** Returns the number of items which match the given predicate */
|
||||
inline fun <T> Iterable<T>.count(predicate: (T)-> Boolean) : Int {
|
||||
var answer = 0
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
answer += 1
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/** Returns the first item in the collection which matches the given predicate or null if none matched */
|
||||
inline fun <T> Iterable<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
for (elem in this) {
|
||||
@@ -32,8 +44,11 @@ inline fun <T> Iterable<T>.find(predicate: (T)-> Boolean) : T? {
|
||||
return null
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> Iterable<T>.filter(result: Collection<T> = ArrayList<T>(), predicate: (T)-> Boolean) : Collection<T> {
|
||||
/** Returns a new List containing all elements in this collection which match the given predicate */
|
||||
inline fun <T> Iterable<T>.filter(predicate: (T)-> Boolean) : Collection<T> = filterTo(java.util.ArrayList<T>(), predicate)
|
||||
|
||||
/** Filters all elements in this collection which match the given predicate into the given result collection */
|
||||
inline fun <T, C: Collection<in T>> Iterable<T>.filterTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (predicate(elem))
|
||||
result.add(elem)
|
||||
@@ -42,7 +57,10 @@ inline fun <T> Iterable<T>.filter(result: Collection<T> = ArrayList<T>(), predic
|
||||
}
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T> Iterable<T>.filterNot(result: Collection<T> = ArrayList<T>(), predicate: (T)-> Boolean) : Collection<T> {
|
||||
inline fun <T> Iterable<T>.filterNot(predicate: (T)-> Boolean) : Collection<T> = filterNotTo(ArrayList<T>(), predicate)
|
||||
|
||||
/** Returns a new collection containing all elements in this collection which do not match the given predicate */
|
||||
inline fun <T, C: Collection<in T>> Iterable<T>.filterNotTo(result: C, predicate: (T)-> Boolean) : C {
|
||||
for (elem in this) {
|
||||
if (!predicate(elem))
|
||||
result.add(elem)
|
||||
@@ -72,6 +90,42 @@ inline fun <T> Iterable<T>.foreach(operation: (element: T) -> Unit) {
|
||||
operation(elem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from from left to right with the initial value to perform the operation on sequential pairs of values
|
||||
*
|
||||
* For example to sum together all numeric values in a collection of numbers it would be
|
||||
* {code}val total = numbers.fold(0){(a, b) -> a + b}{code}
|
||||
*/
|
||||
inline fun <T> Iterable<T>.fold(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
var answer = initial
|
||||
for (elem in this) {
|
||||
answer = operation(answer, elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds all the values from right to left with the initial value to perform the operation on sequential pairs of values
|
||||
*/
|
||||
inline fun <T> Iterable<T>.foldRight(initial: T, operation: (it: T, it2: T) -> T): T {
|
||||
val reversed = this.reverse()
|
||||
return reversed.fold(initial, operation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the collection performing the transformation on each element and using the result
|
||||
* as the key in a map to group elements by the result
|
||||
*/
|
||||
inline fun <T,K> Iterable<T>.groupBy(result: Map<K,List<T>> = HashMap<K,List<T>>(), toKey: (T)-> K) : Map<K,List<T>> {
|
||||
for (elem in this) {
|
||||
val key = toKey(elem)
|
||||
val list = result.getOrPut(key){ ArrayList<T>() }
|
||||
list.add(elem)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/** Creates a String from all the elements in the collection, using the seperator between them and using the given prefix and postfix if supplied */
|
||||
inline fun <T> Iterable<T>.join(separator: String, prefix: String = "", postfix: String = "") : String {
|
||||
val buffer = StringBuilder(prefix)
|
||||
@@ -87,18 +141,33 @@ inline fun <T> Iterable<T>.join(separator: String, prefix: String = "", postfix:
|
||||
return buffer.toString().sure()
|
||||
}
|
||||
|
||||
/** Returns a reversed List of this collection */
|
||||
inline fun <T> Iterable<T>.reverse() : List<T> {
|
||||
val answer = LinkedList<T>()
|
||||
for (elem in this) {
|
||||
answer.addFirst(elem)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
|
||||
/* Copies the collection into the given collection */
|
||||
inline fun <T, C: Collection<T>> Iterable<T>.to(result: C) : C {
|
||||
for (elem in this)
|
||||
result.add(elem)
|
||||
return result
|
||||
}
|
||||
|
||||
/* Converts the collection into a LinkedList */
|
||||
inline fun <T> Iterable<T>.toLinkedList() : LinkedList<T> = this.to(LinkedList<T>())
|
||||
|
||||
/* Converts the collection into a List */
|
||||
inline fun <T> Iterable<T>.toList() : List<T> = this.to(ArrayList<T>())
|
||||
|
||||
/* Converts the collection into a Set */
|
||||
inline fun <T> Iterable<T>.toSet() : Set<T> = this.to(HashSet<T>())
|
||||
|
||||
/* Converts the collection into a SortedSet */
|
||||
inline fun <T> Iterable<T>.toSortedSet() : SortedSet<T> = this.to(TreeSet<T>())
|
||||
/**
|
||||
TODO figure out necessary variance/generics ninja stuff... :)
|
||||
inline fun <in T> Iterable<T>.toSortedList(transform: fun(T) : java.lang.Comparable<*>) : List<T> {
|
||||
|
||||
@@ -67,7 +67,7 @@ class CollectionTest() : TestSupport() {
|
||||
|
||||
fun testFilterIntoLinkedList() {
|
||||
// TODO would be nice to avoid the <String>
|
||||
val foo = data.filter(linkedList<String>()){it.startsWith("f")}
|
||||
val foo = data.filterTo(linkedList<String>()){it.startsWith("f")}
|
||||
|
||||
assertTrue {
|
||||
foo.all{it.startsWith("f")}
|
||||
@@ -82,7 +82,7 @@ class CollectionTest() : TestSupport() {
|
||||
|
||||
fun testFilterIntoSortedSet() {
|
||||
// TODO would be nice to avoid the <String>
|
||||
val foo = data.filter(hashSet<String>()){it.startsWith("f")}
|
||||
val foo = data.filterTo(hashSet<String>()){it.startsWith("f")}
|
||||
|
||||
assertTrue {
|
||||
foo.all{it.startsWith("f")}
|
||||
@@ -246,6 +246,29 @@ class CollectionTest() : TestSupport() {
|
||||
fails { hashSet<Char>().last() }
|
||||
}
|
||||
|
||||
fun testSubscript() {
|
||||
val list = arrayList("foo", "bar")
|
||||
assertEquals("foo", list[0])
|
||||
assertEquals("bar", list[1])
|
||||
|
||||
// lists throw an exception if out of range
|
||||
fails {
|
||||
assertEquals(null, list[2])
|
||||
}
|
||||
|
||||
// lets try update the list
|
||||
list[0] = "new"
|
||||
list[1] = "thing"
|
||||
|
||||
// lists don't allow you to set past the end of the list
|
||||
fails {
|
||||
list[2] = "works"
|
||||
}
|
||||
|
||||
list.add("works")
|
||||
assertEquals(arrayList("new", "thing", "works"), list)
|
||||
}
|
||||
|
||||
fun testIndices() {
|
||||
val indices = data.indices
|
||||
assertEquals(0, indices.start)
|
||||
|
||||
@@ -58,11 +58,11 @@ fun main(args: Array<String>) {
|
||||
|
||||
|
||||
// JavaIterables - Generic iterable stuff
|
||||
generateFile(File(outDir, "ArraysFromJavaIterables.kt"), "package std", File(srcDir, "JavaIterables.kt")) {
|
||||
generateFile(File(outDir, "ArraysFromJavaIterables.kt"), "package std\n\nimport std.util.*", File(srcDir, "JavaIterables.kt")) {
|
||||
it.replaceAll("java.lang.Iterable<T>", "Array<T>")
|
||||
}
|
||||
|
||||
generateFile(File(outDir, "StandardFromJavaIterables.kt"), "package std", File(srcDir, "JavaIterables.kt")) {
|
||||
generateFile(File(outDir, "StandardFromJavaIterables.kt"), "package std\n\nimport std.util.*", File(srcDir, "JavaIterables.kt")) {
|
||||
it.replaceAll("java.lang.Iterable<T>", "Iterable<T>")
|
||||
}
|
||||
|
||||
|
||||
@@ -39,14 +39,12 @@ class MapTest() : TestSupport() {
|
||||
fun testSetViaIndexOperators() {
|
||||
val map = java.util.HashMap<String, String>()
|
||||
assertTrue{ map.empty }
|
||||
// TODO cannot use map.size due to compiler bug
|
||||
assertEquals(map.size(), 0)
|
||||
assertEquals(map.size, 0)
|
||||
|
||||
map["name"] = "James"
|
||||
|
||||
assertTrue{ !map.empty }
|
||||
// TODO cannot use map.size due to compiler bug
|
||||
assertEquals(map.size(), 1)
|
||||
assertEquals(map.size, 1)
|
||||
assertEquals("James", map["name"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.w3c.dom.*
|
||||
|
||||
class DomBuilderTest() : TestSupport() {
|
||||
|
||||
|
||||
fun testBuildDocument() {
|
||||
var doc = createDocument()
|
||||
|
||||
@@ -18,13 +19,20 @@ class DomBuilderTest() : TestSupport() {
|
||||
doc.addElement("foo") {
|
||||
id = "id1"
|
||||
style = "bold"
|
||||
cssClass = "bar"
|
||||
classes = "bar"
|
||||
addElement("child") {
|
||||
id = "id2"
|
||||
cssClass = "another"
|
||||
classes = "another"
|
||||
addElement("grandChild") {
|
||||
id = "id3"
|
||||
cssClass = "tiny"
|
||||
classes = " bar tiny"
|
||||
addText("Hello World!")
|
||||
// TODO support neater syntax sugar for adding text?
|
||||
// += "Hello World!"
|
||||
}
|
||||
addElement("grandChild2") {
|
||||
id = "id3"
|
||||
classes = "tiny thing bar "
|
||||
addText("Hello World!")
|
||||
// TODO support neater syntax sugar for adding text?
|
||||
// += "Hello World!"
|
||||
@@ -37,8 +45,8 @@ class DomBuilderTest() : TestSupport() {
|
||||
// test css selections on document
|
||||
assertEquals(0, doc[".doesNotExist"].size())
|
||||
assertEquals(1, doc[".another"].size())
|
||||
assertEquals(1, doc[".tiny"].size())
|
||||
assertEquals(1, doc[".bar"].size())
|
||||
assertEquals(3, doc[".bar"].size())
|
||||
assertEquals(2, doc[".tiny"].size())
|
||||
|
||||
// element tag selections
|
||||
assertEquals(0, doc["doesNotExist"].size())
|
||||
@@ -60,8 +68,8 @@ class DomBuilderTest() : TestSupport() {
|
||||
// test css selections on element
|
||||
assertEquals(0, root[".doesNotExist"].size())
|
||||
assertEquals(1, root[".another"].size())
|
||||
assertEquals(1, root[".tiny"].size())
|
||||
assertEquals(0, root[".bar"].size())
|
||||
assertEquals(2, root[".bar"].size())
|
||||
assertEquals(2, root[".tiny"].size())
|
||||
|
||||
// element tag selections
|
||||
assertEquals(0, root["doesNotExist"].size())
|
||||
@@ -77,12 +85,32 @@ class DomBuilderTest() : TestSupport() {
|
||||
fail("No root!")
|
||||
}
|
||||
|
||||
|
||||
val grandChild = doc["grandChild"].first
|
||||
if (grandChild != null) {
|
||||
println("got element ${grandChild.toXmlString()} with text '${grandChild.text}`")
|
||||
assertEquals("Hello World!", grandChild.text)
|
||||
assertEquals("tiny", grandChild.attribute("class") ?: "")
|
||||
assertEquals(" bar tiny", grandChild.attribute("class"))
|
||||
|
||||
// test the classSet
|
||||
val classSet = grandChild.classSet
|
||||
|
||||
assertTrue(classSet.contains("bar"))
|
||||
assertTrue(classSet.contains("tiny"))
|
||||
assertTrue(classSet.size == 2 )
|
||||
assertFalse(classSet.contains("doesNotExist"))
|
||||
|
||||
// lets add a new class and some existing classes
|
||||
grandChild.addClass("bar")
|
||||
grandChild.addClass("newThingy")
|
||||
assertEquals("bar tiny newThingy", grandChild.classes)
|
||||
|
||||
// remove
|
||||
grandChild.removeClass("bar")
|
||||
assertEquals("tiny newThingy", grandChild.classes)
|
||||
|
||||
grandChild.removeClass("tiny")
|
||||
assertEquals("newThingy", grandChild.classes)
|
||||
|
||||
} else {
|
||||
fail("Not an Element $grandChild")
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class DomTest() : TestSupport() {
|
||||
assertCssClass(e, "")
|
||||
|
||||
// now lets update the cssClass property
|
||||
e.cssClass = "foo"
|
||||
e.classes = "foo"
|
||||
assertCssClass(e, "foo")
|
||||
|
||||
// now using the attribute directly
|
||||
@@ -28,7 +28,7 @@ class DomTest() : TestSupport() {
|
||||
|
||||
|
||||
fun assertCssClass(e: Element, value: String?): Unit {
|
||||
val cl = e.cssClass
|
||||
val cl = e.classes
|
||||
val cl2 = e.getAttribute("class")
|
||||
println("element ${e.toXmlString()} has cssClass `${cl}` class attr `${cl2}`")
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ import junit.framework.*
|
||||
import java.util.*
|
||||
|
||||
public fun scheduleRefresh(vararg files : Object) {
|
||||
java.util.ArrayList<Object>(files.map{ it })
|
||||
// TODO
|
||||
// java.util.ArrayList<Object>(files.map{ it })
|
||||
}
|
||||
|
||||
fun main(args : Array<String?>?) {
|
||||
|
||||
Reference in New Issue
Block a user