rewrite of closure capturing for object literals
This commit is contained in:
@@ -98,7 +98,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
captureThis = generateBody(funDescriptor, cv, fun.getFunctionLiteral());
|
||||
ClassDescriptor thisDescriptor = context.getThisDescriptor();
|
||||
final Type enclosingType = thisDescriptor == null ? null : Type.getObjectType(thisDescriptor.getName());
|
||||
if (enclosingType == null) captureThis = false;
|
||||
if (enclosingType == null)
|
||||
captureThis = false;
|
||||
|
||||
final Method constructor = generateConstructor(funClass, fun);
|
||||
|
||||
@@ -208,14 +209,14 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
|
||||
private Method generateConstructor(String funClass, JetFunctionLiteralExpression fun) {
|
||||
int argCount = captureThis ? 1 : 0;
|
||||
argCount += (captureReceiver != null ? 1 : 0);
|
||||
|
||||
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
||||
if(descriptor instanceof VariableDescriptor) {
|
||||
if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
||||
argCount++;
|
||||
}
|
||||
else if(descriptor instanceof FunctionDescriptor) {
|
||||
captureReceiver = state.getTypeMapper().mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType());
|
||||
argCount++;
|
||||
assert captureReceiver != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,8 +232,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
||||
if(descriptor instanceof VariableDescriptor) {
|
||||
final Type sharedVarType = exprContext.getSharedVarType(descriptor);
|
||||
if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
||||
final Type sharedVarType = exprContext.getTypeMapper().getSharedVarType(descriptor);
|
||||
final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
||||
argTypes[i++] = type;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@ public abstract class CodegenContext {
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
|
||||
@@ -244,6 +249,8 @@ public abstract class CodegenContext {
|
||||
return getThisDescriptor() != null ? StackValue.local(1, asmType) : StackValue.local(0, asmType);
|
||||
}
|
||||
|
||||
public abstract boolean isStatic();
|
||||
|
||||
public abstract static class ReceiverContext extends CodegenContext {
|
||||
final CallableDescriptor receiverDescriptor;
|
||||
|
||||
@@ -276,6 +283,11 @@ public abstract class CodegenContext {
|
||||
return getParentContext().enclosingClassType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return getParentContext().isStatic();
|
||||
}
|
||||
|
||||
protected StackValue getOuterExpression(StackValue prefix) {
|
||||
return getParentContext().getOuterExpression(prefix);
|
||||
}
|
||||
@@ -310,6 +322,11 @@ public abstract class CodegenContext {
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return (ClassDescriptor) getContextDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AnonymousClassContext extends CodegenContext {
|
||||
@@ -326,6 +343,11 @@ public abstract class CodegenContext {
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return (ClassDescriptor) getContextDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClosureContext extends ReceiverContext {
|
||||
@@ -350,6 +372,11 @@ public abstract class CodegenContext {
|
||||
public DeclarationDescriptor getContextDescriptor() {
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NamespaceContext extends CodegenContext {
|
||||
@@ -361,5 +388,10 @@ public abstract class CodegenContext {
|
||||
protected ClassDescriptor getThisDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,9 @@ public class CodegenUtil {
|
||||
}
|
||||
|
||||
public static boolean hasTypeInfoField(JetType type) {
|
||||
if(isInterface(type))
|
||||
return false;
|
||||
|
||||
List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
|
||||
for (TypeParameterDescriptor parameter : parameters) {
|
||||
if(parameter.isReified())
|
||||
|
||||
@@ -81,7 +81,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
this.intrinsics = state.getIntrinsics();
|
||||
}
|
||||
|
||||
StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDescriptor provided, ClassDescriptor required) {
|
||||
StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDescriptor provided, @Nullable ClassDescriptor required) {
|
||||
if(required == null)
|
||||
return inner;
|
||||
|
||||
@@ -640,13 +640,19 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
v.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor descriptor : closureCodegen.closure.keySet()) {
|
||||
Type sharedVarType = getSharedVarType(descriptor);
|
||||
if(sharedVarType == null)
|
||||
sharedVarType = state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
||||
consArgTypes.add(sharedVarType);
|
||||
final EnclosedValueDescriptor valueDescriptor = closureCodegen.closure.get(descriptor);
|
||||
valueDescriptor.getOuterValue().put(sharedVarType, v);
|
||||
if(closureCodegen.captureReceiver != null) {
|
||||
v.load(context.isStatic() ? 0 : 1, closureCodegen.captureReceiver);
|
||||
consArgTypes.add(closureCodegen.captureReceiver);
|
||||
}
|
||||
|
||||
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closureCodegen.closure.entrySet()) {
|
||||
if(entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) {
|
||||
Type sharedVarType = typeMapper.getSharedVarType(entry.getKey());
|
||||
if(sharedVarType == null)
|
||||
sharedVarType = state.getTypeMapper().mapType(((VariableDescriptor) entry.getKey()).getOutType());
|
||||
consArgTypes.add(sharedVarType);
|
||||
entry.getValue().getOuterValue().put(sharedVarType, v);
|
||||
}
|
||||
}
|
||||
|
||||
Method cons = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
|
||||
@@ -654,20 +660,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return StackValue.onStack(Type.getObjectType(closure.getClassname()));
|
||||
}
|
||||
|
||||
Type getSharedVarType(DeclarationDescriptor variableDescriptor) {
|
||||
if(!(variableDescriptor instanceof VariableDescriptor))
|
||||
return null;
|
||||
|
||||
Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) variableDescriptor);
|
||||
if (aBoolean != null && aBoolean) {
|
||||
JetType outType = ((VariableDescriptor) variableDescriptor).getOutType();
|
||||
return StackValue.sharedTypeForType(typeMapper.mapType(outType));
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateBlock(List<JetElement> statements) {
|
||||
Label blockStart = new Label();
|
||||
v.mark(blockStart);
|
||||
@@ -677,7 +669,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, statement);
|
||||
assert variableDescriptor != null;
|
||||
|
||||
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||
final Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
|
||||
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
|
||||
myFrameMap.enter(variableDescriptor, type.getSize());
|
||||
}
|
||||
@@ -705,7 +697,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
int index = myFrameMap.leave(variableDescriptor);
|
||||
|
||||
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||
final Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
|
||||
final Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType(variableDescriptor.getOutType());
|
||||
if(sharedVarType != null) {
|
||||
v.aconst(null);
|
||||
@@ -819,7 +811,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
else {
|
||||
int index = lookupLocal(descriptor);
|
||||
if (index >= 0) {
|
||||
Type sharedVarType = getSharedVarType(descriptor);
|
||||
Type sharedVarType = typeMapper.getSharedVarType(descriptor);
|
||||
final JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
||||
if(sharedVarType != null) {
|
||||
return StackValue.shared(index, typeMapper.mapType(outType));
|
||||
@@ -914,7 +906,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
||||
else {
|
||||
if(resolvedCall.getThisObject() instanceof ExtensionReceiver)
|
||||
receiver = generateReceiver(((ExtensionReceiver)resolvedCall.getThisObject()).getDeclarationDescriptor(), null);
|
||||
receiver = generateReceiver(((ExtensionReceiver)resolvedCall.getThisObject()).getDeclarationDescriptor());
|
||||
else
|
||||
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
||||
}
|
||||
@@ -992,6 +984,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
functionDescriptor = functionDescriptor.getOriginal();
|
||||
String owner;
|
||||
|
||||
IntrinsicMethod intrinsic = intrinsics.getIntrinsic(functionDescriptor);
|
||||
if(intrinsic != null) {
|
||||
intrinsic.generate(this, v, type, null, null, StackValue.onStack(JetTypeMapper.TYPE_OBJECT));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isInterface;
|
||||
boolean isInsideClass = containingDeclaration == context.getThisDescriptor();
|
||||
if (isInsideClass || isStatic) {
|
||||
@@ -1247,7 +1245,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
else if(descriptor instanceof ExtensionReceiver) {
|
||||
ExtensionReceiver extensionReceiver = (ExtensionReceiver) descriptor;
|
||||
generateReceiver(extensionReceiver.getDeclarationDescriptor(), null).put(typeMapper.mapType(descriptor.getType()), v);
|
||||
generateReceiver(extensionReceiver.getDeclarationDescriptor()).put(typeMapper.mapType(descriptor.getType()), v);
|
||||
}
|
||||
else if(descriptor instanceof ExpressionReceiver) {
|
||||
ExpressionReceiver expressionReceiver = (ExpressionReceiver) descriptor;
|
||||
@@ -1266,16 +1264,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private StackValue generateReceiver(DeclarationDescriptor provided, ClassDescriptor required) {
|
||||
private StackValue generateReceiver(DeclarationDescriptor provided) {
|
||||
assert context instanceof CodegenContext.ReceiverContext;
|
||||
CodegenContext.ReceiverContext cur = (CodegenContext.ReceiverContext) context;
|
||||
if (cur.getReceiverDescriptor() == provided) {
|
||||
StackValue result = cur.getReceiverExpression(typeMapper);
|
||||
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, required);
|
||||
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, null);
|
||||
}
|
||||
|
||||
StackValue result = context.lookupInContext(provided, v, StackValue.local(0, JetTypeMapper.TYPE_OBJECT));
|
||||
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, required);
|
||||
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, null);
|
||||
}
|
||||
|
||||
public StackValue generateThisOrOuter(ClassDescriptor calleeContainingClass) {
|
||||
@@ -1939,7 +1937,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
assert index >= 0;
|
||||
|
||||
final Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||
final Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
|
||||
assert variableDescriptor != null;
|
||||
Type varType = typeMapper.mapType(variableDescriptor.getOutType());
|
||||
if(sharedVarType != null) {
|
||||
@@ -2217,8 +2215,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return generateThisOrOuter((ClassDescriptor) descriptor);
|
||||
}
|
||||
else {
|
||||
if(descriptor instanceof FunctionDescriptor) {
|
||||
return generateReceiver(descriptor, null);
|
||||
if(descriptor instanceof FunctionDescriptor || descriptor instanceof PropertyDescriptor) {
|
||||
return generateReceiver(descriptor);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
else {
|
||||
for (ValueParameterDescriptor parameter : paramDescrs) {
|
||||
Type sharedVarType = codegen.getSharedVarType(parameter);
|
||||
Type sharedVarType = state.getTypeMapper().getSharedVarType(parameter);
|
||||
Type localVarType = state.getTypeMapper().mapType(parameter.getOutType());
|
||||
if (sharedVarType != null) {
|
||||
int index = frameMap.getIndex(parameter);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -39,43 +38,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private Set<String> getSuperInterfaces(JetClassOrObject aClass) {
|
||||
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
|
||||
String superClassName = null;
|
||||
Set<String> superInterfaces = new LinkedHashSet<String>();
|
||||
|
||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
PsiElement superPsi = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||
|
||||
if (superPsi instanceof PsiClass) {
|
||||
PsiClass psiClass = (PsiClass) superPsi;
|
||||
String fqn = psiClass.getQualifiedName();
|
||||
assert fqn != null;
|
||||
if (psiClass.isInterface()) {
|
||||
superInterfaces.add(fqn.replace('.', '/'));
|
||||
}
|
||||
else {
|
||||
if (superClassName == null) {
|
||||
superClassName = fqn.replace('.', '/');
|
||||
|
||||
while (psiClass != null) {
|
||||
for (PsiClass ifs : psiClass.getInterfaces()) {
|
||||
String qualifiedName = ifs.getQualifiedName();
|
||||
assert qualifiedName != null;
|
||||
superInterfaces.add(qualifiedName.replace('.', '/'));
|
||||
}
|
||||
psiClass = psiClass.getSuperClass();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException("Cannot determine single class to inherit from");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(superPsi == null || ((JetClass)superPsi).isTrait())
|
||||
superInterfaces.add(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName());
|
||||
if(CodegenUtil.isInterface(superClassDescriptor)) {
|
||||
superInterfaces.add(typeMapper.getFQName(superClassDescriptor));
|
||||
}
|
||||
}
|
||||
return superInterfaces;
|
||||
@@ -137,21 +107,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||
if (declaration != null) {
|
||||
if (declaration instanceof PsiClass) {
|
||||
if (!((PsiClass) declaration).isInterface()) {
|
||||
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
|
||||
superCall = specifier;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(declaration instanceof JetClass) {
|
||||
if(!((JetClass) declaration).isTrait()) {
|
||||
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
|
||||
superCall = specifier;
|
||||
}
|
||||
}
|
||||
if(!CodegenUtil.isInterface(superClassDescriptor)) {
|
||||
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
|
||||
superCall = specifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,16 +290,33 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
method = callableMethod.getSignature();
|
||||
}
|
||||
|
||||
int firstClosureIndex = -1;
|
||||
if(context.closure != null) {
|
||||
ObjectOrClosureCodegen closure = context.closure;
|
||||
if(closure != null) {
|
||||
final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(method.getArgumentTypes()));
|
||||
|
||||
firstClosureIndex = consArgTypes.size()+1;
|
||||
int insert = 0;
|
||||
if(closure.captureThis) {
|
||||
if(!CodegenUtil.hasThis0(descriptor))
|
||||
consArgTypes.add(insert, Type.getObjectType(context.getThisDescriptor().getName()));
|
||||
insert++;
|
||||
}
|
||||
else {
|
||||
if(CodegenUtil.hasThis0(descriptor))
|
||||
insert++;
|
||||
}
|
||||
|
||||
Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure;
|
||||
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
||||
final Type sharedVarType = context.closure.exprContext.getSharedVarType(descriptor);
|
||||
consArgTypes.add(sharedVarType != null ? sharedVarType : typeMapper.mapType(((VariableDescriptor) descriptor).getOutType()));
|
||||
if(closure.captureReceiver != null)
|
||||
consArgTypes.add(insert++, closure.captureReceiver);
|
||||
|
||||
for (DeclarationDescriptor descriptor : closure.closure.keySet()) {
|
||||
if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
||||
final Type sharedVarType = typeMapper.getSharedVarType(descriptor);
|
||||
final Type type = sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
||||
consArgTypes.add(insert++, type);
|
||||
}
|
||||
else if(descriptor instanceof FunctionDescriptor) {
|
||||
assert closure.captureReceiver != null;
|
||||
}
|
||||
}
|
||||
|
||||
method = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
|
||||
@@ -450,17 +425,28 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
generateTypeInfoInitializer(frameMap.getFirstTypeParameter(), frameMap.getTypeParameterCount(), iv);
|
||||
}
|
||||
|
||||
if(context.closure != null) {
|
||||
Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure;
|
||||
int k = 0;
|
||||
for (DeclarationDescriptor varDescr : closure.keySet()) {
|
||||
Type sharedVarType = context.closure.exprContext.getSharedVarType(varDescr);
|
||||
if(sharedVarType == null) {
|
||||
sharedVarType = typeMapper.mapType(((VariableDescriptor) varDescr).getOutType());
|
||||
}
|
||||
if(closure != null) {
|
||||
int k = outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT ? 2 : 1;
|
||||
if(closure.captureReceiver != null) {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(firstClosureIndex + k, StackValue.refType(sharedVarType));
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$" + (k+1), sharedVarType.getDescriptor());
|
||||
iv.load(1, closure.captureReceiver);
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "receiver$0", closure.captureReceiver.getDescriptor());
|
||||
k += closure.captureReceiver.getSize();
|
||||
}
|
||||
|
||||
int l = 0;
|
||||
for (DeclarationDescriptor varDescr : closure.closure.keySet()) {
|
||||
if(varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) {
|
||||
Type sharedVarType = typeMapper.getSharedVarType(varDescr);
|
||||
if(sharedVarType == null) {
|
||||
sharedVarType = typeMapper.mapType(((VariableDescriptor) varDescr).getOutType());
|
||||
}
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.load(k, StackValue.refType(sharedVarType));
|
||||
k += StackValue.refType(sharedVarType).getSize();
|
||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$" + (l+1), sharedVarType.getDescriptor());
|
||||
l++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -664,4 +664,24 @@ public class JetTypeMapper {
|
||||
JetType type = arrayType.getArguments().get(0).getType();
|
||||
return isGenericsArray(type) ? type : null;
|
||||
}
|
||||
|
||||
public Type getSharedVarType(DeclarationDescriptor descriptor) {
|
||||
if(descriptor instanceof PropertyDescriptor) {
|
||||
return StackValue.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType()));
|
||||
}
|
||||
else if (descriptor instanceof FunctionDescriptor) {
|
||||
return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType()));
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptor) {
|
||||
Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) descriptor);
|
||||
if (aBoolean != null && aBoolean) {
|
||||
JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
||||
return StackValue.sharedTypeForType(mapType(outType));
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,13 +34,13 @@ public class ObjectOrClosureCodegen {
|
||||
return result != null ? innerValue : StackValue.composed(result, innerValue);
|
||||
}
|
||||
|
||||
if (d instanceof VariableDescriptor) {
|
||||
if (d instanceof VariableDescriptor && !(d instanceof PropertyDescriptor)) {
|
||||
VariableDescriptor vd = (VariableDescriptor) d;
|
||||
|
||||
final int idx = exprContext.lookupLocal(vd);
|
||||
if (idx < 0) return null;
|
||||
|
||||
final Type sharedVarType = exprContext.getSharedVarType(vd);
|
||||
final Type sharedVarType = state.getTypeMapper().getSharedVarType(vd);
|
||||
Type localType = state.getTypeMapper().mapType(vd.getOutType());
|
||||
final Type type = sharedVarType != null ? sharedVarType : localType;
|
||||
|
||||
@@ -79,6 +79,9 @@ public class ObjectOrClosureCodegen {
|
||||
answer = new EnclosedValueDescriptor(d, innerValue, outerValue);
|
||||
closure.put(d, answer);
|
||||
|
||||
assert captureReceiver == null;
|
||||
captureReceiver = type;
|
||||
|
||||
return innerValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||
//todo not needed when frontend will be able to calculate properly
|
||||
static JetType getSuperClass(ClassDescriptor myClassDescr, BindingContext bindingContext) {
|
||||
JetClassOrObject myClass = (JetClassOrObject) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, myClassDescr);
|
||||
if(myClass == null)
|
||||
return JetStandardClasses.getAnyType();
|
||||
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
||||
|
||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
|
||||
@@ -35,6 +35,7 @@ public class IntrinsicMethods {
|
||||
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
||||
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
|
||||
public static final Equals EQUALS = new Equals();
|
||||
public static final IteratorNext ITERATOR_NEXT = new IteratorNext();
|
||||
|
||||
private final Project myProject;
|
||||
private final JetStandardLibrary myStdLib;
|
||||
@@ -83,6 +84,15 @@ public class IntrinsicMethods {
|
||||
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
|
||||
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
||||
|
||||
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
||||
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
||||
declareIntrinsicFunction("IntIterator", "next", 0, ITERATOR_NEXT);
|
||||
declareIntrinsicFunction("LongIterator", "next", 0, ITERATOR_NEXT);
|
||||
declareIntrinsicFunction("CharIterator", "next", 0, ITERATOR_NEXT);
|
||||
declareIntrinsicFunction("BooleanIterator", "next", 0, ITERATOR_NEXT);
|
||||
declareIntrinsicFunction("FloatIterator", "next", 0, ITERATOR_NEXT);
|
||||
declareIntrinsicFunction("DoubleIterator", "next", 0, ITERATOR_NEXT);
|
||||
|
||||
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
|
||||
//
|
||||
declareIntrinsicStringMethods();
|
||||
@@ -168,7 +178,11 @@ public class IntrinsicMethods {
|
||||
private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation) {
|
||||
JetScope memberScope = getClassMemberScope(className);
|
||||
final Set<FunctionDescriptor> group = memberScope.getFunctions(functionName);
|
||||
declareOverload(group, arity, implementation);
|
||||
for (FunctionDescriptor descriptor : group) {
|
||||
if (className.equals(descriptor.getContainingDeclaration().getName()) && descriptor.getValueParameters().size() == arity) {
|
||||
myMethods.put(descriptor.getOriginal(), implementation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void declareOverload(Set<FunctionDescriptor> group, int arity, IntrinsicMethod implementation) {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public class IteratorNext implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
String name;
|
||||
if(expectedType == Type.CHAR_TYPE)
|
||||
name = "Char";
|
||||
else if(expectedType == Type.BOOLEAN_TYPE)
|
||||
name = "Boolean";
|
||||
else if(expectedType == Type.BYTE_TYPE)
|
||||
name = "Byte";
|
||||
else if(expectedType == Type.SHORT_TYPE)
|
||||
name = "Short";
|
||||
else if(expectedType == Type.INT_TYPE)
|
||||
name = "Int";
|
||||
else if(expectedType == Type.LONG_TYPE)
|
||||
name = "Long";
|
||||
else if(expectedType == Type.FLOAT_TYPE)
|
||||
name = "Float";
|
||||
else if(expectedType == Type.DOUBLE_TYPE)
|
||||
name = "Double";
|
||||
else
|
||||
throw new UnsupportedOperationException();
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
v.invokevirtual("jet/" + name + "Iterator", "next" + name, "()" + expectedType.getDescriptor());
|
||||
return StackValue.onStack(expectedType);
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ namespace io {
|
||||
fun readLine() : String?
|
||||
}
|
||||
|
||||
fun Any?.identityEquals(other : Any?) // = this === other
|
||||
fun Any?.identityEquals(other : Any?) : Boolean // = this === other
|
||||
|
||||
// Can't write a body due to a bootstrapping problem (see JET-74)
|
||||
fun Any?.equals(other : Any?) : Boolean// = this === other
|
||||
@@ -53,36 +53,52 @@ trait Iterator<out T> {
|
||||
val hasNext : Boolean
|
||||
}
|
||||
|
||||
abstract open class ByteIterator : Iterator<Byte> {
|
||||
fun nextByte() : Byte
|
||||
abstract open class ByteIterator() : Iterator<Byte> {
|
||||
abstract open fun nextByte() : Byte
|
||||
|
||||
override fun next() : Byte
|
||||
}
|
||||
|
||||
abstract open class ShortIterator : Iterator<Short> {
|
||||
fun nextShort() : Short
|
||||
abstract open class ShortIterator() : Iterator<Short> {
|
||||
abstract open fun nextShort() : Short
|
||||
|
||||
override fun next() : Short
|
||||
}
|
||||
|
||||
abstract open class CharIterator : Iterator<Char> {
|
||||
fun nextChar() : Char
|
||||
abstract open class CharIterator() : Iterator<Char> {
|
||||
abstract open fun nextChar() : Char
|
||||
|
||||
override fun next() : Char
|
||||
}
|
||||
|
||||
abstract open class IntIterator : Iterator<Int> {
|
||||
fun nextInt() : Int
|
||||
abstract open class IntIterator() : Iterator<Int> {
|
||||
abstract open fun nextInt() : Int
|
||||
|
||||
override fun next() : Int
|
||||
}
|
||||
|
||||
abstract open class LongIterator : Iterator<Long> {
|
||||
fun nextLong() : Long
|
||||
abstract open class LongIterator() : Iterator<Long> {
|
||||
abstract open fun nextLong() : Long
|
||||
|
||||
override fun next() : Long
|
||||
}
|
||||
|
||||
abstract open class FloatIterator : Iterator<Float> {
|
||||
fun nextFloat() : Float
|
||||
abstract open class FloatIterator() : Iterator<Float> {
|
||||
abstract open fun nextFloat() : Float
|
||||
|
||||
override fun next() : Float
|
||||
}
|
||||
|
||||
abstract open class DoubleIterator : Iterator<Double> {
|
||||
fun nextDouble() : Double
|
||||
abstract open class DoubleIterator() : Iterator<Double> {
|
||||
abstract open fun nextDouble() : Double
|
||||
|
||||
override fun next() : Double
|
||||
}
|
||||
|
||||
abstract open class BooleanIterator : Iterator<Boolean> {
|
||||
fun nextBoolean() : Boolean
|
||||
abstract open class BooleanIterator() : Iterator<Boolean> {
|
||||
abstract open fun nextBoolean() : Boolean
|
||||
|
||||
override fun next() : Boolean
|
||||
}
|
||||
|
||||
trait Iterable<out T> {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import java.io.*
|
||||
|
||||
val ByteArray.inputStream : ByteArrayInputStream
|
||||
get() = ByteArrayInputStream(this)
|
||||
|
||||
fun InputStream.iterator() : ByteIterator =
|
||||
object: ByteIterator() {
|
||||
override val hasNext : Boolean
|
||||
get() = available() > 0
|
||||
|
||||
override fun nextByte() = read().byt
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val x = ByteArray (10)
|
||||
|
||||
for(index in 0..9) {
|
||||
x [index] = index.byt
|
||||
}
|
||||
|
||||
for(b in x.inputStream) {
|
||||
System.out?.println(b)
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -139,6 +139,55 @@ public class ArrayGenTest extends CodegenTestCase {
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testByteIterator () throws Exception {
|
||||
loadText("fun box() { val x = ByteArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testShortIterator () throws Exception {
|
||||
loadText("fun box() { val x = ShortArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testIntIterator () throws Exception {
|
||||
loadText("fun box() { val x = IntArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testLongIterator2 () throws Exception {
|
||||
loadText("fun box() { val x = LongArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testFloatIterator () throws Exception {
|
||||
loadText("fun box() { val x = FloatArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testDoubleIterator () throws Exception {
|
||||
loadText("fun box() { val x = ShortArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testBooleanIterator () throws Exception {
|
||||
loadText("fun box() { val x = BooleanArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testArrayIndices () throws Exception {
|
||||
loadText("fun box() { val x = Array<Int>(5, {it}).indices.iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
|
||||
@@ -24,7 +24,7 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
loadFile("classes/inheritingFromArrayList.jet");
|
||||
|
||||
final Class aClass = loadClass("Foo", generateClassesInFile());
|
||||
checkInterface(aClass, List.class);
|
||||
assertInstanceOf(aClass.newInstance(), List.class);
|
||||
}
|
||||
|
||||
public void testInheritanceAndDelegation_DelegatingDefaultConstructorProperties() throws Exception {
|
||||
@@ -47,13 +47,6 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
blackBoxFile("classes/rightHandOverride.jet");
|
||||
}
|
||||
|
||||
private static void checkInterface(Class aClass, Class ifs) {
|
||||
for (Class anInterface : aClass.getInterfaces()) {
|
||||
if (anInterface == ifs) return;
|
||||
}
|
||||
fail(aClass.getName() + " must have " + ifs.getName() + " in its interfaces");
|
||||
}
|
||||
|
||||
public void testNewInstanceExplicitConstructor() throws Exception {
|
||||
loadFile("classes/newInstanceDefaultConstructor.jet");
|
||||
System.out.println(generateToText());
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public class StdlibTest extends CodegenTestCase {
|
||||
public void testInputStreamIterator () {
|
||||
blackBoxFile("inputStreamIterator.jet");
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,42 @@ namespace io {
|
||||
inline fun println(message : CharArray) { System.out?.println(message) }
|
||||
inline fun println() { System.out?.println() }
|
||||
|
||||
val ByteArray.inputStream : ByteArrayInputStream
|
||||
get() = ByteArrayInputStream(this)
|
||||
|
||||
inline fun ByteArray.inputStream(offset: Int, length: Int) : ByteArrayInputStream = ByteArrayInputStream(this, offset, length)
|
||||
|
||||
val InputStream.buffered : BufferedInputStream
|
||||
get() = if(this instanceof BufferedInputStream) this else BufferedInputStream(this)
|
||||
|
||||
inline fun InputStream.buffered(bufferSize: Int) = BufferedInputStream(this, bufferSize)
|
||||
|
||||
val InputStream.reader : InputStreamReader
|
||||
get() = InputStreamReader(this)
|
||||
|
||||
val InputStream.bufferedReader : BufferedReader
|
||||
get() = buffered.reader
|
||||
|
||||
inline fun val InputStream.reader(charset: Charset) : InputStreamReader = InputStreamReader(this, charset)
|
||||
|
||||
inline fun val InputStream.reader(charsetName: String) = InputStreamReader(this, charsetNme)
|
||||
|
||||
inline fun val InputStream.reader(charset: Charset) = InputStreamReader(this, charset)
|
||||
|
||||
inline fun val InputStream.reader(charsetDecoder: CharsetDecoder) = InputStreamReader(this, charsetDecoder)
|
||||
|
||||
fun InputStream.iterator() : ByteIterator = object: ByteIterator() {
|
||||
override val hasNext : Boolean
|
||||
get() = available() > 0
|
||||
|
||||
override fun nextByte() = read().byt
|
||||
}
|
||||
|
||||
val Reader.buffered : BufferedReader
|
||||
get() = if(this instanceof BufferedReader) this else BufferedReader(this)
|
||||
|
||||
inline fun Reader.buffered(bufferSize: Int) = BufferedReader(this, bufferSize)
|
||||
|
||||
private val stdin : BufferedReader = BufferedReader(InputStreamReader(object : InputStream() {
|
||||
override fun read() : Int {
|
||||
return System.`in`?.read() ?: -1
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class BooleanIterator implements Iterator<Boolean> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(BooleanIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Boolean next() {
|
||||
return nextBoolean();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class ByteIterator implements Iterator<Byte> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(ByteIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Byte next() {
|
||||
return nextByte();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class CharIterator implements Iterator<Character> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(CharIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Character next() {
|
||||
return nextChar();
|
||||
}
|
||||
|
||||
@@ -8,10 +8,17 @@ import jet.typeinfo.TypeInfo;
|
||||
public class DefaultJetObject implements JetObject {
|
||||
private TypeInfo<?> typeInfo;
|
||||
|
||||
protected DefaultJetObject() {
|
||||
}
|
||||
|
||||
protected DefaultJetObject(TypeInfo<?> typeInfo) {
|
||||
this.typeInfo = typeInfo;
|
||||
}
|
||||
|
||||
protected final void $setTypeInfo(TypeInfo typeInfo) {
|
||||
this.typeInfo = typeInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TypeInfo<?> getTypeInfo() {
|
||||
return typeInfo;
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class DoubleIterator implements Iterator<Double> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(DoubleIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Double next() {
|
||||
return nextDouble();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
public abstract class ExtensionFunction0<E, R> extends DefaultJetObject{
|
||||
public abstract class ExtensionFunction0<E, R> extends DefaultJetObject {
|
||||
protected ExtensionFunction0(TypeInfo<?> typeInfo) {
|
||||
super(typeInfo);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class FloatIterator implements Iterator<Float> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(FloatIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Float next() {
|
||||
return nextFloat();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class IntIterator implements Iterator<Integer> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(IntIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Integer next() {
|
||||
return nextInt();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class LongIterator implements Iterator<Long> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(LongIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Long next() {
|
||||
return nextLong();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public abstract class ShortIterator implements Iterator<Short> {
|
||||
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(ShortIterator.class, false);
|
||||
|
||||
public TypeInfo getTypeInfo () {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public final Short next() {
|
||||
return nextShort();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user