Merge remote-tracking branch 'origin/master'

Conflicts:
	js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/RangesFIF.java
	js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/NamePredicate.java
This commit is contained in:
Pavel V. Talanov
2012-08-14 13:04:38 +04:00
188 changed files with 3277 additions and 1907 deletions
+2 -31
View File
@@ -176,6 +176,8 @@
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
@@ -227,38 +229,7 @@
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="jet">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="5" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
</value>
+30
View File
@@ -0,0 +1,30 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All Jvm Backend Tests" type="JUnit" factoryName="JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea">
<pattern>
<option name="PATTERN" value="org.jetbrains.jet.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<module name="compiler-tests" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
<option name="PACKAGE_NAME" value="org.jetbrains.jet.codegen" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx512m -XX:MaxPermSize=320m" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" />
</option>
<envs />
<patterns />
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Run" />
<method />
</configuration>
</component>
@@ -32,7 +32,7 @@ import org.jetbrains.jet.codegen.GenerationUtils;
import org.jetbrains.jet.compiler.PathManager;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.test.generator.Printer;
import org.jetbrains.jet.utils.Printer;
import java.io.File;
import java.io.IOException;
@@ -95,6 +95,7 @@ public class SpecialFiles {
excludedFiles.add("box.kt"); // MultiFileTest not supported yet
excludedFiles.add("kt2060_1.kt"); // MultiFileTest not supported yet
excludedFiles.add("kt2257_1.kt"); // MultiFileTest not supported yet
excludedFiles.add("kt1528_1.kt"); // MultiFileTest not supported yet
excludedFiles.add("kt684.jet"); // StackOverflow with StringBuilder (escape())
@@ -0,0 +1,45 @@
/*
* 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 org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collections;
/**
* @author alex.tkachman
*/
public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl {
public AccessorForFunctionDescriptor(DeclarationDescriptor descriptor, DeclarationDescriptor containingDeclaration, int index) {
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(),
Name.identifier(descriptor.getName() + "$b$" + index),
Kind.DECLARATION);
FunctionDescriptor fd = (SimpleFunctionDescriptor) descriptor;
initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
fd.getExpectedThisObject(),
Collections.<TypeParameterDescriptor>emptyList(),
fd.getValueParameters(),
fd.getReturnType(),
Modality.FINAL,
Visibilities.INTERNAL,
/*isInline = */ false);
}
}
@@ -0,0 +1,56 @@
/*
* 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 org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collections;
/**
* @author alex.tkachman
*/
public class AccessorForPropertyDescriptor extends PropertyDescriptor {
public AccessorForPropertyDescriptor(PropertyDescriptor pd, DeclarationDescriptor containingDeclaration, int index) {
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC,
pd.isVar(), pd.isObjectDeclaration(), Name.identifier(pd.getName() + "$b$" + index),
Kind.DECLARATION);
JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null;
setType(pd.getType(), Collections.<TypeParameterDescriptorImpl>emptyList(), pd.getExpectedThisObject(), receiverType);
initialize(new Getter(this), new Setter(this));
}
public static class Getter extends PropertyGetterDescriptor {
public Getter(AccessorForPropertyDescriptor property) {
super(property, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC,
false,
false, Kind.DECLARATION);
initialize(property.getType());
}
}
public static class Setter extends PropertySetterDescriptor {
public Setter(AccessorForPropertyDescriptor property) {
super(property, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC,
false,
false, Kind.DECLARATION);
}
}
}
@@ -233,4 +233,13 @@ public abstract class AnnotationCodegen {
}
};
}
public static AnnotationCodegen forParameter(final int parameter, final MethodVisitor mv, JetTypeMapper mapper) {
return new AnnotationCodegen(mapper) {
@Override
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
return mv.visitParameterAnnotation(parameter, descr, visible);
}
};
}
}
@@ -67,7 +67,7 @@ public class CallableMethod implements Callable {
return owner;
}
@NotNull
@Nullable
public JvmClassName getDefaultImplParam() {
return defaultImplParam;
}
@@ -96,6 +96,7 @@ public class CallableMethod implements Callable {
v.visitMethodInsn(getInvokeOpcode(), owner.getInternalName(), getSignature().getAsmMethod().getName(), getSignature().getAsmMethod().getDescriptor());
}
@Nullable
public Type getGenerateCalleeType() {
return generateCalleeType;
}
@@ -122,10 +123,6 @@ public class CallableMethod implements Callable {
return thisClass != null && generateCalleeType == null;
}
public boolean isNeedsReceiver() {
return receiverParameterType != null;
}
public Type getReturnType() {
return signature.getAsmMethod().getReturnType();
}
@@ -24,14 +24,12 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.asm4.Opcodes.ACC_ABSTRACT;
import static org.jetbrains.asm4.Opcodes.ACC_PRIVATE;
import static org.jetbrains.asm4.Opcodes.ACC_PUBLIC;
/**
@@ -99,25 +97,10 @@ public abstract class ClassBodyCodegen {
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
if (propertyDescriptor != null) {
if (!isAnnotation) {
int accessModifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0);
if((accessModifiers & ACC_PRIVATE) == 0) {
propertyCodegen.generateDefaultGetter(propertyDescriptor, accessModifiers, p);
if (propertyDescriptor.isVar()) {
propertyCodegen.generateDefaultSetter(propertyDescriptor, accessModifiers, origin);
}
}
//noinspection ConstantConditions
if (!(kind instanceof OwnerKind.DelegateKind) && state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
int modifiers = accessModifiers;
if (!propertyDescriptor.isVar()) {
modifiers |= Opcodes.ACC_FINAL;
}
if (JetStandardLibrary.isVolatile(propertyDescriptor)) {
modifiers |= Opcodes.ACC_VOLATILE;
}
Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, null);
propertyCodegen.generateBackingField(p, propertyDescriptor);
propertyCodegen.generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p);
if (propertyDescriptor.isVar()) {
propertyCodegen.generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p);
}
}
else {
@@ -17,6 +17,7 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.asm4.util.TraceClassVisitor;
@@ -28,6 +29,34 @@ import java.io.StringWriter;
*/
public class ClassBuilderFactories {
public static ClassBuilderFactory TEST = new ClassBuilderFactory() {
@NotNull
@Override
public ClassBuilderMode getClassBuilderMode() {
return ClassBuilderMode.FULL;
}
@Override
public ClassBuilder newClassBuilder() {
return new TraceBuilder(new BinaryClassWriter());
}
@Override
public String asText(ClassBuilder builder) {
TraceClassVisitor visitor = (TraceClassVisitor) builder.getVisitor();
StringWriter writer = new StringWriter();
visitor.p.print(new PrintWriter(writer));
return writer.toString();
}
@Override
public byte[] asBytes(ClassBuilder builder) {
return ((TraceBuilder) builder).binary.toByteArray();
}
};
public static ClassBuilderFactory TEXT = new ClassBuilderFactory() {
@NotNull
@Override
@@ -56,6 +85,9 @@ public class ClassBuilderFactories {
}
};
private ClassBuilderFactories() {
}
public static ClassBuilderFactory binaries(final boolean stubs) {
return new ClassBuilderFactory() {
@NotNull
@@ -66,18 +98,7 @@ public class ClassBuilderFactories {
@Override
public ClassBuilder newClassBuilder() {
return new ClassBuilder.Concrete(new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS){
@Override
protected String getCommonSuperClass(String type1, String type2) {
try {
return super.getCommonSuperClass(type1, type2);
}
catch (Throwable t) {
// @todo we might need at some point do more sofisticated handling
return "java/lang/Object";
}
}
});
return new ClassBuilder.Concrete(new BinaryClassWriter());
}
@Override
@@ -92,4 +113,30 @@ public class ClassBuilderFactories {
}
};
}
private static class BinaryClassWriter extends ClassWriter {
public BinaryClassWriter() {
super(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
}
@Override
protected String getCommonSuperClass(String type1, String type2) {
try {
return super.getCommonSuperClass(type1, type2);
}
catch (Throwable t) {
// @todo we might need at some point do more sofisticated handling
return "java/lang/Object";
}
}
}
private static class TraceBuilder extends ClassBuilder.Concrete {
public final BinaryClassWriter binary;
public TraceBuilder(BinaryClassWriter binary) {
super(new TraceClassVisitor(binary, new PrintWriter(new StringWriter())));
this.binary = binary;
}
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.jet.codegen;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*;
@@ -222,8 +221,8 @@ public class ClosureAnnotator {
}
private class MyJetVisitorVoid extends JetVisitorVoid {
private LinkedList<ClassDescriptor> classStack = new LinkedList<ClassDescriptor>();
private LinkedList<String> nameStack = new LinkedList<String>();
private final LinkedList<ClassDescriptor> classStack = new LinkedList<ClassDescriptor>();
private final LinkedList<String> nameStack = new LinkedList<String>();
private void recordEnclosing(ClassDescriptor classDescriptor) {
if (classStack.size() > 0) {
@@ -381,7 +380,9 @@ public class ClosureAnnotator {
else if (containingDeclaration instanceof NamespaceDescriptor) {
String peek = nameStack.peek();
if (peek.isEmpty()) { peek = "namespace"; }
else { peek = peek + "/namespace"; }
else {
peek += "/namespace";
}
nameStack.push(peek + '$' + function.getName());
super.visitNamedFunction(function);
nameStack.pop();
@@ -410,9 +411,4 @@ public class ClosureAnnotator {
public JvmClassName classNameForClassDescriptor(@NotNull ClassDescriptor classDescriptor) {
return classNamesForClassDescriptor.get(classDescriptor);
}
@Nullable
public JvmClassName classNameForClassDescriptorIfDefined(@NotNull ClassDescriptor classDescriptor) {
return classNamesForClassDescriptor.get(classDescriptor);
}
}
@@ -20,9 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
@@ -43,9 +41,6 @@ public abstract class CodegenContext {
private final CodegenContext parentContext;
public final ObjectOrClosureCodegen closure;
HashMap<JetType,Integer> typeInfoConstants;
HashMap<Integer,JetType> reverseTypeInfoConstants;
int typeInfoConstantsCount;
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
protected StackValue outerExpression;
@@ -183,50 +178,10 @@ public abstract class CodegenContext {
if (accessor != null) { return accessor; }
if (descriptor instanceof SimpleFunctionDescriptor) {
SimpleFunctionDescriptorImpl myAccessor = new SimpleFunctionDescriptorImpl(contextDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
Name.identifier(descriptor.getName() + "$b$" + getHierarchyCount() + "$" + accessors.size()),
CallableMemberDescriptor.Kind.DECLARATION);
FunctionDescriptor fd = (SimpleFunctionDescriptor) descriptor;
myAccessor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
fd.getExpectedThisObject(),
fd.getTypeParameters(),
fd.getValueParameters(),
fd.getReturnType(),
Modality.FINAL,
Visibilities.PUBLIC,
/*isInline = */ false);
accessor = myAccessor;
accessor = new AccessorForFunctionDescriptor(descriptor, contextDescriptor, accessors.size());
}
else if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor pd = (PropertyDescriptor) descriptor;
PropertyDescriptor myAccessor = new PropertyDescriptor(contextDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Visibilities.PUBLIC,
pd.isVar(),
pd.isObjectDeclaration(),
Name.identifier(pd.getName() + "$b$" + getHierarchyCount() + "$" + accessors.size()),
CallableMemberDescriptor.Kind.DECLARATION
);
JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null;
myAccessor.setType(pd.getType(), Collections.<TypeParameterDescriptorImpl>emptyList(), pd.getExpectedThisObject(), receiverType);
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Visibilities.PUBLIC,
false, false, CallableMemberDescriptor.Kind.DECLARATION);
pgd.initialize(myAccessor.getType());
PropertySetterDescriptor psd = new PropertySetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Visibilities.PUBLIC,
false, false, CallableMemberDescriptor.Kind.DECLARATION);
myAccessor.initialize(pgd, psd);
accessor = myAccessor;
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor,accessors.size());
}
else {
throw new UnsupportedOperationException();
@@ -235,25 +190,6 @@ public abstract class CodegenContext {
return accessor;
}
private int getHierarchyCount() {
ClassDescriptor descriptor = getThisDescriptor();
int c = 0;
while(descriptor != null) {
Collection<? extends JetType> supertypes = descriptor.getDefaultType().getConstructor().getSupertypes();
if (supertypes.isEmpty()) {
break;
}
c++;
for (JetType supertype : supertypes) {
descriptor = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
if (descriptor.getKind() == ClassKind.CLASS) {
break;
}
}
}
return c;
}
public StackValue getReceiverExpression(JetTypeMapper typeMapper) {
assert getReceiverDescriptor() != null;
Type asmType = typeMapper.mapType(getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE);
@@ -40,6 +40,9 @@ import java.util.List;
* @author Stepan Koltsov
*/
public class CodegenContexts {
private CodegenContexts() {
}
private static class FakeDescriptorForStaticContext implements DeclarationDescriptor {
@NotNull
@@ -214,7 +217,7 @@ public class CodegenContexts {
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, typeMapper.getClassFQName(contextDescriptor), "this$0", false)
? StackValue.field(type, typeMapper.getJvmClassName(contextDescriptor), "this$0", false)
: null;
}
@@ -17,6 +17,7 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.asm4.Type;
@@ -42,6 +43,11 @@ public class ConstructorFrameMap extends FrameMap {
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
if(descriptor != null && descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS) {
enterTemp(); // name
enterTemp(); // ordinal
}
List<ValueParameterDescriptor> paramDescrs = descriptor != null
? descriptor.getValueParameters()
: Collections.<ValueParameterDescriptor>emptyList();
@@ -687,14 +687,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private StackValue generateSingleBranchIf(StackValue condition, JetExpression expression, boolean inverse) {
Type expressionType = expressionType(expression);
Type targetType = expressionType;
if (!expressionType.equals(TUPLE0_TYPE)) {
targetType = TYPE_OBJECT;
}
Label elseLabel = new Label();
condition.condJump(elseLabel, inverse, v);
gen(expression, expressionType);
StackValue.coerce(expressionType, targetType, v);
Label end = new Label();
v.goTo(end);
condition.condJump(end, inverse, v);
gen(expression, Type.VOID_TYPE);
v.mark(elseLabel);
StackValue.putTuple0Instance(v);
v.mark(end);
return StackValue.none();
return StackValue.onStack(targetType);
}
@Override
@@ -1023,7 +1035,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
IntrinsicMethod intrinsic = null;
if (descriptor instanceof CallableMemberDescriptor) {
intrinsic = state.getInjector().getIntrinsics().getIntrinsic((CallableMemberDescriptor) descriptor);
CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
while(memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
memberDescriptor = memberDescriptor.getOverriddenDescriptors().iterator().next();
}
intrinsic = state.getInjector().getIntrinsics().getIntrinsic(memberDescriptor);
}
if (intrinsic != null) {
final Type expectedType = expressionType(expression);
@@ -1099,11 +1115,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if (descriptor instanceof ClassDescriptor) {
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
if (declaration instanceof JetClass) {
final JetClassObject classObject = ((JetClass) declaration).getClassObject();
if (classObject == null) {
throw new UnsupportedOperationException("trying to reference a class which doesn't have a class object");
}
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
final ClassDescriptor descriptor1 = ((ClassDescriptor)descriptor).getClassObjectDescriptor();
assert descriptor1 != null;
final Type type = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE);
return StackValue.field(type,
@@ -2717,25 +2729,38 @@ The "returned" value of try expression with no finally is either the last expres
(or blocks).
*/
JetFinallySection finallyBlock = expression.getFinallyBlock();
FinallyBlockStackElement finallyBlockStackElement = null;
if (finallyBlock != null) {
blockStackElements.push(new FinallyBlockStackElement(expression));
finallyBlockStackElement = new FinallyBlockStackElement(expression);
blockStackElements.push(finallyBlockStackElement);
}
JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
Type expectedAsmType = asmType(jetType);
Label tryStart = new Label();
v.mark(tryStart);
v.nop(); // prevent verify error on empty try
gen(expression.getTryBlock(), expectedAsmType);
int savedValue = myFrameMap.enterTemp(expectedAsmType.getSize());
v.store(savedValue, expectedAsmType);
Label tryEnd = new Label();
v.mark(tryEnd);
if (finallyBlock != null) {
blockStackElements.pop();
gen(finallyBlock.getFinalExpression(), Type.VOID_TYPE);
blockStackElements.push(finallyBlockStackElement);
}
Label end = new Label();
v.goTo(end); // TODO don't generate goto if there's no code following try/catch
for (JetCatchClause clause : expression.getCatchClauses()) {
v.goTo(end);
List<JetCatchClause> clauses = expression.getCatchClauses();
for (int i = 0, size = clauses.size(); i < size; i++) {
JetCatchClause clause = clauses.get(i);
Label clauseStart = new Label();
v.mark(clauseStart);
@@ -2748,28 +2773,45 @@ The "returned" value of try expression with no finally is either the last expres
gen(clause.getCatchBody(), expectedAsmType);
v.store(savedValue, expectedAsmType);
myFrameMap.leave(descriptor);
if (finallyBlock != null) {
blockStackElements.pop();
gen(finallyBlock.getFinalExpression(), Type.VOID_TYPE);
blockStackElements.push(finallyBlockStackElement);
}
v.goTo(end); // TODO don't generate goto if there's no code following try/catch
if (i != size - 1 || finallyBlock != null) {
v.goTo(end);
}
v.visitTryCatchBlock(tryStart, tryEnd, clauseStart, descriptorType.getInternalName());
}
if (finallyBlock != null) {
Label finallyStart = new Label();
v.mark(finallyStart);
int savedException = myFrameMap.enterTemp();
v.store(savedException, TYPE_THROWABLE);
blockStackElements.pop();
gen(finallyBlock.getFinalExpression(), Type.VOID_TYPE);
blockStackElements.push(finallyBlockStackElement);
v.load(savedException, TYPE_THROWABLE);
myFrameMap.leaveTemp();
v.athrow();
v.visitTryCatchBlock(tryStart, tryEnd, finallyStart, null);
}
v.mark(end);
v.nop();
v.load(savedValue, expectedAsmType);
myFrameMap.leaveTemp(expectedAsmType.getSize());
if (finallyBlock != null) {
blockStackElements.pop();
@@ -170,8 +170,9 @@ public class FunctionCodegen {
av.visitEnd();
}
for(int i = 0; i != paramDescrs.size(); ++i) {
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i + start);
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(parameterDescriptor);
JetValueParameterAnnotationWriter av = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i + start);
av.writeName(parameterDescriptor.getName().getName());
av.writeHasDefaultValue(parameterDescriptor.declaresDefaultValue());
av.writeNullable(parameterDescriptor.getType().isNullable());
@@ -444,6 +445,10 @@ public class FunctionCodegen {
FrameMap frameMap = owner.prepareFrame(state.getInjector().getJetTypeMapper());
if (kind instanceof OwnerKind.StaticDelegateKind) {
frameMap.leaveTemp();
}
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state);
int var = 0;
@@ -452,15 +457,13 @@ public class FunctionCodegen {
}
Type receiverType;
if (receiverParameter.exists()) {
if (hasReceiver) {
receiverType = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType(), MapTypeMode.VALUE);
var += receiverType.getSize();
}
else {
receiverType = Type.DOUBLE_TYPE;
}
if (hasReceiver) {
var += receiverType.getSize();
}
Type[] argTypes = jvmSignature.getArgumentTypes();
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
@@ -484,12 +487,15 @@ public class FunctionCodegen {
int extra = hasReceiver ? 1 : 0;
Type[] argumentTypes = jvmSignature.getArgumentTypes();
for (int index = 0; index < paramDescrs.size(); index++) {
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index);
Type t = argumentTypes[extra + index];
Label endArg = null;
Type t = argTypes[extra + index];
if (frameMap.getIndex(parameterDescriptor) < 0) {
frameMap.enter(parameterDescriptor, t.getSize());
}
if (parameterDescriptor.declaresDefaultValue()) {
iv.load(maskIndex, Type.INT_TYPE);
iv.iconst(1 << index);
@@ -501,18 +507,14 @@ public class FunctionCodegen {
assert jetParameter != null;
codegen.gen(jetParameter.getDefaultValue(), t);
endArg = new Label();
iv.goTo(endArg);
int ind = frameMap.getIndex(parameterDescriptor);
iv.store(ind, t);
iv.mark(loadArg);
}
iv.load(var, t);
var += t.getSize();
if (parameterDescriptor.declaresDefaultValue()) {
iv.mark(endArg);
}
}
if (!isStatic) {
@@ -19,10 +19,10 @@
*/
package org.jetbrains.jet.codegen;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.di.InjectorForJvmCodegen;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -30,11 +30,10 @@ import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.utils.Progress;
import org.jetbrains.asm4.commons.Method;
import java.util.Collection;
import java.util.Collections;
@@ -42,7 +41,6 @@ import java.util.List;
import java.util.Map;
public class GenerationState {
private final Project project;
private final Progress progress;
@NotNull
private final AnalyzeExhaust analyzeExhaust;
@@ -60,20 +58,19 @@ public class GenerationState {
private Method scriptConstructorMethod;
public GenerationState(Project project, ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List<JetFile> files) {
this(project, builderFactory, Progress.DEAF, analyzeExhaust, files, BuiltinToJavaTypesMapping.ENABLED);
public GenerationState(ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List<JetFile> files) {
this(builderFactory, Progress.DEAF, analyzeExhaust, files, BuiltinToJavaTypesMapping.ENABLED);
}
public GenerationState(Project project, ClassBuilderFactory builderFactory, Progress progress,
public GenerationState(ClassBuilderFactory builderFactory, Progress progress,
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping) {
this.project = project;
this.progress = progress;
this.analyzeExhaust = exhaust;
this.files = files;
this.classBuilderMode = builderFactory.getClassBuilderMode();
this.injector = new InjectorForJvmCodegen(
analyzeExhaust.getBindingContext(),
this.files, project, builtinToJavaTypesMapping, builderFactory.getClassBuilderMode(), this, builderFactory);
this.files, builtinToJavaTypesMapping, builderFactory.getClassBuilderMode(), this, builderFactory);
}
private void markUsed() {
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.utils.BitSetUtils;
import org.jetbrains.asm4.AnnotationVisitor;
@@ -54,6 +55,7 @@ import static org.jetbrains.asm4.Opcodes.*;
* @author alex.tkachman
*/
public class ImplementationBodyCodegen extends ClassBodyCodegen {
public static final String VALUES = "$VALUES";
private JetDelegationSpecifier superCall;
private String superClass;
@Nullable // null means java/lang/Object
@@ -78,6 +80,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isFinal = false;
boolean isStatic = false;
boolean isAnnotation = false;
boolean isEnum = false;
if (myClass instanceof JetClass) {
JetClass jetClass = (JetClass) myClass;
@@ -87,12 +90,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
isAbstract = true;
isInterface = true;
}
if (jetClass.isAnnotation()) {
else if (jetClass.isAnnotation()) {
isAbstract = true;
isInterface = true;
isAnnotation = true;
signature.getInterfaces().add(JdkNames.JLA_ANNOTATION.getInternalName());
}
else if (jetClass.hasModifier(JetTokens.ENUM_KEYWORD)) {
isEnum = true;
}
if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD) && !isAbstract) {
isFinal = true;
}
@@ -121,6 +128,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (isAnnotation) {
access |= ACC_ANNOTATION;
}
if (isEnum) {
access |= ACC_ENUM;
}
v.defineClass(myClass, V1_6,
access,
signature.getName(),
@@ -270,6 +280,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
}
if(superClassType == null) {
if (myClass instanceof JetClass && ((JetClass) myClass).hasModifier(JetTokens.ENUM_KEYWORD)) {
superClassType = JetStandardLibrary.getInstance().getEnumType(descriptor.getDefaultType());
superClass = typeMapper.mapType(superClassType,MapTypeMode.VALUE).getInternalName();
}
}
}
@Override
@@ -293,6 +310,38 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateTraitMethods();
generateAccessors();
generateEnumMethods();
}
private void generateEnumMethods() {
if(myEnumConstants.size() > 0) {
{
Type type = typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL);
MethodVisitor mv =
v.newMethod(myClass, ACC_PUBLIC | ACC_STATIC, "values", "()" + type.getDescriptor(), null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(),MapTypeMode.VALUE).getInternalName(), VALUES, type.getDescriptor());
mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;");
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
mv.visitInsn(ARETURN);
FunctionCodegen.endVisit(mv,"values()",myClass);
}
{
Type type = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL);
MethodVisitor mv =
v.newMethod(myClass, ACC_PUBLIC | ACC_STATIC, "valueOf", "(Ljava/lang/String;)" + type.getDescriptor(), null, null);
mv.visitCode();
mv.visitLdcInsn(type);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
mv.visitInsn(ARETURN);
FunctionCodegen.endVisit(mv,"values()",myClass);
}
}
}
private void generateAccessors() {
@@ -312,7 +361,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method originalMethod = typeMapper.mapSignature(original.getName(), original).getAsmMethod();
Type[] argTypes = method.getArgumentTypes();
MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_FINAL, bridge.getName().getName(), method.getDescriptor(), null, null);
String owner = typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName();
MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, bridge.getName().getName(),
method.getDescriptor(), null, null);
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
StubCodegen.generateStubCode(mv);
}
@@ -322,13 +373,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
for (int i = 0, reg = 1; i < argTypes.length; i++) {
for (int i = 1, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(reg, argType);
//noinspection AssignmentToForLoopParameter
reg += argType.getSize();
}
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor());
iv.invokespecial(owner, originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType());
FunctionCodegen.endVisit(iv, "accessor", null);
@@ -342,7 +393,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(),
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(),
original, ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility());
@@ -370,7 +421,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
MethodVisitor mv = v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(),
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(),
original, ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility());
@@ -384,7 +435,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.load(0, JetTypeMapper.TYPE_OBJECT);
Type[] argTypes = method.getArgumentTypes();
for (int i = 0, reg = 1; i < argTypes.length; i++) {
for (int i = 1, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(reg, argType);
//noinspection AssignmentToForLoopParameter
@@ -591,7 +642,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
i++;
}
if(myClass instanceof JetClass && ((JetClass)myClass).hasModifier(JetTokens.ENUM_KEYWORD)) {
i += 2;
}
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(valueParameter);
JetValueParameterAnnotationWriter jetValueParameterAnnotation = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
jetValueParameterAnnotation.writeName(valueParameter.getName().getName());
jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue());
@@ -638,7 +694,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (superCall == null) {
iv.load(0, Type.getType("L" + superClass + ";"));
iv.invokespecial(superClass, "<init>", "()V");
if(descriptor.getKind() == ClassKind.ENUM_CLASS) {
iv.load(1, JetTypeMapper.JL_STRING_TYPE);
iv.load(2, Type.INT_TYPE);
iv.invokespecial(superClass, "<init>", "(Ljava/lang/String;I)V");
}
else {
iv.invokespecial(superClass, "<init>", "()V");
}
}
else if (superCall instanceof JetDelegatorToSuperClass) {
iv.load(0, Type.getType("L" + superClass + ";"));
@@ -862,6 +925,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
iv.load(0, TYPE_OBJECT);
if(classDecl.getKind() == ClassKind.ENUM_CLASS) {
iv.load(1, JetTypeMapper.TYPE_OBJECT);
iv.load(2, Type.INT_TYPE);
}
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL));
@@ -892,7 +959,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
String name = declaration.getName();
final String desc = "L" + typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName() + ";";
v.newField(declaration, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, name, desc, null, null);
v.newField(declaration, ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL, name, desc, null, null);
if (myEnumConstants.isEmpty()) {
staticInitializerChunks.add(new CodeChunk() {
@Override
@@ -910,19 +977,40 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private final List<JetEnumEntry> myEnumConstants = new ArrayList<JetEnumEntry>();
private void initializeEnumConstants(InstructionAdapter v) {
ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state);
private void initializeEnumConstants(InstructionAdapter iv) {
ExpressionCodegen codegen = new ExpressionCodegen(iv, new FrameMap(), Type.VOID_TYPE, context, state);
int ordinal = -1;
JetType myType = descriptor.getDefaultType();
Type myAsmType = typeMapper.mapType(myType, MapTypeMode.IMPL);
assert myEnumConstants.size() > 0;
JetType arrayType = JetStandardLibrary.getInstance().getArrayType(myType);
Type arrayAsmType = typeMapper.mapType(arrayType, MapTypeMode.IMPL);
v.newField(myClass, ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, "$VALUES", arrayAsmType.getDescriptor(), null, null);
iv.iconst(myEnumConstants.size());
iv.newarray(myAsmType);
iv.dup();
for (JetEnumEntry enumConstant : myEnumConstants) {
ordinal++;
iv.dup();
iv.iconst(ordinal);
// TODO type and constructor parameters
String implClass = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
String implClass = typeMapper.mapType(myType, MapTypeMode.IMPL).getInternalName();
final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
if (delegationSpecifiers.size() > 1) {
throw new UnsupportedOperationException("multiple delegation specifiers for enum constant not supported");
}
v.anew(Type.getObjectType(implClass));
v.dup();
iv.anew(Type.getObjectType(implClass));
iv.dup();
iv.aconst(enumConstant.getName());
iv.iconst(ordinal);
if (delegationSpecifiers.size() == 1) {
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
@@ -937,10 +1025,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
else {
v.invokespecial(implClass, "<init>", "()V");
iv.invokespecial(implClass, "<init>", "(Ljava/lang/String;I)V");
}
v.putstatic(implClass, enumConstant.getName(), "L" + implClass + ";");
iv.dup();
iv.putstatic(implClass, enumConstant.getName(), "L" + implClass + ";");
iv.astore(TYPE_OBJECT);
}
iv.putstatic(myAsmType.getInternalName(), "$VALUES", arrayAsmType.getDescriptor());
}
public static void generateInitializers(@NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List<JetDeclaration> declarations,
@@ -1024,18 +1115,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
}
for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
if (p.getValOrVarNode() != null) {
PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
if (propertyDescriptor != null) {
propertyCodegen.generateDefaultGetter(propertyDescriptor, ACC_PUBLIC, p);
if (propertyDescriptor.isVar()) {
propertyCodegen.generateDefaultSetter(propertyDescriptor, ACC_PUBLIC, p);
}
}
}
}
}
@Nullable
@@ -62,6 +62,7 @@ public class JetTypeMapper {
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
public static final Type JL_STRING_BUILDER = Type.getObjectType("java/lang/StringBuilder");
public static final Type JL_STRING_TYPE = Type.getObjectType("java/lang/String");
public static final Type JL_ENUM_TYPE = Type.getObjectType("java/lang/Enum");
public static final Type JL_CHAR_SEQUENCE_TYPE = Type.getObjectType("java/lang/CharSequence");
private static final Type JL_COMPARABLE_TYPE = Type.getObjectType("java/lang/Comparable");
public static final Type JL_CLASS_TYPE = Type.getObjectType("java/lang/Class");
@@ -84,11 +85,79 @@ public class JetTypeMapper {
public static final Type TYPE_FUNCTION0 = Type.getObjectType("jet/Function0");
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
public static class SpecialTypes {
private static final class SpecialTypeKey {
@NotNull
private final FqNameUnsafe className;
private final boolean nullable;
private SpecialTypeKey(@NotNull FqNameUnsafe className, boolean nullable) {
this.className = className;
this.nullable = nullable;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SpecialTypeKey that = (SpecialTypeKey) o;
if (nullable != that.nullable) return false;
if (!className.equals(that.className)) return false;
return true;
}
@Override
public int hashCode() {
int result = className.hashCode();
result = 31 * result + (nullable ? 1 : 0);
return result;
}
}
private final Map<SpecialTypeKey, Type> asmTypes = Maps.newHashMap();
@Nullable
public Type get(@NotNull JetType type) {
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
return asmTypes.get(new SpecialTypeKey(DescriptorUtils.getFQName(classifier), type.isNullable()));
}
private void register(@NotNull ClassName className, @NotNull Type nonNullType, @NotNull Type nullableType) {
asmTypes.put(new SpecialTypeKey(className.getFqName().toUnsafe(), true), nullableType);
asmTypes.put(new SpecialTypeKey(className.getFqName().toUnsafe(), false), nonNullType);
}
public void init() {
register(JetStandardLibraryNames.NOTHING, TYPE_NOTHING, TYPE_NOTHING);
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
register(primitiveType.getClassName(), jvmPrimitiveType.getAsmType(), jvmPrimitiveType.getWrapper().getAsmType());
}
register(JetStandardLibraryNames.NUMBER, JL_NUMBER_TYPE, JL_NUMBER_TYPE);
register(JetStandardLibraryNames.STRING, JL_STRING_TYPE, JL_STRING_TYPE);
register(JetStandardLibraryNames.CHAR_SEQUENCE, JL_CHAR_SEQUENCE_TYPE, JL_CHAR_SEQUENCE_TYPE);
register(JetStandardLibraryNames.THROWABLE, TYPE_THROWABLE, TYPE_THROWABLE);
register(JetStandardLibraryNames.COMPARABLE, JL_COMPARABLE_TYPE, JL_COMPARABLE_TYPE);
register(JetStandardLibraryNames.ENUM, JL_ENUM_TYPE, JL_ENUM_TYPE);
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
register(primitiveType.getArrayClassName(), jvmPrimitiveType.getAsmArrayType(), jvmPrimitiveType.getAsmArrayType());
}
}
}
public BindingContext bindingContext;
private ClosureAnnotator closureAnnotator;
private boolean mapBuiltinsToJava;
private ClassBuilderMode classBuilderMode;
private final SpecialTypes specialTypes = new SpecialTypes();
@Inject
public void setBindingContext(BindingContext bindingContext) {
@@ -112,12 +181,9 @@ public class JetTypeMapper {
@PostConstruct
public void init() {
initKnownTypes();
specialTypes.init();
}
public boolean hasThis0(ClassDescriptor classDescriptor) {
return closureAnnotator.hasThis0(classDescriptor);
}
@@ -126,40 +192,6 @@ public class JetTypeMapper {
return closureAnnotator;
}
private static final class KnownTypeKey {
@NotNull
private final FqNameUnsafe className;
private final boolean nullable;
private KnownTypeKey(@NotNull FqNameUnsafe className, boolean nullable) {
this.className = className;
this.nullable = nullable;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
KnownTypeKey that = (KnownTypeKey) o;
if (nullable != that.nullable) return false;
if (!className.equals(that.className)) return false;
return true;
}
@Override
public int hashCode() {
int result = className.hashCode();
result = 31 * result + (nullable ? 1 : 0);
return result;
}
}
private final HashMap<KnownTypeKey, Type> knowTypes = Maps.newHashMap();
public static boolean isIntPrimitive(Type type) {
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
}
@@ -309,17 +341,12 @@ public class JetTypeMapper {
return null;
}
public JvmClassName getClassFQName(ClassDescriptor classDescriptor) {
return JvmClassName.byInternalName(getFQName(classDescriptor));
public JvmClassName getJvmClassName(ClassDescriptor classDescriptor) {
return JvmClassName.byInternalName(getJvmInternalFQName(classDescriptor));
}
/**
* @return Internal name
*
* @see DescriptorUtils#getFQName(DeclarationDescriptor)
*/
@NotNull
private String getFQName(@NotNull DeclarationDescriptor descriptor) {
private String getJvmInternalFQName(@NotNull DeclarationDescriptor descriptor) {
descriptor = descriptor.getOriginal();
if (descriptor instanceof FunctionDescriptor) {
@@ -340,12 +367,15 @@ public class JetTypeMapper {
if (klass.getContainingDeclaration() instanceof ClassDescriptor) {
ClassDescriptor containingKlass = (ClassDescriptor) klass.getContainingDeclaration();
if (containingKlass.getKind() == ClassKind.ENUM_CLASS) {
return getFQName(containingKlass);
return getJvmInternalFQName(containingKlass);
}
else {
return getJvmInternalFQName(containingKlass) + JvmAbi.CLASS_OBJECT_SUFFIX;
}
}
}
else if (klass.getKind() == ClassKind.ENUM_ENTRY) {
return getFQName(klass.getContainingDeclaration());
return getJvmInternalFQName(klass.getContainingDeclaration());
}
}
@@ -363,7 +393,7 @@ public class JetTypeMapper {
return className.getInternalName();
}
String baseName = getFQName(container);
String baseName = getJvmInternalFQName(container);
if (!baseName.isEmpty()) {
return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier();
}
@@ -383,17 +413,16 @@ public class JetTypeMapper {
if (mapBuiltinsToJava) {
if (classifier instanceof ClassDescriptor) {
KnownTypeKey key = new KnownTypeKey(DescriptorUtils.getFQName(classifier), jetType.isNullable());
known = knowTypes.get(key);
known = specialTypes.get(jetType);
}
}
if (known != null) {
if (kind == MapTypeMode.VALUE) {
return mapKnownAsmType(jetType, known, signatureVisitor, false);
return mapKnownAsmType(jetType, known, signatureVisitor);
}
else if (kind == MapTypeMode.TYPE_PARAMETER) {
return mapKnownAsmType(jetType, known, signatureVisitor, true);
return mapKnownAsmType(jetType, boxType(known), signatureVisitor);
}
else if (kind == MapTypeMode.TRAIT_IMPL) {
throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType);
@@ -426,7 +455,7 @@ public class JetTypeMapper {
}
Type asmType = Type.getObjectType("error/NonExistentClass");
if (signatureVisitor != null) {
visitAsmType(signatureVisitor, asmType, true);
writeSimpleType(signatureVisitor, asmType, true);
}
checkValidType(asmType);
return asmType;
@@ -459,7 +488,7 @@ public class JetTypeMapper {
if (JetStandardClasses.getAny().equals(descriptor)) {
if (signatureVisitor != null) {
visitAsmType(signatureVisitor, TYPE_OBJECT, jetType.isNullable());
writeSimpleType(signatureVisitor, TYPE_OBJECT, jetType.isNullable());
}
checkValidType(TYPE_OBJECT);
return TYPE_OBJECT;
@@ -467,33 +496,12 @@ public class JetTypeMapper {
if (descriptor instanceof ClassDescriptor) {
Type asmType;
boolean forceReal;
if (JetStandardLibraryNames.COMPARABLE.is((ClassDescriptor) descriptor) && mapBuiltinsToJava) {
if (jetType.getArguments().size() != 1) {
throw new UnsupportedOperationException("Comparable must have one type argument");
}
JvmClassName name = getJvmClassName((ClassDescriptor) descriptor);
Type asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
boolean forceReal = isForceReal(name);
asmType = JL_COMPARABLE_TYPE;
forceReal = false;
}
else {
JvmClassName name = getClassFQName((ClassDescriptor) descriptor);
asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
forceReal = isForceReal(name);
}
if (signatureVisitor != null) {
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable(), forceReal);
for (TypeProjection proj : jetType.getArguments()) {
// TODO: +-
signatureVisitor.writeTypeArgument(proj.getProjectionKind());
mapType(proj.getType(), signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeTypeArgumentEnd();
}
signatureVisitor.writeClassEnd();
}
writeGenericType(jetType, signatureVisitor, asmType, forceReal);
checkValidType(asmType);
return asmType;
@@ -513,26 +521,34 @@ public class JetTypeMapper {
throw new UnsupportedOperationException("Unknown type " + jetType);
}
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean boxPrimitive) {
if (boxPrimitive) {
Type boxed = boxType(asmType);
if (signatureVisitor != null) {
visitAsmType(signatureVisitor, boxed, jetType.isNullable());
private void writeGenericType(JetType jetType, BothSignatureWriter signatureVisitor, Type asmType, boolean forceReal) {
if (signatureVisitor != null) {
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable(), forceReal);
for (TypeProjection proj : jetType.getArguments()) {
// TODO: +-
signatureVisitor.writeTypeArgument(proj.getProjectionKind());
mapType(proj.getType(), signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeTypeArgumentEnd();
}
checkValidType(boxed);
return boxed;
}
else {
if (signatureVisitor != null) {
visitAsmType(signatureVisitor, asmType, jetType.isNullable());
}
checkValidType(asmType);
return asmType;
signatureVisitor.writeClassEnd();
}
}
public static void visitAsmType(BothSignatureWriter visitor, Type asmType, boolean nullable) {
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor) {
if (signatureVisitor != null) {
if (jetType.getArguments().isEmpty()) {
writeSimpleType(signatureVisitor, asmType, jetType.isNullable());
}
else {
writeGenericType(jetType, signatureVisitor, asmType, false);
}
}
checkValidType(asmType);
return asmType;
}
public static void writeSimpleType(BothSignatureWriter visitor, Type asmType, boolean nullable) {
visitor.writeAsmType(asmType, nullable);
}
@@ -611,6 +627,8 @@ public class JetTypeMapper {
boolean originalIsInterface = CodegenUtil.isInterface(declarationOwner);
boolean currentIsInterface = CodegenUtil.isInterface(currentOwner);
boolean isAccessor = isAccessor(functionDescriptor);
ClassDescriptor receiver;
if (currentIsInterface && !originalIsInterface) {
receiver = declarationOwner;
@@ -630,7 +648,7 @@ public class JetTypeMapper {
invokeOpcode = isInterface
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
: (isAccessor ? Opcodes.INVOKESTATIC : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL));
if (isInterface && superCall) {
descriptor = mapSignature(functionDescriptor, false, OwnerKind.TRAIT_IMPL);
owner = JvmClassName.byInternalName(owner.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
@@ -653,7 +671,11 @@ public class JetTypeMapper {
owner, ownerForDefaultImpl, ownerForDefaultParam, descriptor, invokeOpcode,
thisClass, receiverParameterType, null);
}
private static boolean isAccessor(FunctionDescriptor functionDescriptor) {
return functionDescriptor instanceof AccessorForFunctionDescriptor || functionDescriptor instanceof AccessorForPropertyDescriptor.Getter || functionDescriptor instanceof AccessorForPropertyDescriptor.Setter;
}
@NotNull
private static FunctionDescriptor findAnyDeclaration(@NotNull FunctionDescriptor function) {
//if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
@@ -682,6 +704,12 @@ public class JetTypeMapper {
signatureVisitor.writeParametersStart();
if(isAccessor(f)) {
signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS);
mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureVisitor, MapTypeMode.VALUE);
signatureVisitor.writeParameterTypeEnd();
}
if (kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration);
@@ -784,7 +812,13 @@ public class JetTypeMapper {
writeFormalTypeParameters(f.getTypeParameters(), signatureWriter);
signatureWriter.writeParametersStart();
if(isAccessor(f)) {
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
if (receiver.exists()) {
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
@@ -826,6 +860,13 @@ public class JetTypeMapper {
mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL);
signatureWriter.writeParameterTypeEnd();
}
else {
if(descriptor instanceof AccessorForPropertyDescriptor) {
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}
}
if (descriptor.getReceiverParameter().exists()) {
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
@@ -866,6 +907,13 @@ public class JetTypeMapper {
mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}
else {
if(descriptor instanceof AccessorForPropertyDescriptor) {
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}
}
if (descriptor.getReceiverParameter().exists()) {
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
@@ -896,9 +944,19 @@ public class JetTypeMapper {
signatureWriter.writeParametersStart();
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (hasThis0) {
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
mapType(closureAnnotator.getEclosingClassDescriptor(descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}
if(containingDeclaration.getKind() == ClassKind.ENUM_CLASS) {
signatureWriter.writeParameterType(JvmMethodParameterKind.ENUM_NAME);
mapType(JetStandardLibrary.getInstance().getStringType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
signatureWriter.writeParameterType(JvmMethodParameterKind.ENUM_ORDINAL);
mapType(JetStandardLibrary.getInstance().getIntType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}
@@ -971,7 +1029,7 @@ public class JetTypeMapper {
return defaultFlags;
}
if (p.getContainingDeclaration() instanceof NamespaceDescriptor) {
return ACC_PROTECTED;
return 0;
}
return ACC_PRIVATE;
}
@@ -995,36 +1053,13 @@ public class JetTypeMapper {
return result;
}
private void registerKnownType(@NotNull ClassName className, @NotNull Type nonNullType, @NotNull Type nullableType) {
knowTypes.put(new KnownTypeKey(className.getFqName().toUnsafe(), true), nullableType);
knowTypes.put(new KnownTypeKey(className.getFqName().toUnsafe(), false), nonNullType);
}
private void initKnownTypes() {
registerKnownType(JetStandardLibraryNames.NOTHING, TYPE_NOTHING, TYPE_NOTHING);
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
registerKnownType(primitiveType.getClassName(), jvmPrimitiveType.getAsmType(), jvmPrimitiveType.getWrapper().getAsmType());
}
registerKnownType(JetStandardLibraryNames.NUMBER, JL_NUMBER_TYPE, JL_NUMBER_TYPE);
registerKnownType(JetStandardLibraryNames.STRING, JL_STRING_TYPE, JL_STRING_TYPE);
registerKnownType(JetStandardLibraryNames.CHAR_SEQUENCE, JL_CHAR_SEQUENCE_TYPE, JL_CHAR_SEQUENCE_TYPE);
registerKnownType(JetStandardLibraryNames.THROWABLE, TYPE_THROWABLE, TYPE_THROWABLE);
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
registerKnownType(primitiveType.getArrayClassName(), jvmPrimitiveType.getAsmArrayType(), jvmPrimitiveType.getAsmArrayType());
}
}
private static boolean isForceReal(JvmClassName className) {
return JvmPrimitiveType.getByWrapperClass(className) != null
|| className.getFqName().getFqName().equals("java.lang.String")
|| className.getFqName().getFqName().equals("java.lang.CharSequence")
|| className.getFqName().getFqName().equals("java.lang.Object")
|| className.getFqName().getFqName().equals("java.lang.Number")
|| className.getFqName().getFqName().equals("java.lang.Enum")
|| className.getFqName().getFqName().equals("java.lang.Comparable");
}
@@ -41,6 +41,7 @@ import java.util.BitSet;
/**
* @author max
* @author alex.tkachman
*/
public class PropertyCodegen {
private final GenerationState state;
@@ -75,14 +76,14 @@ public class PropertyCodegen {
}
}
private void generateBackingField(JetProperty p, PropertyDescriptor propertyDescriptor) {
public void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) {
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
if (CodegenUtil.isInterface(containingDeclaration))
return;
Object value = null;
final JetExpression initializer = p.getInitializer();
final JetExpression initializer = p instanceof JetProperty ? ((JetProperty)p).getInitializer() : null;
if (initializer != null) {
if (initializer instanceof JetConstantExpression) {
CompileTimeConstant<?> compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer);
@@ -91,11 +92,10 @@ public class PropertyCodegen {
}
int modifiers;
if (kind == OwnerKind.NAMESPACE) {
int access = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0);
modifiers = access | Opcodes.ACC_STATIC;
modifiers = Opcodes.ACC_STATIC;
}
else {
modifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0);
modifiers = Opcodes.ACC_PRIVATE;
}
if (!propertyDescriptor.isVar()) {
modifiers |= Opcodes.ACC_FINAL;
@@ -104,7 +104,7 @@ public class PropertyCodegen {
modifiers |= Opcodes.ACC_VOLATILE;
}
Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
FieldVisitor fieldVisitor = v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, value);
FieldVisitor fieldVisitor = v.newField(p, modifiers, propertyDescriptor.getName().getName(), type.getDescriptor(), null, value);
AnnotationCodegen.forField(fieldVisitor, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor);
}
}
@@ -150,7 +150,8 @@ public class PropertyCodegen {
private void generateDefaultGetter(JetProperty p) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | (propertyDescriptor.getModality() == Modality.ABSTRACT ? Opcodes.ACC_ABSTRACT : 0);
assert propertyDescriptor != null;
int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | (propertyDescriptor.getModality() == Modality.ABSTRACT ? Opcodes.ACC_ABSTRACT : (propertyDescriptor.getModality() == Modality.FINAL ? Opcodes.ACC_FINAL : 0));
generateDefaultGetter(propertyDescriptor, flags, p);
}
@@ -212,6 +212,13 @@ public abstract class StackValue {
}
}
protected static void pop(Type type, InstructionAdapter v) {
if (type.getSize() == 1)
v.pop();
else
v.pop2();
}
protected void coerce(Type toType, InstructionAdapter v) {
coerce(this.type, toType, v);
}
@@ -220,10 +227,7 @@ public abstract class StackValue {
if (toType.equals(fromType)) return;
if (toType.getSort() == Type.VOID && fromType.getSort() != Type.VOID) {
if (fromType.getSize() == 1)
v.pop();
else
v.pop2();
pop(fromType, v);
}
else if (toType.getSort() != Type.VOID && fromType.getSort() == Type.VOID) {
if (toType.getSort() == Type.OBJECT) {
@@ -238,6 +242,10 @@ public abstract class StackValue {
else
v.iconst(0);
}
else if (toType.equals(JetTypeMapper.TUPLE0_TYPE) && !fromType.equals(JetTypeMapper.TUPLE0_TYPE)) {
pop(fromType, v);
putTuple0Instance(v);
}
else if (toType.getSort() == Type.OBJECT && fromType.equals(JetTypeMapper.TYPE_OBJECT) || toType.getSort() == Type.ARRAY) {
v.checkcast(toType);
}
@@ -357,17 +365,7 @@ public abstract class StackValue {
@Override
public void put(Type type, InstructionAdapter v) {
if (type == Type.VOID_TYPE && this.type != Type.VOID_TYPE) {
if (this.type.getSize() == 2) {
v.pop2();
}
else {
v.pop();
}
}
else {
coerce(type, v);
}
coerce(type, v);
}
@Override
@@ -627,10 +625,7 @@ public abstract class StackValue {
method.invoke(v);
Type returnType = asmMethod.getReturnType();
if (returnType != Type.VOID_TYPE) {
if (returnType.getSize() == 2)
v.pop2();
else
v.pop();
pop(returnType, v);
}
}
else
@@ -24,6 +24,9 @@ import org.jetbrains.asm4.commons.InstructionAdapter;
* @author Stepan Koltsov
*/
public class StubCodegen {
private StubCodegen() {
}
public static void generateStubThrow(MethodVisitor mv) {
new InstructionAdapter(mv).anew(Type.getObjectType("java/lang/RuntimeException"));
new InstructionAdapter(mv).dup();
@@ -0,0 +1,56 @@
/*
* 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 org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
import java.util.List;
/**
* @author Evgeny Gerashchenko
* @since 08.08.12
*/
public class EmptyRange implements IntrinsicMethod {
private final PrimitiveType elementType;
public EmptyRange(PrimitiveType elementType) {
this.elementType = elementType;
}
@Override
public StackValue generate(ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state) {
JvmClassName name = JvmClassName.byFqNameWithoutInnerClasses(elementType.getRangeClassName().getFqName());
v.getstatic(name.toString(), "EMPTY", "L" + name + ";");
return StackValue.onStack(expectedType);
}
}
@@ -0,0 +1,48 @@
/*
* 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 org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import java.util.List;
public class EnumName implements IntrinsicMethod {
@Override
public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.invokevirtual("java/lang/Enum", "name", "()Ljava/lang/String;");
StackValue.onStack(JetTypeMapper.JL_STRING_TYPE).put(expectedType, v);
return StackValue.onStack(expectedType);
}
}
@@ -0,0 +1,48 @@
/*
* 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 org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import java.util.List;
public class EnumOrdinal implements IntrinsicMethod {
@Override
public StackValue generate(
ExpressionCodegen codegen,
InstructionAdapter v,
@NotNull Type expectedType,
@Nullable PsiElement element,
@Nullable List<JetExpression> arguments,
StackValue receiver,
@NotNull GenerationState state
) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.invokevirtual("java/lang/Enum", "ordinal", "()I");
StackValue.onStack(Type.INT_TYPE).put(expectedType, v);
return StackValue.onStack(expectedType);
}
}
@@ -0,0 +1,51 @@
/*
* 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 org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import java.util.List;
/**
* @author alex.tkachman
*/
public class EnumValueOf implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) {
JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
Type type = state.getInjector().getJetTypeMapper().mapType(
resultingDescriptor.getReturnType(), MapTypeMode.VALUE);
codegen.gen(arguments.get(0),JetTypeMapper.JL_STRING_TYPE);
v.invokestatic(type.getInternalName(),"valueOf","(Ljava/lang/String;)" + type.getDescriptor());
StackValue.onStack(type).put(expectedType, v);
return StackValue.onStack(expectedType);
}
}
@@ -0,0 +1,49 @@
/*
* 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 org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import java.util.List;
/**
* @author alex.tkachman
*/
public class EnumValues implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element,
@Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) {
JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
Type type = state.getInjector().getJetTypeMapper().mapType(
resultingDescriptor.getReturnType(), MapTypeMode.VALUE);
v.invokestatic(type.getElementType().getInternalName(), "values", "()" + type);
StackValue.onStack(type).put(expectedType, v);
return StackValue.onStack(expectedType);
}
}
@@ -17,23 +17,27 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.google.common.collect.ImmutableList;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.asm4.Opcodes;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author yole
@@ -44,14 +48,11 @@ public class IntrinsicMethods {
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
private static final IntrinsicMethod INV = new Inv();
private static final IntrinsicMethod UP_TO = new UpTo(true);
private static final IntrinsicMethod DOWN_TO = new UpTo(false);
private static final IntrinsicMethod RANGE_TO = new RangeTo();
private static final IntrinsicMethod INC = new Increment(1);
private static final IntrinsicMethod DEC = new Increment(-1);
private static final IntrinsicMethod HASH_CODE = new HashCode();
private static final List<Name> PRIMITIVE_TYPES = ImmutableList.of(Name.identifier("Boolean"), Name.identifier("Byte"), Name.identifier("Char"), Name.identifier("Short"), Name.identifier("Int"), Name.identifier("Float"), Name.identifier("Long"), Name.identifier("Double"));
private static final List<Name> PRIMITIVE_NUMBER_TYPES = ImmutableList.of(Name.identifier("Byte"), Name.identifier("Char"), Name.identifier("Short"), Name.identifier("Int"), Name.identifier("Float"), Name.identifier("Long"), Name.identifier("Double"));
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
public static final Equals EQUALS = new Equals();
@@ -63,18 +64,14 @@ public class IntrinsicMethods {
public static final String KOTLIN_JAVA_CLASS_FUNCTION = "kotlin.javaClass.function";
public static final String KOTLIN_ARRAYS_ARRAY = "kotlin.arrays.array";
public static final String KOTLIN_JAVA_CLASS_PROPERTY = "kotlin.javaClass.property";
public static final EnumValues ENUM_VALUES = new EnumValues();
public static final EnumValueOf ENUM_VALUE_OF = new EnumValueOf();
private Project myProject;
private final Map<String, IntrinsicMethod> namedMethods = new HashMap<String, IntrinsicMethod>();
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
private final IntrinsicsMap intrinsicsMap = new IntrinsicsMap();
@Inject
public void setMyProject(Project myProject) {
this.myProject = myProject;
}
@PostConstruct
public void init() {
namedMethods.put(KOTLIN_JAVA_CLASS_FUNCTION, new JavaClassFunction());
@@ -84,22 +81,21 @@ public class IntrinsicMethods {
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
for (Name method : primitiveCastMethods) {
declareIntrinsicFunction(Name.identifier("Number"), method, 0, NUMBER_CAST);
for (Name type : PRIMITIVE_NUMBER_TYPES) {
declareIntrinsicFunction(type, method, 0, NUMBER_CAST);
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
declareIntrinsicFunction(type.getTypeName(), method, 0, NUMBER_CAST);
}
}
for (Name type : PRIMITIVE_NUMBER_TYPES) {
declareIntrinsicFunction(type, Name.identifier("plus"), 0, UNARY_PLUS);
declareIntrinsicFunction(type, Name.identifier("minus"), 0, UNARY_MINUS);
declareIntrinsicFunction(type, Name.identifier("inv"), 0, INV);
declareIntrinsicFunction(type, Name.identifier("rangeTo"), 1, UP_TO);
declareIntrinsicFunction(type, Name.identifier("upto"), 1, UP_TO);
declareIntrinsicFunction(type, Name.identifier("downto"), 1, DOWN_TO);
declareIntrinsicFunction(type, Name.identifier("inc"), 0, INC);
declareIntrinsicFunction(type, Name.identifier("dec"), 0, DEC);
declareIntrinsicFunction(type, Name.identifier("hashCode"), 0, HASH_CODE);
declareIntrinsicFunction(type, Name.identifier("equals"), 1, EQUALS);
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
Name typeName = type.getTypeName();
declareIntrinsicFunction(typeName, Name.identifier("plus"), 0, UNARY_PLUS);
declareIntrinsicFunction(typeName, Name.identifier("minus"), 0, UNARY_MINUS);
declareIntrinsicFunction(typeName, Name.identifier("inv"), 0, INV);
declareIntrinsicFunction(typeName, Name.identifier("rangeTo"), 1, RANGE_TO);
declareIntrinsicFunction(typeName, Name.identifier("inc"), 0, INC);
declareIntrinsicFunction(typeName, Name.identifier("dec"), 0, DEC);
declareIntrinsicFunction(typeName, Name.identifier("hashCode"), 0, HASH_CODE);
declareIntrinsicFunction(typeName, Name.identifier("equals"), 1, EQUALS);
}
declareBinaryOp(Name.identifier("plus"), Opcodes.IADD);
@@ -120,6 +116,9 @@ public class IntrinsicMethods {
declareIntrinsicFunction(Name.identifier("CharSequence"), Name.identifier("get"), 1, new StringGetChar());
declareIntrinsicFunction(Name.identifier("String"), Name.identifier("get"), 1, new StringGetChar());
intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME, Name.identifier("name"), 0, new EnumName());
intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME, Name.identifier("ordinal"), 0, new EnumOrdinal());
intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME, Name.identifier("toString"), 0, new ToString());
intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME, Name.identifier("equals"), 1, EQUALS);
intrinsicsMap.registerIntrinsic(JetStandardClasses.STANDARD_CLASSES_FQNAME, Name.identifier("identityEquals"), 1, IDENTITY_EQUALS);
@@ -139,14 +138,20 @@ public class IntrinsicMethods {
declareIntrinsicFunction(Name.identifier("FloatIterator"), Name.identifier("next"), 0, ITERATOR_NEXT);
declareIntrinsicFunction(Name.identifier("DoubleIterator"), Name.identifier("next"), 0, ITERATOR_NEXT);
for (Name type : PRIMITIVE_TYPES) {
declareIntrinsicFunction(type, Name.identifier("compareTo"), 1, new CompareTo());
for (PrimitiveType type : PrimitiveType.values()) {
declareIntrinsicFunction(type.getTypeName(), Name.identifier("compareTo"), 1, new CompareTo());
}
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
//
declareIntrinsicProperty(Name.identifier("CharSequence"), Name.identifier("length"), new StringLength());
declareIntrinsicProperty(Name.identifier("String"), Name.identifier("length"), new StringLength());
for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) {
intrinsicsMap.registerIntrinsic(
JetStandardClasses.STANDARD_CLASSES_FQNAME.child(type.getRangeTypeName()).toUnsafe().child(JetPsiUtil.NO_NAME_PROVIDED),
Name.identifier("EMPTY"), -1, new EmptyRange(type));
}
declareArrayMethods();
}
@@ -178,8 +183,8 @@ public class IntrinsicMethods {
private void declareBinaryOp(Name methodName, int opcode) {
BinaryOp op = new BinaryOp(opcode);
for (Name type : PRIMITIVE_TYPES) {
declareIntrinsicFunction(type, methodName, 1, op);
for (PrimitiveType type : PrimitiveType.values()) {
declareIntrinsicFunction(type.getTypeName(), methodName, 1, op);
}
}
@@ -220,6 +225,15 @@ public class IntrinsicMethods {
return new PsiMethodCall(functionDescriptor);
}
}
if(isEnumClassObject(functionDescriptor.getContainingDeclaration())) {
if("values".equals(functionDescriptor.getName().getName())) {
return ENUM_VALUES;
}
if("valueOf".equals(functionDescriptor.getName().getName())) {
return ENUM_VALUE_OF;
}
}
}
List<AnnotationDescriptor> annotations = descriptor.getAnnotations();
@@ -235,4 +249,17 @@ public class IntrinsicMethods {
return intrinsicMethod;
}
private static boolean isEnumClassObject(DeclarationDescriptor declaration) {
if(declaration instanceof ClassDescriptor) {
ClassDescriptor descriptor = (ClassDescriptor) declaration;
if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
//noinspection ConstantConditions
if(containingDeclaration != null && containingDeclaration.getClassObjectDescriptor() != null && containingDeclaration.getClassObjectDescriptor().equals(descriptor)) {
return true;
}
}
}
return false; //To change body of created methods use File | Settings | File Templates.
}
}
@@ -82,11 +82,18 @@ class IntrinsicsMap {
private Map<Key, IntrinsicMethod> intrinsicsMap = Maps.newHashMap();
/**
* @param valueParameterCount -1 for property
*/
public void registerIntrinsic(@NotNull FqNameUnsafe owner, @NotNull Name name, int valueParameterCount, @NotNull IntrinsicMethod impl) {
intrinsicsMap.put(new Key(owner, name, valueParameterCount), impl);
}
/**
* @param valueParameterCount -1 for property
*/
public void registerIntrinsic(@NotNull FqName owner, @NotNull Name name, int valueParameterCount, @NotNull IntrinsicMethod impl) {
intrinsicsMap.put(new Key(owner.toUnsafe(), name, valueParameterCount), impl);
registerIntrinsic(owner.toUnsafe(), name, valueParameterCount, impl);
}
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import java.util.List;
@@ -42,7 +43,13 @@ public class JavaClassFunction implements IntrinsicMethod {
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
Type type = state.getInjector().getJetTypeMapper().mapType(
resultingDescriptor.getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE);
v.aconst(type);
JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(type);
if (primitiveType != null) {
v.getstatic(primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;");
}
else {
v.aconst(type);
}
return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE);
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
import java.util.List;
@@ -36,33 +37,13 @@ public class JavaClassProperty implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, @Nullable PsiElement element, @Nullable List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) {
receiver.put(receiver.type, v);
switch (receiver.type.getSort()) {
case Type.BOOLEAN:
v.getstatic("java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
break;
case Type.BYTE:
v.getstatic("java/lang/Byte", "TYPE", "Ljava/lang/Class;");
break;
case Type.SHORT:
v.getstatic("java/lang/Short", "TYPE", "Ljava/lang/Class;");
break;
case Type.CHAR:
v.getstatic("java/lang/Character", "TYPE", "Ljava/lang/Class;");
break;
case Type.INT:
v.getstatic("java/lang/Integer", "TYPE", "Ljava/lang/Class;");
break;
case Type.LONG:
v.getstatic("java/lang/Long", "TYPE", "Ljava/lang/Class;");
break;
case Type.FLOAT:
v.getstatic("java/lang/Float", "TYPE", "Ljava/lang/Class;");
break;
case Type.DOUBLE:
v.getstatic("java/lang/Double", "TYPE", "Ljava/lang/Class;");
break;
default:
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;");
JvmPrimitiveType primitiveType = JvmPrimitiveType.getByAsmType(receiver.type);
if (primitiveType != null) {
v.pop();
v.getstatic(primitiveType.getWrapper().getAsmType().getInternalName(), "TYPE", "Ljava/lang/Class;");
}
else {
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;");
}
return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE);
}
@@ -32,16 +32,16 @@ import java.util.List;
* @author alex.tkachman
*/
public class PsiMethodCall implements IntrinsicMethod {
private final SimpleFunctionDescriptor myMethod;
private final SimpleFunctionDescriptor method;
public PsiMethodCall(SimpleFunctionDescriptor method) {
myMethod = method;
this.method = method;
}
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, @NotNull Type expectedType, PsiElement element,
List<JetExpression> arguments, StackValue receiver, @NotNull GenerationState state) {
final CallableMethod callableMethod = state.getInjector().getJetTypeMapper().mapToCallableMethod(myMethod, false, OwnerKind.IMPLEMENTATION);
final CallableMethod callableMethod = state.getInjector().getJetTypeMapper().mapToCallableMethod(method, false, OwnerKind.IMPLEMENTATION);
codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver);
return StackValue.onStack(callableMethod.getSignature().getAsmMethod().getReturnType());
}
@@ -32,11 +32,9 @@ import java.util.List;
* @author yole
* @author alex.tkachman
*/
public class UpTo implements IntrinsicMethod {
private boolean forward;
public class RangeTo implements IntrinsicMethod {
public UpTo(boolean forward) {
this.forward = forward;
public RangeTo() {
}
@Override
@@ -46,7 +44,7 @@ public class UpTo implements IntrinsicMethod {
final Type rightType = codegen.expressionType(arguments.get(0));
receiver.put(Type.INT_TYPE, v);
codegen.gen(arguments.get(0), rightType);
v.invokestatic("jet/runtime/Ranges", forward ? "upTo" : "downTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor());
v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + receiver.type.getDescriptor() + leftType.getDescriptor() + ")" + expectedType.getDescriptor());
return StackValue.onStack(expectedType);
}
else {
@@ -56,7 +54,7 @@ public class UpTo implements IntrinsicMethod {
// if (JetTypeMapper.isIntPrimitive(leftType)) {
codegen.gen(expression.getLeft(), leftType);
codegen.gen(expression.getRight(), rightType);
v.invokestatic("jet/runtime/Ranges", forward ? "upTo" : "downTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor());
v.invokestatic("jet/runtime/Ranges", "rangeTo", "(" + leftType.getDescriptor() + rightType.getDescriptor() + ")" + expectedType.getDescriptor());
return StackValue.onStack(expectedType);
// }
// else {
@@ -27,4 +27,6 @@ public enum JvmMethodParameterKind {
THIS0,
RECEIVER,
SHARED_VAR,
ENUM_NAME,
ENUM_ORDINAL,
}
@@ -20,7 +20,6 @@ package org.jetbrains.jet.di;
import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.List;
import org.jetbrains.jet.lang.psi.JetFile;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.codegen.BuiltinToJavaTypesMapping;
import org.jetbrains.jet.codegen.ClassBuilderMode;
import org.jetbrains.jet.codegen.GenerationState;
@@ -40,7 +39,6 @@ public class InjectorForJvmCodegen {
private final BindingContext bindingContext;
private final List<JetFile> listOfJetFile;
private final Project project;
private final BuiltinToJavaTypesMapping builtinToJavaTypesMapping;
private final ClassBuilderMode classBuilderMode;
private final GenerationState generationState;
@@ -56,7 +54,6 @@ public class InjectorForJvmCodegen {
public InjectorForJvmCodegen(
@NotNull BindingContext bindingContext,
@NotNull List<JetFile> listOfJetFile,
@NotNull Project project,
@NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping,
@NotNull ClassBuilderMode classBuilderMode,
@NotNull GenerationState generationState,
@@ -64,7 +61,6 @@ public class InjectorForJvmCodegen {
) {
this.bindingContext = bindingContext;
this.listOfJetFile = listOfJetFile;
this.project = project;
this.builtinToJavaTypesMapping = builtinToJavaTypesMapping;
this.classBuilderMode = classBuilderMode;
this.generationState = generationState;
@@ -92,8 +88,6 @@ public class InjectorForJvmCodegen {
this.scriptCodegen.setMemberCodegen(memberCodegen);
this.scriptCodegen.setState(generationState);
this.intrinsics.setMyProject(project);
this.classFileFactory.setBuilderFactory(classBuilderFactory);
this.classFileFactory.setState(generationState);
@@ -339,7 +339,7 @@ public class KotlinToJVMBytecodeCompiler {
environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(CompilerMessageSeverity.LOGGING, message, CompilerMessageLocation.NO_LOCATION);
}
};
GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs), backendProgress,
GenerationState generationState = new GenerationState(ClassBuilderFactories.binaries(stubs), backendProgress,
exhaust, environment.getSourceFiles(),
environment.getConfiguration().get(
JVMConfigurationKeys.BUILTIN_TO_JAVA_TYPES_MAPPING_KEY,
@@ -236,7 +236,7 @@ public class ReplInterpreter {
earierScripts.add(Pair.create(earlierLine.getScriptDescriptor(), earlierLine.getClassName()));
}
GenerationState generationState = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactories.binaries(false), backendProgress,
GenerationState generationState = new GenerationState(ClassBuilderFactories.binaries(false), backendProgress,
AnalyzeExhaust.success(trace.getBindingContext()), Collections.singletonList(psiFile),
BuiltinToJavaTypesMapping.ENABLED);
generationState.compileScript(psiFile.getScript(), scriptClassName, earierScripts, CompilationErrorHandler.THROW_EXCEPTION);
@@ -321,7 +321,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
checkPsiClassIsNotJet(psiClass);
Name name = Name.identifier(psiClass.getName());
ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS;
ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : (psiClass.isEnum() ? ClassKind.ENUM_CLASS : ClassKind.CLASS);
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
// class may be resolved during resolution of parent
@@ -266,6 +266,7 @@ public class JavaTypeTransformer {
classDescriptorMap.put(new FqName("java.lang.Throwable"), JetStandardLibrary.getInstance().getThrowable());
classDescriptorMap.put(new FqName("java.lang.Number"), JetStandardLibrary.getInstance().getNumber());
classDescriptorMap.put(new FqName("java.lang.Comparable"), JetStandardLibrary.getInstance().getComparable());
classDescriptorMap.put(new FqName("java.lang.Enum"), JetStandardLibrary.getInstance().getEnum());
}
return classDescriptorMap;
}
@@ -24,5 +24,8 @@ public class JdkNames {
public static final JvmClassName JL_OBJECT = JvmClassName.byInternalName("java/lang/Object");
public static final JvmClassName JL_STRING = JvmClassName.byInternalName("java/lang/String");
public static final JvmClassName JLA_ANNOTATION = JvmClassName.byInternalName("java/lang/annotation/Annotation");
public static final JvmClassName JLA_ENUM = JvmClassName.byInternalName("java/lang/Enum");
private JdkNames() {
}
}
@@ -30,4 +30,7 @@ public class JvmAbi {
public static final JvmClassName JETBRAINS_NOT_NULL_ANNOTATION =
JvmClassName.byFqNameWithoutInnerClasses("org.jetbrains.annotations.NotNull");
private JvmAbi() {
}
}
@@ -25,13 +25,6 @@ import org.jetbrains.asm4.Type;
*/
public class JvmClassName {
@NotNull
private final String internalName;
private JvmClassName(@NotNull String internalName) {
this.internalName = internalName;
}
@NotNull
public static JvmClassName byInternalName(@NotNull String internalName) {
return new JvmClassName(internalName);
@@ -47,7 +40,7 @@ public class JvmClassName {
}
/**
* WARNING: fq name is cannot be uniquely mapped to JVM class name.
* WARNING: fq name cannot be uniquely mapped to JVM class name.
*/
@NotNull
public static JvmClassName byFqNameWithoutInnerClasses(@NotNull FqName fqName) {
@@ -62,8 +55,16 @@ public class JvmClassName {
}
@NotNull
private final String internalName;
private transient FqName fqName;
private FqName fqName;
private String descriptor;
private Type asmType;
private JvmClassName(@NotNull String internalName) {
this.internalName = internalName;
}
@NotNull
public FqName getFqName() {
@@ -73,15 +74,11 @@ public class JvmClassName {
return fqName;
}
@NotNull
public String getInternalName() {
return internalName;
}
private transient String descriptor;
@NotNull
public String getDescriptor() {
if (descriptor == null) {
@@ -94,8 +91,6 @@ public class JvmClassName {
return descriptor;
}
private transient Type asmType;
@NotNull
public Type getAsmType() {
if (asmType == null) {
+6
View File
@@ -0,0 +1,6 @@
package jet
public abstract class Enum<E: Enum<E>>(name: String, ordinal: Int) {
public final fun name() : String
public final fun ordinal() : Int
}
-112
View File
@@ -73,22 +73,6 @@ public class Double : Number, Comparable<Double> {
public fun rangeTo(other : Byte) : DoubleRange
public fun rangeTo(other : Char) : DoubleRange
public fun upto(other : Double) : DoubleRange
public fun upto(other : Float) : DoubleRange
public fun upto(other : Long) : DoubleRange
public fun upto(other : Int) : DoubleRange
public fun upto(other : Short) : DoubleRange
public fun upto(other : Byte) : DoubleRange
public fun upto(other : Char) : DoubleRange
public fun downto(other : Double) : DoubleRange
public fun downto(other : Float) : DoubleRange
public fun downto(other : Long) : DoubleRange
public fun downto(other : Int) : DoubleRange
public fun downto(other : Short) : DoubleRange
public fun downto(other : Byte) : DoubleRange
public fun downto(other : Char) : DoubleRange
public fun inc() : Double
public fun dec() : Double
public fun plus() : Double
@@ -163,22 +147,6 @@ public class Float : Number, Comparable<Float> {
public fun rangeTo(other : Byte) : FloatRange
public fun rangeTo(other : Char) : FloatRange
public fun upto(other : Double) : DoubleRange
public fun upto(other : Float) : FloatRange
public fun upto(other : Long) : DoubleRange
public fun upto(other : Int) : FloatRange
public fun upto(other : Short) : FloatRange
public fun upto(other : Byte) : FloatRange
public fun upto(other : Char) : FloatRange
public fun downto(other : Double) : DoubleRange
public fun downto(other : Float) : FloatRange
public fun downto(other : Long) : DoubleRange
public fun downto(other : Int) : FloatRange
public fun downto(other : Short) : FloatRange
public fun downto(other : Byte) : FloatRange
public fun downto(other : Char) : FloatRange
public fun inc() : Float
public fun dec() : Float
public fun plus() : Float
@@ -253,22 +221,6 @@ public class Long : Number, Comparable<Long> {
public fun rangeTo(other : Byte) : LongRange
public fun rangeTo(other : Char) : LongRange
public fun upto(other : Double) : DoubleRange
public fun upto(other : Float) : FloatRange
public fun upto(other : Long) : LongRange
public fun upto(other : Int) : LongRange
public fun upto(other : Short) : LongRange
public fun upto(other : Byte) : LongRange
public fun upto(other : Char) : LongRange
public fun downto(other : Double) : DoubleRange
public fun downto(other : Float) : FloatRange
public fun downto(other : Long) : LongRange
public fun downto(other : Int) : LongRange
public fun downto(other : Short) : LongRange
public fun downto(other : Byte) : LongRange
public fun downto(other : Char) : LongRange
public fun inc() : Long
public fun dec() : Long
public fun plus() : Long
@@ -351,22 +303,6 @@ public class Int : Number, Comparable<Int> {
public fun rangeTo(other : Byte) : IntRange
public fun rangeTo(other : Char) : IntRange
public fun upto(other : Double) : DoubleRange
public fun upto(other : Float) : FloatRange
public fun upto(other : Long) : LongRange
public fun upto(other : Int) : IntRange
public fun upto(other : Short) : IntRange
public fun upto(other : Byte) : IntRange
public fun upto(other : Char) : IntRange
public fun downto(other : Double) : DoubleRange
public fun downto(other : Float) : FloatRange
public fun downto(other : Long) : LongRange
public fun downto(other : Int) : IntRange
public fun downto(other : Short) : IntRange
public fun downto(other : Byte) : IntRange
public fun downto(other : Char) : IntRange
public fun inc() : Int
public fun dec() : Int
public fun plus() : Int
@@ -449,22 +385,6 @@ public class Char : Number, Comparable<Char> {
public fun rangeTo(other : Byte) : CharRange
public fun rangeTo(other : Char) : CharRange
public fun upto(other : Double) : DoubleRange
public fun upto(other : Float) : FloatRange
public fun upto(other : Long) : LongRange
public fun upto(other : Int) : IntRange
public fun upto(other : Short) : ShortRange
public fun upto(other : Byte) : CharRange
public fun upto(other : Char) : CharRange
public fun downto(other : Double) : DoubleRange
public fun downto(other : Float) : FloatRange
public fun downto(other : Long) : LongRange
public fun downto(other : Int) : IntRange
public fun downto(other : Short) : ShortRange
public fun downto(other : Byte) : CharRange
public fun downto(other : Char) : CharRange
public fun inc() : Char
public fun dec() : Char
public fun plus() : Int
@@ -539,22 +459,6 @@ public class Short : Number, Comparable<Short> {
public fun rangeTo(other : Byte) : ShortRange
public fun rangeTo(other : Char) : ShortRange
public fun upto(other : Double) : DoubleRange
public fun upto(other : Float) : FloatRange
public fun upto(other : Long) : LongRange
public fun upto(other : Int) : IntRange
public fun upto(other : Short) : ShortRange
public fun upto(other : Byte) : ShortRange
public fun upto(other : Char) : ShortRange
public fun downto(other : Double) : DoubleRange
public fun downto(other : Float) : FloatRange
public fun downto(other : Long) : LongRange
public fun downto(other : Int) : IntRange
public fun downto(other : Short) : ShortRange
public fun downto(other : Byte) : ShortRange
public fun downto(other : Char) : ShortRange
public fun inc() : Short
public fun dec() : Short
public fun plus() : Short
@@ -629,22 +533,6 @@ public class Byte : Number, Comparable<Byte> {
public fun rangeTo(other : Byte) : ByteRange
public fun rangeTo(other : Char) : CharRange
public fun upto(other : Double) : DoubleRange
public fun upto(other : Float) : FloatRange
public fun upto(other : Long) : LongRange
public fun upto(other : Int) : IntRange
public fun upto(other : Short) : ShortRange
public fun upto(other : Byte) : ByteRange
public fun upto(other : Char) : CharRange
public fun downto(other : Double) : DoubleRange
public fun downto(other : Float) : FloatRange
public fun downto(other : Long) : LongRange
public fun downto(other : Int) : IntRange
public fun downto(other : Short) : ShortRange
public fun downto(other : Byte) : ByteRange
public fun downto(other : Char) : CharRange
public fun inc() : Byte
public fun dec() : Byte
public fun plus() : Byte
+28 -14
View File
@@ -13,11 +13,13 @@ public class IntRange(public val start : Int, public val size : Int) : Range<Int
public val iteratorStart : Int
public fun minus() : IntRange
public fun step(step: Int) : IntIterator
public val isReversed : Boolean
public class object {
public val EMPTY: IntRange
}
}
public class LongRange(public val start : Long, public val size : Long) : Range<Long>, LongIterable {
@@ -29,11 +31,13 @@ public class LongRange(public val start : Long, public val size : Long) : Range<
public val end : Long
public fun minus() : LongRange
public fun step(step: Long) : LongIterator
public val isReversed : Boolean
public class object {
public val EMPTY: LongRange
}
}
public class ByteRange(public val start : Byte, public val size : Int) : Range<Byte>, ByteIterable {
@@ -45,11 +49,13 @@ public class ByteRange(public val start : Byte, public val size : Int) : Range<B
public val iteratorStart : Byte
public fun minus() : ByteRange
public fun step(step: Int) : ByteIterator
public val isReversed : Boolean
public class object {
public val EMPTY: ByteRange
}
}
public class ShortRange(public val start : Short, public val size : Int) : Range<Short>, ShortIterable {
@@ -61,11 +67,13 @@ public class ShortRange(public val start : Short, public val size : Int) : Range
public val end : Short
public fun minus() : ShortRange
public fun step(step: Int) : ShortIterator
public val isReversed : Boolean
public class object {
public val EMPTY: ShortRange
}
}
public class CharRange(public val start : Char, public val size : Int) : Range<Char>, CharIterable {
@@ -77,11 +85,13 @@ public class CharRange(public val start : Char, public val size : Int) : Range<C
public val end : Char
public fun minus() : CharRange
public fun step(step: Int) : CharIterator
public val isReversed : Boolean
public class object {
public val EMPTY: CharRange
}
}
public class FloatRange(public val start : Float, public val size : Float) : Range<Float> {
@@ -89,11 +99,13 @@ public class FloatRange(public val start : Float, public val size : Float) : Ran
public val end : Float
public fun minus() : FloatRange
public fun step(step: Float) : FloatIterator
public val isReversed : Boolean
public class object {
public val EMPTY: FloatRange
}
}
public class DoubleRange(public val start : Double, public val size : Double) : Range<Double> {
@@ -101,9 +113,11 @@ public class DoubleRange(public val start : Double, public val size : Double) :
public val end : Double
public fun minus() : DoubleRange
public fun step(step: Double) : DoubleIterator
public val isReversed : Boolean
public class object {
public val EMPTY: DoubleRange
}
}
@@ -17,11 +17,9 @@
package org.jetbrains.jet.lang.descriptors;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -31,7 +29,10 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author Stepan Koltsov
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -34,11 +33,9 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ScriptReceiver;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -106,17 +103,8 @@ public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl {
if(jetDeclaration instanceof JetProperty) {
VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, jetDeclaration);
assert descriptor != null;
propertyDescriptor = new PropertyDescriptor(classDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
propertyDescriptor.getVisibility(),
false,
false,
descriptor.getName(),
CallableMemberDescriptor.Kind.DECLARATION);
propertyDescriptor.setType(returnType, Collections.<TypeParameterDescriptor>emptyList(), classReceiver, ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.initialize(null, null);
classScope.addPropertyDescriptor(propertyDescriptor);
initializeWithDefaultGetterSetter((PropertyDescriptor) descriptor);
classScope.addPropertyDescriptor(descriptor);
}
else if(jetDeclaration instanceof JetNamedFunction) {
SimpleFunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, jetDeclaration);
@@ -128,6 +116,21 @@ public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl {
}
}
public static void initializeWithDefaultGetterSetter(PropertyDescriptor propertyDescriptor) {
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if(getter == null) {
getter = propertyDescriptor.getVisibility() != Visibilities.PRIVATE ? DescriptorResolver.createDefaultGetter(propertyDescriptor) : null;
if(getter != null)
getter.initialize(propertyDescriptor.getType());
}
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if(setter == null) {
setter = propertyDescriptor.isVar() ? DescriptorResolver.createDefaultSetter(propertyDescriptor) : null;
}
propertyDescriptor.initialize(getter, setter);
}
public int getPriority() {
return priority;
}
@@ -141,43 +141,6 @@ public class TabledDescriptorRenderer {
return new TableRenderer();
}
//protected final List<TableRenderer> previousTables = Lists.newArrayList();
//private TextRow currentFirstText;
//private List<TableRow> currentRows;
//
//public TabledDescriptorRenderer newElement() {
// previousTables.add(new TableRenderer(currentFirstText, currentRows));
// currentFirstText = null;
// currentRows = Lists.newArrayList();
// return this;
//}
//
//public TabledDescriptorRenderer text(String text) {
// if (currentRows.isEmpty()) {
// currentFirstText = new TextRow(text);
// return this;
// }
// currentRows.add(new TextRow(text));
// return this;
//}
//
//public TabledDescriptorRenderer text(String text, Object... args) {
// return text(String.format(text, args));
//}
//private TabledDescriptorRenderer(@Nullable TextRow firstText, @NotNull List<TableRow> rows) {
// this.currentFirstText = firstText;
// this.currentRows = rows;
//}
//
//protected TabledDescriptorRenderer() {
// this(null, Lists.<TableRow>newArrayList());
//}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
@@ -97,7 +97,7 @@ public class JetParsing extends AbstractJetParsing {
void parseFile() {
PsiBuilder.Marker fileMarker = mark();
parsePreamble();
parsePreamble(true);
parseToplevelDeclarations(false);
@@ -107,22 +107,7 @@ public class JetParsing extends AbstractJetParsing {
void parseScript() {
PsiBuilder.Marker fileMarker = mark();
PsiBuilder.Marker namespaceHeader = mark();
PsiBuilder.Marker firstEntry = mark();
parseModifierList(MODIFIER_LIST, true);
if (at(PACKAGE_KEYWORD)) {
advance(); // PACKAGE_KEYWORD
parseNamespaceName();
firstEntry.drop();
consumeIf(SEMICOLON);
}
else {
firstEntry.rollbackTo();
}
namespaceHeader.done(NAMESPACE_HEADER);
parsePreamble(false);
PsiBuilder.Marker scriptMarker = mark();
parseImportDirectives();
@@ -155,7 +140,7 @@ public class JetParsing extends AbstractJetParsing {
* : namespaceHeader? import*
* ;
*/
private void parsePreamble() {
private void parsePreamble(boolean imports) {
/*
* namespaceHeader
* : modifiers "namespace" SimpleName{"."} SEMI?
@@ -187,7 +172,8 @@ public class JetParsing extends AbstractJetParsing {
}
namespaceHeader.done(NAMESPACE_HEADER);
parseImportDirectives();
if(imports)
parseImportDirectives();
}
/* SimpleName{"."} */
@@ -28,12 +28,10 @@ import java.util.List;
public class JetScriptDefinition {
private final String extension;
private final List<AnalyzerScriptParameter> parameters;
private final List<ImportPath> imports;
public JetScriptDefinition(String extension, List<AnalyzerScriptParameter> scriptParameters, @Nullable List<String> imports) {
public JetScriptDefinition(String extension, List<AnalyzerScriptParameter> scriptParameters) {
this.extension = extension;
parameters = scriptParameters == null ? Collections.<AnalyzerScriptParameter>emptyList() : scriptParameters;
this.imports = imports == null || imports.isEmpty() ? Collections.<ImportPath>emptyList() : importPaths(imports);
}
private static List<ImportPath> importPaths(List<String> imports) {
@@ -44,10 +42,6 @@ public class JetScriptDefinition {
return paths;
}
public JetScriptDefinition(String extension, List<AnalyzerScriptParameter> scriptParameters) {
this(extension, scriptParameters, null);
}
public JetScriptDefinition(String extension, AnalyzerScriptParameter... scriptParameters) {
this(extension, Arrays.asList(scriptParameters));
}
@@ -59,8 +53,4 @@ public class JetScriptDefinition {
public String getExtension() {
return extension;
}
public List<ImportPath> getImports() {
return imports;
}
}
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
@@ -47,6 +48,7 @@ import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.CLASS;
import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR;
/**
@@ -76,7 +78,11 @@ public class DescriptorResolver {
}
public void resolveMutableClassDescriptor(@NotNull JetClass classElement, @NotNull MutableClassDescriptor descriptor, BindingTrace trace) {
public void resolveMutableClassDescriptor(
@NotNull JetClass classElement,
@NotNull MutableClassDescriptor descriptor,
BindingTrace trace
) {
// TODO : Where-clause
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
int index = 0;
@@ -114,8 +120,11 @@ public class DescriptorResolver {
public List<JetType> resolveSupertypes(@NotNull JetScope scope, @NotNull JetClassOrObject jetClass, BindingTrace trace) {
List<JetType> result = Lists.newArrayList();
List<JetDelegationSpecifier> delegationSpecifiers = jetClass.getDelegationSpecifiers();
boolean isEnum = jetClass instanceof JetClass && ((JetClass) jetClass).hasModifier(JetTokens.ENUM_KEYWORD);
if (delegationSpecifiers.isEmpty()) {
result.add(getDefaultSupertype(jetClass, trace));
if (!isEnum) {
result.add(getDefaultSupertype(jetClass, trace));
}
}
else {
Collection<JetType> supertypes = resolveDelegationSpecifiers(
@@ -126,6 +135,19 @@ public class DescriptorResolver {
result.add(supertype);
}
}
if (isEnum) {
boolean hasSuper = false;
for (JetType type : result) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.TRAIT) {
hasSuper = true;
}
}
if (!hasSuper) {
ClassDescriptor classDescriptor = trace.getBindingContext().get(CLASS, jetClass);
result.add(0, JetStandardLibrary.getInstance().getEnumType(classDescriptor.getDefaultType()));
}
}
return result;
}
@@ -138,14 +160,20 @@ public class DescriptorResolver {
return parentDescriptor.getDefaultType();
}
else {
trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(((JetEnumEntry) jetClass).getNameIdentifier()));
trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(jetClass.getNameIdentifier()));
return ErrorUtils.createErrorType("Supertype not specified");
}
}
return JetStandardClasses.getAnyType();
}
public Collection<JetType> resolveDelegationSpecifiers(JetScope extensibleScope, List<JetDelegationSpecifier> delegationSpecifiers, @NotNull TypeResolver resolver, BindingTrace trace, boolean checkBounds) {
public Collection<JetType> resolveDelegationSpecifiers(
JetScope extensibleScope,
List<JetDelegationSpecifier> delegationSpecifiers,
@NotNull TypeResolver resolver,
BindingTrace trace,
boolean checkBounds
) {
if (delegationSpecifiers.isEmpty()) {
return Collections.emptyList();
}
@@ -178,17 +206,24 @@ public class DescriptorResolver {
}
@NotNull
public SimpleFunctionDescriptor resolveFunctionDescriptor(DeclarationDescriptor containingDescriptor, final JetScope scope, final JetNamedFunction function, final BindingTrace trace) {
public SimpleFunctionDescriptor resolveFunctionDescriptor(
DeclarationDescriptor containingDescriptor,
final JetScope scope,
final JetNamedFunction function,
final BindingTrace trace
) {
final SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
containingDescriptor,
annotationResolver.resolveAnnotations(scope, function.getModifierList(), trace),
JetPsiUtil.safeName(function.getName()),
CallableMemberDescriptor.Kind.DECLARATION
);
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace), "Function descriptor header scope");
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace),
"Function descriptor header scope");
innerScope.addLabeledDeclaration(functionDescriptor);
List<TypeParameterDescriptorImpl> typeParameterDescriptors = resolveTypeParameters(functionDescriptor, innerScope, function.getTypeParameters(), trace);
List<TypeParameterDescriptorImpl> typeParameterDescriptors =
resolveTypeParameters(functionDescriptor, innerScope, function.getTypeParameters(), trace);
innerScope.changeLockLevel(WritableScope.LockLevel.BOTH);
resolveGenericBounds(function, innerScope, typeParameterDescriptors, trace);
@@ -197,12 +232,13 @@ public class DescriptorResolver {
if (receiverTypeRef != null) {
JetScope scopeForReceiver =
function.hasTypeParameterListBeforeFunctionName()
? innerScope
: scope;
? innerScope
: scope;
receiverType = typeResolver.resolveType(scopeForReceiver, receiverTypeRef, trace, true);
}
List<ValueParameterDescriptor> valueParameterDescriptors = resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters(), trace);
List<ValueParameterDescriptor> valueParameterDescriptors =
resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters(), trace);
innerScope.changeLockLevel(WritableScope.LockLevel.READING);
@@ -217,13 +253,14 @@ public class DescriptorResolver {
else {
final JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression != null) {
returnType = DeferredType.create(trace, new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
@Override
protected JetType compute() {
//JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
return expressionTypingServices.inferFunctionReturnType(scope, function, functionDescriptor, trace);
}
});
returnType =
DeferredType.create(trace, new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
@Override
protected JetType compute() {
//JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
return expressionTypingServices.inferFunctionReturnType(scope, function, functionDescriptor, trace);
}
});
}
else {
returnType = ErrorUtils.createErrorType("No type, no body");
@@ -263,7 +300,12 @@ public class DescriptorResolver {
}
@NotNull
private List<ValueParameterDescriptor> resolveValueParameters(FunctionDescriptor functionDescriptor, WritableScope parameterScope, List<JetParameter> valueParameters, BindingTrace trace) {
private List<ValueParameterDescriptor> resolveValueParameters(
FunctionDescriptor functionDescriptor,
WritableScope parameterScope,
List<JetParameter> valueParameters,
BindingTrace trace
) {
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
for (int i = 0, valueParametersSize = valueParameters.size(); i < valueParametersSize; i++) {
JetParameter valueParameter = valueParameters.get(i);
@@ -278,7 +320,8 @@ public class DescriptorResolver {
type = typeResolver.resolveType(parameterScope, typeReference, trace, true);
}
ValueParameterDescriptor valueParameterDescriptor = resolveValueParameterDescriptor(parameterScope, functionDescriptor, valueParameter, i, type, trace);
ValueParameterDescriptor valueParameterDescriptor =
resolveValueParameterDescriptor(parameterScope, functionDescriptor, valueParameter, i, type, trace);
parameterScope.addVariableDescriptor(valueParameterDescriptor);
result.add(valueParameterDescriptor);
}
@@ -288,7 +331,8 @@ public class DescriptorResolver {
@NotNull
public MutableValueParameterDescriptor resolveValueParameterDescriptor(
JetScope scope, DeclarationDescriptor declarationDescriptor,
JetParameter valueParameter, int index, JetType type, BindingTrace trace) {
JetParameter valueParameter, int index, JetType type, BindingTrace trace
) {
JetType varargElementType = null;
JetType variableType = type;
if (valueParameter.hasModifier(JetTokens.VARARG_KEYWORD)) {
@@ -320,7 +364,12 @@ public class DescriptorResolver {
}
}
public List<TypeParameterDescriptorImpl> resolveTypeParameters(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, List<JetTypeParameter> typeParameters, BindingTrace trace) {
public List<TypeParameterDescriptorImpl> resolveTypeParameters(
DeclarationDescriptor containingDescriptor,
WritableScope extensibleScope,
List<JetTypeParameter> typeParameters,
BindingTrace trace
) {
List<TypeParameterDescriptorImpl> result = new ArrayList<TypeParameterDescriptorImpl>();
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
JetTypeParameter typeParameter = typeParameters.get(i);
@@ -329,11 +378,17 @@ public class DescriptorResolver {
return result;
}
private TypeParameterDescriptorImpl resolveTypeParameter(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, JetTypeParameter typeParameter, int index, BindingTrace trace) {
// JetTypeReference extendsBound = typeParameter.getExtendsBound();
// JetType bound = extendsBound == null
// ? JetStandardClasses.getDefaultBound()
// : typeResolver.resolveType(extensibleScope, extendsBound);
private TypeParameterDescriptorImpl resolveTypeParameter(
DeclarationDescriptor containingDescriptor,
WritableScope extensibleScope,
JetTypeParameter typeParameter,
int index,
BindingTrace trace
) {
// JetTypeReference extendsBound = typeParameter.getExtendsBound();
// JetType bound = extendsBound == null
// ? JetStandardClasses.getDefaultBound()
// : typeResolver.resolveType(extensibleScope, extendsBound);
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
containingDescriptor,
annotationResolver.createAnnotationStubs(typeParameter.getModifierList(), trace),
@@ -342,7 +397,7 @@ public class DescriptorResolver {
JetPsiUtil.safeName(typeParameter.getName()),
index
);
// typeParameterDescriptor.addUpperBound(bound);
// typeParameterDescriptor.addUpperBound(bound);
extensibleScope.addTypeParameterDescriptor(typeParameterDescriptor);
trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
return typeParameterDescriptor;
@@ -372,7 +427,7 @@ public class DescriptorResolver {
return constructorDescriptor;
}
final class UpperBoundCheckerTask {
static final class UpperBoundCheckerTask {
JetTypeReference upperBound;
JetType upperBoundType;
boolean isClassObjectConstraint;
@@ -384,7 +439,12 @@ public class DescriptorResolver {
}
}
public void resolveGenericBounds(@NotNull JetTypeParameterListOwner declaration, JetScope scope, List<TypeParameterDescriptorImpl> parameters, BindingTrace trace) {
public void resolveGenericBounds(
@NotNull JetTypeParameterListOwner declaration,
JetScope scope,
List<TypeParameterDescriptorImpl> parameters,
BindingTrace trace
) {
List<UpperBoundCheckerTask> deferredUpperBoundCheckerTasks = Lists.newArrayList();
List<JetTypeParameter> typeParameters = declaration.getTypeParameters();
@@ -416,7 +476,8 @@ public class DescriptorResolver {
JetType bound = null;
if (boundTypeReference != null) {
bound = typeResolver.resolveType(scope, boundTypeReference, trace, false);
deferredUpperBoundCheckerTasks.add(new UpperBoundCheckerTask(boundTypeReference, bound, constraint.isClassObjectContraint()));
deferredUpperBoundCheckerTasks
.add(new UpperBoundCheckerTask(boundTypeReference, bound, constraint.isClassObjectContraint()));
}
if (typeParameterDescriptor == null) {
@@ -469,7 +530,12 @@ public class DescriptorResolver {
}
}
private static void checkUpperBoundType(JetTypeReference upperBound, JetType upperBoundType, boolean isClassObjectConstraint, BindingTrace trace) {
private static void checkUpperBoundType(
JetTypeReference upperBound,
JetType upperBoundType,
boolean isClassObjectConstraint,
BindingTrace trace
) {
if (!TypeUtils.canHaveSubtypes(JetTypeChecker.INSTANCE, upperBoundType)) {
if (isClassObjectConstraint) {
trace.report(FINAL_CLASS_OBJECT_UPPER_BOUND.on(upperBound, upperBoundType));
@@ -481,7 +547,12 @@ public class DescriptorResolver {
}
@NotNull
public VariableDescriptor resolveLocalVariableDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, @NotNull JetParameter parameter, BindingTrace trace) {
public VariableDescriptor resolveLocalVariableDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetScope scope,
@NotNull JetParameter parameter,
BindingTrace trace
) {
JetType type = resolveParameterType(scope, parameter, trace);
return resolveLocalVariableDescriptor(containingDeclaration, parameter, type, trace);
}
@@ -502,7 +573,12 @@ public class DescriptorResolver {
return type;
}
public VariableDescriptor resolveLocalVariableDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetParameter parameter, @NotNull JetType type, BindingTrace trace) {
public VariableDescriptor resolveLocalVariableDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetParameter parameter,
@NotNull JetType type,
BindingTrace trace
) {
VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
containingDeclaration,
annotationResolver.createAnnotationStubs(parameter.getModifierList(), trace),
@@ -514,7 +590,13 @@ public class DescriptorResolver {
}
@NotNull
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property, DataFlowInfo dataFlowInfo, BindingTrace trace) {
public VariableDescriptor resolveLocalVariableDescriptor(
DeclarationDescriptor containingDeclaration,
JetScope scope,
JetProperty property,
DataFlowInfo dataFlowInfo,
BindingTrace trace
) {
if (property.isScriptDeclaration()) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
@@ -527,24 +609,31 @@ public class DescriptorResolver {
CallableMemberDescriptor.Kind.DECLARATION
);
JetType type = getVariableType(scope, property, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
JetType type =
getVariableType(scope, property, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), scope.getImplicitReceiver(), (JetType) null);
trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
return propertyDescriptor;
}
else {
VariableDescriptorImpl variableDescriptor = resolveLocalVariableDescriptorWithType(containingDeclaration, property, null, trace);
VariableDescriptorImpl variableDescriptor =
resolveLocalVariableDescriptorWithType(containingDeclaration, property, null, trace);
JetType type = getVariableType(scope, property, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
JetType type =
getVariableType(scope, property, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
variableDescriptor.setOutType(type);
return variableDescriptor;
}
}
@NotNull
public VariableDescriptorImpl resolveLocalVariableDescriptorWithType(DeclarationDescriptor containingDeclaration, JetProperty property, JetType type, BindingTrace trace) {
public VariableDescriptorImpl resolveLocalVariableDescriptorWithType(
DeclarationDescriptor containingDeclaration,
JetProperty property,
JetType type,
BindingTrace trace
) {
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
containingDeclaration,
annotationResolver.createAnnotationStubs(property.getModifierList(), trace),
@@ -556,11 +645,13 @@ public class DescriptorResolver {
}
@NotNull
public VariableDescriptor resolveObjectDeclaration(@NotNull DeclarationDescriptor containingDeclaration,
public VariableDescriptor resolveObjectDeclaration(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetClassOrObject objectDeclaration,
@NotNull ClassDescriptor classDescriptor, BindingTrace trace) {
@NotNull ClassDescriptor classDescriptor, BindingTrace trace
) {
boolean isProperty = (containingDeclaration instanceof NamespaceDescriptor)
|| (containingDeclaration instanceof ClassDescriptor);
|| (containingDeclaration instanceof ClassDescriptor);
if (isProperty) {
return resolveObjectDeclarationAsPropertyDescriptor(containingDeclaration, objectDeclaration, classDescriptor, trace);
}
@@ -570,9 +661,11 @@ public class DescriptorResolver {
}
@NotNull
public PropertyDescriptor resolveObjectDeclarationAsPropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration,
public PropertyDescriptor resolveObjectDeclarationAsPropertyDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetClassOrObject objectDeclaration,
@NotNull ClassDescriptor classDescriptor, BindingTrace trace) {
@NotNull ClassDescriptor classDescriptor, BindingTrace trace
) {
JetModifierList modifierList = objectDeclaration.getModifierList();
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
@@ -584,7 +677,8 @@ public class DescriptorResolver {
JetPsiUtil.safeName(objectDeclaration.getName()),
CallableMemberDescriptor.Kind.DECLARATION
);
propertyDescriptor.setType(classDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.setType(classDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(),
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.initialize(createDefaultGetter(propertyDescriptor), null);
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
if (nameAsDeclaration != null) {
@@ -594,15 +688,17 @@ public class DescriptorResolver {
}
@NotNull
private VariableDescriptor resolveObjectDeclarationAsLocalVariable(@NotNull DeclarationDescriptor containingDeclaration,
private VariableDescriptor resolveObjectDeclarationAsLocalVariable(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetClassOrObject objectDeclaration,
@NotNull ClassDescriptor classDescriptor, BindingTrace trace) {
@NotNull ClassDescriptor classDescriptor, BindingTrace trace
) {
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
containingDeclaration,
annotationResolver.createAnnotationStubs(objectDeclaration.getModifierList(), trace),
JetPsiUtil.safeName(objectDeclaration.getName()),
classDescriptor.getDefaultType(),
/*isVar =*/ false);
containingDeclaration,
annotationResolver.createAnnotationStubs(objectDeclaration.getModifierList(), trace),
JetPsiUtil.safeName(objectDeclaration.getName()),
classDescriptor.getDefaultType(),
/*isVar =*/ false);
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
if (nameAsDeclaration != null) {
trace.record(BindingContext.VARIABLE, nameAsDeclaration, variableDescriptor);
@@ -610,10 +706,13 @@ public class DescriptorResolver {
return variableDescriptor;
}
public JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull ReceiverDescriptor receiver, BindingTrace trace) {
public JetScope getPropertyDeclarationInnerScope(
@NotNull JetScope outerScope, @NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull ReceiverDescriptor receiver, BindingTrace trace
) {
WritableScopeImpl result = new WritableScopeImpl(
outerScope, outerScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace), "Property declaration inner scope");
outerScope, outerScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace),
"Property declaration inner scope");
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
result.addTypeParameterDescriptor(typeParameterDescriptor);
}
@@ -625,7 +724,12 @@ public class DescriptorResolver {
}
@NotNull
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property, BindingTrace trace) {
public PropertyDescriptor resolvePropertyDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetScope scope,
JetProperty property,
BindingTrace trace
) {
JetModifierList modifierList = property.getModifierList();
boolean isVar = property.isVar();
@@ -655,7 +759,8 @@ public class DescriptorResolver {
}
else {
WritableScope writableScope = new WritableScopeImpl(
scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace), "Scope with type parameters of a property");
scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace),
"Scope with type parameters of a property");
typeParameterDescriptors = resolveTypeParameters(containingDeclaration, writableScope, typeParameters, trace);
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
resolveGenericBounds(property, writableScope, typeParameterDescriptors, trace);
@@ -669,14 +774,15 @@ public class DescriptorResolver {
}
ReceiverDescriptor receiverDescriptor = receiverType == null
? ReceiverDescriptor.NO_RECEIVER
: new ExtensionReceiver(propertyDescriptor, receiverType);
? ReceiverDescriptor.NO_RECEIVER
: new ExtensionReceiver(propertyDescriptor, receiverType);
JetScope propertyScope = getPropertyDeclarationInnerScope(scope, typeParameterDescriptors, ReceiverDescriptor.NO_RECEIVER, trace);
JetType type = getVariableType(propertyScope, property, DataFlowInfo.EMPTY, true, trace);
propertyDescriptor.setType(type, typeParameterDescriptors, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), receiverDescriptor);
propertyDescriptor.setType(type, typeParameterDescriptors, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
receiverDescriptor);
PropertyGetterDescriptor getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
@@ -687,7 +793,8 @@ public class DescriptorResolver {
return propertyDescriptor;
}
/*package*/ static boolean hasBody(JetProperty property) {
/*package*/
static boolean hasBody(JetProperty property) {
boolean hasBody = property.getInitializer() != null;
if (!hasBody) {
JetPropertyAccessor getter = property.getGetter();
@@ -703,7 +810,13 @@ public class DescriptorResolver {
}
@NotNull
private JetType getVariableType(@NotNull final JetScope scope, @NotNull final JetProperty property, @NotNull final DataFlowInfo dataFlowInfo, boolean allowDeferred, final BindingTrace trace) {
private JetType getVariableType(
@NotNull final JetScope scope,
@NotNull final JetProperty property,
@NotNull final DataFlowInfo dataFlowInfo,
boolean allowDeferred,
final BindingTrace trace
) {
// TODO : receiver?
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
@@ -760,7 +873,9 @@ public class DescriptorResolver {
@NotNull
/*package*/ static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList) {
Visibility defaultVisibility = modifierList != null && modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD) ? Visibilities.INHERITED : Visibilities.INTERNAL;
Visibility defaultVisibility = modifierList != null && modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD)
? Visibilities.INHERITED
: Visibilities.INTERNAL;
return resolveVisibilityFromModifiers(modifierList, defaultVisibility);
}
@@ -775,7 +890,12 @@ public class DescriptorResolver {
}
@Nullable
private PropertySetterDescriptor resolvePropertySetterDescriptor(@NotNull JetScope scope, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor, BindingTrace trace) {
private PropertySetterDescriptor resolvePropertySetterDescriptor(
@NotNull JetScope scope,
@NotNull JetProperty property,
@NotNull PropertyDescriptor propertyDescriptor,
BindingTrace trace
) {
JetPropertyAccessor setter = property.getSetter();
PropertySetterDescriptor setterDescriptor = null;
if (setter != null) {
@@ -783,7 +903,8 @@ public class DescriptorResolver {
JetParameter parameter = setter.getParameter();
setterDescriptor = new PropertySetterDescriptor(
propertyDescriptor, annotations, resolveModalityFromModifiers(setter.getModifierList(), propertyDescriptor.getModality()),
propertyDescriptor, annotations,
resolveModalityFromModifiers(setter.getModifierList(), propertyDescriptor.getModality()),
resolveVisibilityFromModifiers(setter.getModifierList(), propertyDescriptor.getVisibility()),
setter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
if (parameter != null) {
@@ -812,7 +933,8 @@ public class DescriptorResolver {
}
}
MutableValueParameterDescriptor valueParameterDescriptor = resolveValueParameterDescriptor(scope, setterDescriptor, parameter, 0, type, trace);
MutableValueParameterDescriptor valueParameterDescriptor =
resolveValueParameterDescriptor(scope, setterDescriptor, parameter, 0, type, trace);
setterDescriptor.initialize(valueParameterDescriptor);
}
else {
@@ -825,16 +947,16 @@ public class DescriptorResolver {
setterDescriptor = createDefaultSetter(propertyDescriptor);
}
if (! property.isVar()) {
if (!property.isVar()) {
if (setter != null) {
// trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
// trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
trace.report(VAL_WITH_SETTER.on(setter));
}
}
return setterDescriptor;
}
private PropertySetterDescriptor createDefaultSetter(PropertyDescriptor propertyDescriptor) {
public static PropertySetterDescriptor createDefaultSetter(PropertyDescriptor propertyDescriptor) {
PropertySetterDescriptor setterDescriptor;
setterDescriptor = new PropertySetterDescriptor(
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
@@ -845,7 +967,12 @@ public class DescriptorResolver {
}
@Nullable
private PropertyGetterDescriptor resolvePropertyGetterDescriptor(@NotNull JetScope scope, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor, BindingTrace trace) {
private PropertyGetterDescriptor resolvePropertyGetterDescriptor(
@NotNull JetScope scope,
@NotNull JetProperty property,
@NotNull PropertyDescriptor propertyDescriptor,
BindingTrace trace
) {
PropertyGetterDescriptor getterDescriptor;
JetPropertyAccessor getter = property.getGetter();
if (getter != null) {
@@ -862,7 +989,8 @@ public class DescriptorResolver {
}
getterDescriptor = new PropertyGetterDescriptor(
propertyDescriptor, annotations, resolveModalityFromModifiers(getter.getModifierList(), propertyDescriptor.getModality()),
propertyDescriptor, annotations,
resolveModalityFromModifiers(getter.getModifierList(), propertyDescriptor.getModality()),
resolveVisibilityFromModifiers(getter.getModifierList(), propertyDescriptor.getVisibility()),
getter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
getterDescriptor.initialize(returnType);
@@ -891,7 +1019,8 @@ public class DescriptorResolver {
boolean isPrimary,
@Nullable JetModifierList modifierList,
@NotNull JetDeclaration declarationToTrace,
List<TypeParameterDescriptor> typeParameters, @NotNull List<JetParameter> valueParameters, BindingTrace trace) {
List<TypeParameterDescriptor> typeParameters, @NotNull List<JetParameter> valueParameters, BindingTrace trace
) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
classDescriptor,
annotationResolver.resolveAnnotations(scope, modifierList, trace),
@@ -911,7 +1040,12 @@ public class DescriptorResolver {
}
@Nullable
public ConstructorDescriptorImpl resolvePrimaryConstructorDescriptor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass classElement, BindingTrace trace) {
public ConstructorDescriptorImpl resolvePrimaryConstructorDescriptor(
@NotNull JetScope scope,
@NotNull ClassDescriptor classDescriptor,
@NotNull JetClass classElement,
BindingTrace trace
) {
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY && !classElement.hasPrimaryConstructor()) return null;
return createConstructorDescriptor(
scope,
@@ -927,7 +1061,8 @@ public class DescriptorResolver {
@NotNull ClassDescriptor classDescriptor,
@NotNull ValueParameterDescriptor valueParameter,
@NotNull JetScope scope,
@NotNull JetParameter parameter, BindingTrace trace) {
@NotNull JetParameter parameter, BindingTrace trace
) {
JetType type = resolveParameterType(scope, parameter, trace);
Name name = parameter.getNameAsName();
boolean isMutable = parameter.isMutable();
@@ -950,7 +1085,8 @@ public class DescriptorResolver {
name == null ? Name.special("<no name>") : name,
CallableMemberDescriptor.Kind.DECLARATION
);
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER);
PropertyGetterDescriptor getter = createDefaultGetter(propertyDescriptor);
PropertySetterDescriptor setter = propertyDescriptor.isVar() ? createDefaultSetter(propertyDescriptor) : null;
@@ -993,7 +1129,8 @@ public class DescriptorResolver {
@NotNull JetTypeReference jetTypeArgument,
@NotNull JetType typeArgument,
@NotNull TypeParameterDescriptor typeParameterDescriptor,
@NotNull TypeSubstitutor substitutor, BindingTrace trace) {
@NotNull TypeSubstitutor substitutor, BindingTrace trace
) {
for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
if (!JetTypeChecker.INSTANCE.isSubtypeOf(typeArgument, substitutedBound)) {
@@ -1001,4 +1138,51 @@ public class DescriptorResolver {
}
}
}
public static SimpleFunctionDescriptor createEnumClassObjectValuesMethod(
final ClassDescriptor mutableClassDescriptor,
ClassDescriptor classObjectDescriptor,
BindingTrace trace
) {
List<AnnotationDescriptor> annotations = Collections.<AnnotationDescriptor>emptyList();
SimpleFunctionDescriptorImpl values =
new SimpleFunctionDescriptorImpl(classObjectDescriptor, annotations,
Name.identifier("values"),
CallableMemberDescriptor.Kind.DECLARATION);
ClassReceiver classReceiver = new ClassReceiver(classObjectDescriptor);
JetType type = DeferredType.create(trace, new LazyValue<JetType>() {
@Override
protected JetType compute() {
return JetStandardLibrary.getInstance().getArrayType(mutableClassDescriptor.getDefaultType());
}
});
values.initialize(null, classReceiver, Collections.<TypeParameterDescriptor>emptyList(),Collections.<ValueParameterDescriptor>emptyList(),
type, Modality.FINAL,
Visibilities.PUBLIC, false);
return values;
}
public static SimpleFunctionDescriptor createEnumClassObjectValueOfMethod(
final ClassDescriptor mutableClassDescriptor,
ClassDescriptor classObjectDescriptor,
BindingTrace trace
) {
List<AnnotationDescriptor> annotations = Collections.<AnnotationDescriptor>emptyList();
SimpleFunctionDescriptorImpl values =
new SimpleFunctionDescriptorImpl(classObjectDescriptor, annotations,
Name.identifier("valueOf"),
CallableMemberDescriptor.Kind.DECLARATION);
ClassReceiver classReceiver = new ClassReceiver(classObjectDescriptor);
JetType type = DeferredType.create(trace, new LazyValue<JetType>() {
@Override
protected JetType compute() {
return mutableClassDescriptor.getDefaultType();
}
});
ValueParameterDescriptorImpl parameterDescriptor = new ValueParameterDescriptorImpl(values,0,Collections.<AnnotationDescriptor>emptyList(),Name.identifier("value"),false,JetStandardLibrary.getInstance().getStringType(),false,null);
values.initialize(null, classReceiver, Collections.<TypeParameterDescriptor>emptyList(),Arrays.<ValueParameterDescriptor>asList(parameterDescriptor),
type, Modality.FINAL,
Visibilities.PUBLIC, false);
return values;
}
}
@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
@@ -80,7 +79,7 @@ public class ImportsResolver {
private void processImports(boolean onlyClasses, @NotNull JetScope rootScope) {
for (JetFile file : context.getNamespaceDescriptors().keySet()) {
WritableScope namespaceScope = context.getNamespaceScopes().get(file);
processImportsInFile(onlyClasses, namespaceScope, ScopeProvider.getFileImports(file), rootScope);
processImportsInFile(onlyClasses, namespaceScope, Lists.newArrayList(file.getImportDirectives()), rootScope);
}
for (JetScript script : context.getScripts().keySet()) {
WritableScope scriptScope = context.getScriptScopes().get(script);
@@ -189,7 +189,7 @@ public class OverrideResolver {
extractAndBindOverridesForMember(fromCurrent, notOverridden, current, sink);
}
bindFakeOverrides(current, notOverridden, sink);
createAndBindFakeOverrides(current, notOverridden, sink);
}
private static void extractAndBindOverridesForMember(
@@ -222,7 +222,7 @@ public class OverrideResolver {
}
}
private static void bindFakeOverrides(
private static void createAndBindFakeOverrides(
@NotNull ClassDescriptor current,
@NotNull List<CallableMemberDescriptor> notOverridden,
@NotNull DescriptorSink sink
@@ -231,11 +231,11 @@ public class OverrideResolver {
while (!fromSuperQueue.isEmpty()) {
CallableMemberDescriptor notOverriddenFromSuper = fromSuperQueue.remove();
Collection<CallableMemberDescriptor> overridables = extractMembersOverridableBy(notOverriddenFromSuper, fromSuperQueue, sink);
bindFakeOverride(notOverriddenFromSuper, overridables, current, sink);
createAndBindFakeOverride(notOverriddenFromSuper, overridables, current, sink);
}
}
private static void bindFakeOverride(
private static void createAndBindFakeOverride(
@NotNull CallableMemberDescriptor notOverriddenFromSuper,
@NotNull Collection<CallableMemberDescriptor> overridables,
@NotNull ClassDescriptor current,
@@ -24,24 +24,26 @@ import com.intellij.psi.PsiNameIdentifierOwner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.SubstitutionUtils;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.util.lazy.LazyValue;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.FQNAME_TO_CLASS_DESCRIPTOR;
import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE;
/**
* @author abreslav
@@ -93,8 +95,10 @@ public class TypeHierarchyResolver {
this.trace = trace;
}
public void process(@NotNull JetScope outerScope, @NotNull NamespaceLikeBuilder owner,
@NotNull Collection<? extends PsiElement> declarations) {
public void process(
@NotNull JetScope outerScope, @NotNull NamespaceLikeBuilder owner,
@NotNull Collection<? extends PsiElement> declarations
) {
{
// TODO: Very temp code - main goal is to remove recursion from collectNamespacesAndClassifiers
@@ -142,7 +146,7 @@ public class TypeHierarchyResolver {
// At this point, there are no loops in the type hierarchy
checkSupertypesForConsistency();
// computeSuperclasses();
// computeSuperclasses();
checkTypesInClassHeaders(); // Check bounds in the types used in generic bounds and supertype lists
}
@@ -170,11 +174,11 @@ public class TypeHierarchyResolver {
DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration();
if (declaration instanceof NamespaceDescriptorImpl) {
return getStaticScope(declarationElement, ((NamespaceDescriptorImpl)declaration).getBuilder());
return getStaticScope(declarationElement, ((NamespaceDescriptorImpl) declaration).getBuilder());
}
if (declaration instanceof MutableClassDescriptorLite) {
return getStaticScope(declarationElement, ((MutableClassDescriptorLite)declaration).getBuilder());
return getStaticScope(declarationElement, ((MutableClassDescriptorLite) declaration).getBuilder());
}
}
@@ -202,7 +206,7 @@ public class TypeHierarchyResolver {
namespaceScope.changeLockLevel(WritableScope.LockLevel.BOTH);
context.getNamespaceScopes().put(file, namespaceScope);
if(file.isScript()) {
if (file.isScript()) {
scriptHeaderResolver.processScriptHierarchy(file.getScript(), namespaceScope);
}
@@ -228,6 +232,7 @@ public class TypeHierarchyResolver {
@Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
final MutableClassDescriptor objectDescriptor = createClassDescriptorForObject(declaration, owner, outerScope);
owner.addObjectDescriptor(objectDescriptor);
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(declaration), objectDescriptor);
}
@@ -266,7 +271,8 @@ public class TypeHierarchyResolver {
public void visitClassObject(JetClassObject classObject) {
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
if (objectDeclaration != null) {
MutableClassDescriptor classObjectDescriptor = createClassDescriptorForObject(objectDeclaration, owner, getStaticScope(classObject, owner));
MutableClassDescriptor classObjectDescriptor =
createClassDescriptorForObject(objectDeclaration, owner, getStaticScope(classObject, owner));
NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor);
switch (status) {
case DUPLICATE:
@@ -282,22 +288,27 @@ public class TypeHierarchyResolver {
}
}
private void createClassObjectForEnumClass(JetClass klass, MutableClassDescriptor mutableClassDescriptor) {
private void createClassObjectForEnumClass(JetClass klass, final MutableClassDescriptor mutableClassDescriptor) {
if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) {
MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(
mutableClassDescriptor, outerScope, ClassKind.OBJECT, Name.special("<class-object-for-" + klass.getName() + ">"));
mutableClassDescriptor, outerScope, ClassKind.OBJECT,
Name.special("<class-object-for-" + klass.getName() + ">"));
classObjectDescriptor.setModality(Modality.FINAL);
classObjectDescriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(klass.getModifierList()));
classObjectDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
classObjectDescriptor.createTypeConstructor();
ConstructorDescriptorImpl primaryConstructorForObject = createPrimaryConstructorForObject(null, classObjectDescriptor);
ConstructorDescriptorImpl primaryConstructorForObject =
createPrimaryConstructorForObject(null, classObjectDescriptor);
primaryConstructorForObject.setReturnType(classObjectDescriptor.getDefaultType());
classObjectDescriptor.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValuesMethod(mutableClassDescriptor, classObjectDescriptor, trace));
classObjectDescriptor.getBuilder().addFunctionDescriptor(DescriptorResolver.createEnumClassObjectValueOfMethod(mutableClassDescriptor, classObjectDescriptor,trace));
mutableClassDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor);
}
}
private MutableClassDescriptor createClassDescriptorForObject(
@NotNull JetObjectDeclaration declaration, @NotNull NamespaceLikeBuilder owner, JetScope scope) {
@NotNull JetObjectDeclaration declaration, @NotNull NamespaceLikeBuilder owner, JetScope scope
) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
owner.getOwnerForChildren(), scope, ClassKind.OBJECT, JetPsiUtil.safeName(declaration.getName()));
context.getObjects().put(declaration, mutableClassDescriptor);
@@ -307,14 +318,17 @@ public class TypeHierarchyResolver {
prepareForDeferredCall(classScope, mutableClassDescriptor, declaration);
createPrimaryConstructorForObject(declaration, mutableClassDescriptor);
owner.addObjectDescriptor(mutableClassDescriptor);
trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor);
return mutableClassDescriptor;
}
private MutableClassDescriptor createClassDescriptorForEnumEntry(@NotNull JetEnumEntry declaration, @NotNull NamespaceLikeBuilder owner) {
private MutableClassDescriptor createClassDescriptorForEnumEntry(
@NotNull JetEnumEntry declaration,
@NotNull NamespaceLikeBuilder owner
) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(
owner.getOwnerForChildren(), getStaticScope(declaration, owner), ClassKind.ENUM_ENTRY, JetPsiUtil.safeName(declaration.getName()));
owner.getOwnerForChildren(), getStaticScope(declaration, owner), ClassKind.ENUM_ENTRY,
JetPsiUtil.safeName(declaration.getName()));
context.getClasses().put(declaration, mutableClassDescriptor);
prepareForDeferredCall(mutableClassDescriptor.getScopeForMemberResolution(), mutableClassDescriptor, declaration);
@@ -326,17 +340,21 @@ public class TypeHierarchyResolver {
return mutableClassDescriptor;
}
private ConstructorDescriptorImpl createPrimaryConstructorForObject(@Nullable PsiElement object,
MutableClassDescriptor mutableClassDescriptor) {
private ConstructorDescriptorImpl createPrimaryConstructorForObject(
@Nullable PsiElement object,
MutableClassDescriptor mutableClassDescriptor
) {
ConstructorDescriptorImpl constructorDescriptor = DescriptorResolver
.createPrimaryConstructorForObject(object, mutableClassDescriptor, trace);
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, trace);
return constructorDescriptor;
}
private void prepareForDeferredCall(@NotNull JetScope outerScope,
@NotNull WithDeferredResolve withDeferredResolve,
@NotNull JetDeclarationContainer container) {
private void prepareForDeferredCall(
@NotNull JetScope outerScope,
@NotNull WithDeferredResolve withDeferredResolve,
@NotNull JetDeclarationContainer container
) {
forDeferredResolve.add(container);
context.normalScope.put(container, outerScope);
context.forDeferredResolver.put(container, withDeferredResolve);
@@ -412,9 +430,11 @@ public class TypeHierarchyResolver {
}
}
private static void topologicallySort(MutableClassDescriptor mutableClassDescriptor,
Set<ClassDescriptor> visited,
LinkedList<MutableClassDescriptor> topologicalOrder) {
private static void topologicallySort(
MutableClassDescriptor mutableClassDescriptor,
Set<ClassDescriptor> visited,
LinkedList<MutableClassDescriptor> topologicalOrder
) {
if (!visited.add(mutableClassDescriptor)) {
return;
}
@@ -428,10 +448,12 @@ public class TypeHierarchyResolver {
topologicalOrder.addFirst(mutableClassDescriptor);
}
private void traverseTypeHierarchy(MutableClassDescriptor currentClass,
Set<ClassDescriptor> visited,
Set<ClassDescriptor> beingProcessed,
List<ClassDescriptor> currentPath) {
private void traverseTypeHierarchy(
MutableClassDescriptor currentClass,
Set<ClassDescriptor> visited,
Set<ClassDescriptor> beingProcessed,
List<ClassDescriptor> currentPath
) {
if (!visited.add(currentClass)) {
if (beingProcessed.contains(currentClass)) {
markCycleErrors(currentPath, currentClass);
@@ -305,13 +305,13 @@ public class CallResolver {
private <D extends CallableDescriptor> OverloadResolutionResults<D> completeTypeInferenceDependentOnExpectedType(
@NotNull BasicResolutionContext context,
@NotNull OverloadResolutionResults<D> results,
@NotNull OverloadResolutionResults<D> resultsWithIncompleteTypeInference,
@NotNull TracingStrategy tracing
) {
if (results.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) return results;
if (resultsWithIncompleteTypeInference.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) return resultsWithIncompleteTypeInference;
Set<ResolvedCallWithTrace<D>> successful = Sets.newLinkedHashSet();
Set<ResolvedCallWithTrace<D>> failed = Sets.newLinkedHashSet();
for (ResolvedCall<? extends D> call : results.getResultingCalls()) {
for (ResolvedCall<? extends D> call : resultsWithIncompleteTypeInference.getResultingCalls()) {
if (!(call instanceof ResolvedCallImpl)) continue;
ResolvedCallImpl<D> resolvedCall = (ResolvedCallImpl<D>) call;
if (!resolvedCall.hasUnknownTypeParameters()) {
@@ -325,16 +325,11 @@ public class CallResolver {
}
completeTypeInferenceDependentOnExpectedTypeForCall(resolvedCall, context, tracing, successful, failed);
}
if (results.getResultingCalls().size() > 1) {
for (ResolvedCallWithTrace<D> call : successful) {
if (call instanceof ResolvedCallImpl) {
((ResolvedCallImpl)call).addStatus(ResolutionStatus.OTHER_ERROR);
failed.add(call);
}
}
successful.clear();
OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(context.trace, tracing, successful, failed);
if (!results.isSingleResult()) {
checkTypesWithNoCallee(context);
}
return computeResultAndReportErrors(context.trace, tracing, successful, failed);
return results;
}
private <D extends CallableDescriptor> void completeTypeInferenceDependentOnExpectedTypeForCall(ResolvedCallImpl<D> resolvedCall,
@@ -381,9 +376,9 @@ public class CallResolver {
if (constraintSystemWithoutExpectedTypeConstraint.isSuccessful()) {
resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor());
}
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, context.trace).argumentTypes;
List<JetType> argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes;
JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null;
tracing.typeInferenceFailed(context.trace,
tracing.typeInferenceFailed(resolvedCall.getTrace(),
InferenceErrorData
.create(descriptor, constraintSystem, argumentTypes, receiverType, context.expectedType),
constraintSystemWithoutExpectedTypeConstraint);
@@ -394,9 +389,9 @@ public class CallResolver {
resolvedCall.setResultingSubstitutor(constraintSystem.getResultingSubstitutor());
// Here we type check the arguments with inferred types expected
checkValueArgumentTypes(context, resolvedCall, context.trace);
checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace());
checkBounds(resolvedCall, constraintSystem, context.trace, tracing);
checkBounds(resolvedCall, constraintSystem, resolvedCall.getTrace(), tracing);
resolvedCall.setHasUnknownTypeParameters(false);
if (resolvedCall.getStatus().isSuccess() || resolvedCall.getStatus() == ResolutionStatus.UNKNOWN_STATUS) {
resolvedCall.addStatus(ResolutionStatus.SUCCESS);
@@ -596,7 +591,7 @@ public class CallResolver {
OverloadResolutionResultsImpl<F> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates,
failedCandidates);
if (!results.isSingleResult() && results.getResultCode() != OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
if (!results.isSingleResult() && !results.isIncomplete()) {
checkTypesWithNoCallee(task.toBasic());
}
return results;
@@ -768,20 +763,25 @@ public class CallResolver {
// Solution
if (!constraintsSystem.hasContradiction()) {
boolean hasContradiction = constraintsSystem.hasContradiction();
boolean boundsAreSatisfied = ConstraintsUtil.checkBoundsAreSatisfied(constraintsSystem);
if (!hasContradiction && boundsAreSatisfied) {
candidateCall.setHasUnknownTypeParameters(true);
return SUCCESS;
}
else {
ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context);
ResolutionStatus argumentsStatus = checkingResult.status;
List<JetType> argumentTypes = checkingResult.argumentTypes;
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
context.tracing.typeInferenceFailed(context.trace,
InferenceErrorData.create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType, context.expectedType),
constraintSystemWithRightTypeParameters);
return TYPE_INFERENCE_ERROR.combine(argumentsStatus);
ValueArgumentsCheckingResult checkingResult = checkAllValueArguments(context);
ResolutionStatus argumentsStatus = checkingResult.status;
List<JetType> argumentTypes = checkingResult.argumentTypes;
JetType receiverType = candidateCall.getReceiverArgument().exists() ? candidateCall.getReceiverArgument().getType() : null;
InferenceErrorData inferenceErrorData = InferenceErrorData
.create(candidate, constraintSystemWithRightTypeParameters, argumentTypes, receiverType, context.expectedType);
if (hasContradiction) {
context.tracing.typeInferenceFailed(candidateCall.getTrace(), inferenceErrorData, constraintSystemWithRightTypeParameters);
}
else {
context.tracing.upperBoundViolated(candidateCall.getTrace(), inferenceErrorData);
}
return TYPE_INFERENCE_ERROR.combine(argumentsStatus);
}
private boolean addConstraintForValueArgument(ValueArgument valueArgument,
@@ -1033,7 +1033,7 @@ public class CallResolver {
}
if (!thisLevel.isEmpty()) {
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
if (results.isSuccess()) {
if (results.isSingleResult()) {
results.getResultingCall().getTrace().commit();
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
}
@@ -1058,9 +1058,6 @@ public class CallResolver {
ResolvedCallWithTrace<D> failed = failedCandidates.iterator().next();
failed.getTrace().commit();
if (failed.getStatus() != ResolutionStatus.STRONG_ERROR && failed.hasUnknownTypeParameters()) {
return OverloadResolutionResultsImpl.incompleteTypeInference(failed);
}
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
}
else {
@@ -1078,13 +1075,9 @@ public class CallResolver {
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallWithTrace<D>> candidates, boolean discriminateGenerics) {
if (candidates.size() != 1) {
boolean dirty = false;
Set<ResolvedCallWithTrace<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
for (Iterator<ResolvedCallWithTrace<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
ResolvedCallWithTrace<D> candidate = iterator.next();
if (candidate.hasUnknownTypeParameters()) {
dirty = true;
}
if (candidate.isDirty()) {
iterator.remove();
}
@@ -1107,10 +1100,6 @@ public class CallResolver {
Set<ResolvedCallWithTrace<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
if (dirty) {
return OverloadResolutionResultsImpl.incompleteTypeInference(candidates);
}
return OverloadResolutionResultsImpl.ambiguity(noOverrides);
}
else {
@@ -1118,9 +1107,6 @@ public class CallResolver {
TemporaryBindingTrace temporaryTrace = result.getTrace();
temporaryTrace.commit();
if (result.hasUnknownTypeParameters()) {
return OverloadResolutionResultsImpl.incompleteTypeInference(result);
}
return OverloadResolutionResultsImpl.success(result);
}
@@ -63,4 +63,6 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
boolean isNothing();
boolean isAmbiguity();
boolean isIncomplete();
}
@@ -28,8 +28,11 @@ import java.util.Collections;
*/
/*package*/ class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallWithTrace<D> descriptor) {
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(descriptor));
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallWithTrace<D> candidate) {
if (candidate.hasUnknownTypeParameters()) {
return incompleteTypeInference(candidate);
}
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(candidate));
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> nameNotFound() {
@@ -37,22 +40,30 @@ import java.util.Collections;
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> singleFailedCandidate(ResolvedCallWithTrace<D> candidate) {
if (candidate.getStatus() != ResolutionStatus.STRONG_ERROR && candidate.hasUnknownTypeParameters()) {
return incompleteTypeInference(candidate);
}
return new OverloadResolutionResultsImpl<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> manyFailedCandidates(Collection<ResolvedCallWithTrace<D>> failedCandidates) {
return new OverloadResolutionResultsImpl<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> descriptors) {
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, descriptors);
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> candidates) {
for (ResolvedCallWithTrace<D> candidate : candidates) {
if (candidate.hasUnknownTypeParameters()) {
return incompleteTypeInference(candidates);
}
}
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, candidates);
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(Collection<ResolvedCallWithTrace<D>> descriptors) {
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, descriptors);
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(Collection<ResolvedCallWithTrace<D>> candidates) {
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, candidates);
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> descriptor) {
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, Collections.singleton(descriptor));
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> candidate) {
return incompleteTypeInference(Collections.singleton(candidate));
}
private final Collection<ResolvedCallWithTrace<D>> results;
@@ -96,7 +107,7 @@ import java.util.Collections;
@Override
public boolean isSingleResult() {
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
return results.size() == 1;
}
@Override
@@ -108,7 +119,13 @@ import java.util.Collections;
public boolean isAmbiguity() {
return resultCode == Code.AMBIGUITY;
}
//
@Override
public boolean isIncomplete() {
return resultCode == Code.INCOMPLETE_TYPE_INFERENCE;
}
//
// public OverloadResolutionResultsImpl<D> newContents(@NotNull Collection<D> functionDescriptors) {
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
// }
@@ -32,8 +32,8 @@ public enum ResolutionStatus {
@SuppressWarnings("unchecked")
public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] {
EnumSet.of(UNSAFE_CALL_ERROR), // weakest
EnumSet.of(OTHER_ERROR),
EnumSet.of(TYPE_INFERENCE_ERROR),
EnumSet.of(OTHER_ERROR),
EnumSet.of(STRONG_ERROR), // most severe
};
@@ -30,6 +30,9 @@ import org.jetbrains.jet.lang.resolve.calls.inference.TypeConstraintsImpl.Constr
import java.util.*;
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeConstraintsImpl.ConstraintKind.*;
import static org.jetbrains.jet.lang.types.Variance.*;
/**
* @author svtk
*/
@@ -137,12 +140,12 @@ public class ConstraintSystemImpl implements ConstraintSystem {
@Override
public void addSubtypingConstraint(@NotNull JetType subjectType, @Nullable JetType constrainingType, @NotNull ConstraintPosition constraintPosition) {
addConstraint(ConstraintKind.SUB_TYPE, subjectType, constrainingType, constraintPosition);
addConstraint(SUB_TYPE, subjectType, constrainingType, constraintPosition);
}
@Override
public void addSupertypeConstraint(@NotNull JetType subjectType, @Nullable JetType constrainingType, @NotNull ConstraintPosition constraintPosition) {
addConstraint(ConstraintKind.SUPER_TYPE, subjectType, constrainingType, constraintPosition);
addConstraint(SUPER_TYPE, subjectType, constrainingType, constraintPosition);
}
private void addConstraint(@NotNull ConstraintKind constraintKind,
@@ -210,12 +213,100 @@ public class ConstraintSystemImpl implements ConstraintSystem {
List<TypeProjection> constrainingArguments = constrainingType.getArguments();
List<TypeParameterDescriptor> parameters = typeConstructor.getParameters();
for (int i = 0; i < subjectArguments.size(); i++) {
//todo constrainingArguments.get(i).getType() -> type projections
addConstraint(ConstraintKind.fromVariance(parameters.get(i).getVariance()), subjectArguments.get(i).getType(),
constrainingArguments.get(i).getType(), constraintPosition);
Variance typeParameterVariance = parameters.get(i).getVariance();
TypeProjection subjectArgument = subjectArguments.get(i);
TypeProjection constrainingArgument = constrainingArguments.get(i);
ConstraintKind typeParameterConstraintKind = getTypeParameterConstraintKind(typeParameterVariance,
subjectArgument, constrainingArgument, constraintKind);
addConstraint(typeParameterConstraintKind, subjectArgument.getType(), constrainingArgument.getType(), constraintPosition);
}
}
/**
* Determines what constraint (supertype, subtype or equal) should be generated for type parameter {@code T} in a constraint like (in this example subtype one): <br/>
* {@code MyClass<in/out/- A> <: MyClass<in/out/- B>}, where {@code MyClass<in/out/- T>} is declared. <br/>
*
* The parameters description is given according to the example above.
* @param typeParameterVariance declared variance of T
* @param subjectTypeProjection {@code in/out/- A}
* @param constrainingTypeProjection {@code in/out/- B}
* @param upperConstraintKind kind of the constraint {@code MyClass<...A> <: MyClass<...B>} (subtype in this example).
* @return kind of constraint to be generated: {@code A <: B} (subtype), {@code A >: B} (supertype) or {@code A = B} (equal).
*/
@NotNull
private static ConstraintKind getTypeParameterConstraintKind(
@NotNull Variance typeParameterVariance,
@NotNull TypeProjection subjectTypeProjection,
@NotNull TypeProjection constrainingTypeProjection,
@NotNull ConstraintKind upperConstraintKind
) {
// If variance of type parameter is non-trivial, it should be taken into consideration to infer result constraint type.
// Otherwise when type parameter declared as INVARIANT, there might be non-trivial use-site variance of a supertype.
//
// Example: Let class MyClass<T> is declared.
//
// If super type has 'out' projection:
// MyClass<A> <: MyClass<out B>,
// then constraint A <: B can be generated.
//
// If super type has 'in' projection:
// MyClass<A> <: MyClass<in B>,
// then constraint A >: B can be generated.
//
// Otherwise constraint A = B should be generated.
Variance varianceForTypeParameter;
if (typeParameterVariance != INVARIANT) {
varianceForTypeParameter = typeParameterVariance;
}
else if (upperConstraintKind == SUB_TYPE) {
varianceForTypeParameter = constrainingTypeProjection.getProjectionKind();
}
else if (upperConstraintKind == SUPER_TYPE) {
varianceForTypeParameter = subjectTypeProjection.getProjectionKind();
}
else {
varianceForTypeParameter = INVARIANT;
}
return getTypeParameterConstraintKind(varianceForTypeParameter, upperConstraintKind);
}
/**
* Let class {@code MyClass<T, out R, in S>} is declared.<br/><br/>
*
* If upperConstraintKind is SUB_TYPE:
* {@code MyClass<A, B, C> <: MyClass<D, E, F>}, <br/>
* then constraints {@code A = D, B <: E, C >: F} are generated. <br/><br/>
*
* If upperConstraintKind is SUPER_TYPE:
* {@code MyClass<A, B, C> >: MyClass<D, E, F>}, <br/>
* then constraints {@code A = D, B >: E, C <: F} are generated. <br/><br/>
*
* If upperConstraintKind is EQUAL:
* {@code MyClass<A, B, C> = MyClass<D, E, F>}, <br/>
* then equality constraints {@code A = D, B = E, C = F} are generated. <br/><br/>
*
* Method getTypeParameterConstraintKind gets upperConstraintKind and variance of type parameter
* (INVARIANT for T, OUT_VARIANCE for R in example above) and returns kind of constraint for corresponding type parameter.
*/
@NotNull
private static ConstraintKind getTypeParameterConstraintKind(
@NotNull Variance typeParameterVariance,
@NotNull ConstraintKind upperConstraintKind
) {
if (upperConstraintKind == EQUAL || typeParameterVariance == INVARIANT) {
return EQUAL;
}
if ((upperConstraintKind == SUPER_TYPE && typeParameterVariance == OUT_VARIANCE) ||
(upperConstraintKind == SUB_TYPE && typeParameterVariance == IN_VARIANCE)) {
return SUPER_TYPE;
}
return SUB_TYPE;
}
@NotNull
@Override
public Set<TypeParameterDescriptor> getTypeVariables() {
@@ -39,28 +39,28 @@ public class ConstraintsUtil {
values.addAll(typeConstraints.getExactBounds());
if (!typeConstraints.getLowerBounds().isEmpty()) {
JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertype(typeConstraints.getLowerBounds());
if (values.isEmpty()) {
values.add(superTypeOfLowerBounds);
}
for (JetType value : values) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(superTypeOfLowerBounds, value)) {
values.add(superTypeOfLowerBounds);
break;
}
}
if (values.isEmpty()) {
values.add(superTypeOfLowerBounds);
}
}
if (!typeConstraints.getUpperBounds().isEmpty()) {
//todo subTypeOfUpperBounds
JetType subTypeOfUpperBounds = typeConstraints.getUpperBounds().iterator().next(); //todo
if (values.isEmpty()) {
values.add(subTypeOfUpperBounds);
}
for (JetType value : values) {
if (!JetTypeChecker.INSTANCE.isSubtypeOf(value, subTypeOfUpperBounds)) {
values.add(subTypeOfUpperBounds);
break;
}
}
if (values.isEmpty()) {
values.add(subTypeOfUpperBounds);
}
}
}
return values;
@@ -141,10 +141,10 @@ public class ConstraintsUtil {
assert typeConstraints != null;
JetType type = getValue(typeConstraints);
JetType upperBound = typeParameter.getUpperBoundsAsType();
JetType substitute = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
JetType substitutedType = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
if (type != null) {
if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) {
if (substitutedType == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitutedType)) {
return false;
}
}
@@ -153,14 +153,8 @@ public class ConstraintsUtil {
public static boolean checkBoundsAreSatisfied(@NotNull ConstraintSystem constraintSystem) {
for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) {
JetType type = getValue(constraintSystem.getTypeConstraints(typeVariable));
JetType upperBound = typeVariable.getUpperBoundsAsType();
JetType substitutedType = constraintSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
if (type != null) {
if (substitutedType == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitutedType)) {
return false;
}
if (!checkUpperBoundIsSatisfied(constraintSystem, typeVariable)) {
return false;
}
}
return true;
@@ -93,22 +93,6 @@ public class TypeConstraintsImpl implements TypeConstraints {
}
public static enum ConstraintKind {
SUB_TYPE, SUPER_TYPE, EQUAL;
@NotNull
static ConstraintKind fromVariance(@NotNull Variance variance) {
ConstraintKind constraintKind = null;
switch (variance) {
case INVARIANT:
constraintKind = EQUAL;
break;
case OUT_VARIANCE:
constraintKind = SUPER_TYPE;
break;
case IN_VARIANCE:
constraintKind = SUB_TYPE;
}
return constraintKind;
}
SUB_TYPE, SUPER_TYPE, EQUAL
}
}
@@ -42,7 +42,9 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
protected boolean allDescriptorsComputed = false;
private final Map<Name, ClassDescriptor> classDescriptors = Maps.newHashMap();
private final Map<Name, Set<FunctionDescriptor>> functionDescriptors = Maps.newHashMap();
private final Map<Name, ClassDescriptor> objectDescriptors = Maps.newHashMap();
protected final Map<Name, Set<FunctionDescriptor>> functionDescriptors = Maps.newHashMap();
private final Map<Name, Set<VariableDescriptor>> propertyDescriptors = Maps.newHashMap();
protected final List<DeclarationDescriptor> allDescriptors = Lists.newArrayList();
@@ -58,8 +60,8 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
}
@Nullable
private ClassDescriptor getClassOrObjectDescriptor(@NotNull Name name, boolean object) {
ClassDescriptor known = classDescriptors.get(name);
private ClassDescriptor getClassOrObjectDescriptor(@NotNull Map<Name, ClassDescriptor> cache, @NotNull Name name, boolean object) {
ClassDescriptor known = cache.get(name);
if (known != null) return known;
if (allDescriptorsComputed) return null;
@@ -67,12 +69,13 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
if (classOrObjectDeclaration == null) return null;
if (object != classOrObjectDeclaration instanceof JetObjectDeclaration) return null;
// TODO: when enum entries with constructors are dropped, replace with declaresObjectOrEnumConstant()
if (object != mayDeclareObject(classOrObjectDeclaration)) return null;
ClassDescriptor classDescriptor = new LazyClassDescriptor(resolveSession, thisDescriptor, name,
JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration));
JetClassInfoUtil.createClassLikeInfo(classOrObjectDeclaration));
classDescriptors.put(name, classDescriptor);
cache.put(name, classDescriptor);
if (!object) {
allDescriptors.add(classDescriptor);
}
@@ -80,15 +83,25 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
return classDescriptor;
}
private static boolean mayDeclareObject(JetClassOrObject declaration) {
return declaration instanceof JetObjectDeclaration || declaration instanceof JetEnumEntry;
}
protected static boolean declaresObjectOrEnumConstant(JetClassOrObject declaration) {
if (declaration instanceof JetObjectDeclaration) {
return true;
}
return declaration instanceof JetEnumEntry && !declaration.hasPrimaryConstructor();
}
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
return getClassOrObjectDescriptor(name, false);
return getClassOrObjectDescriptor(classDescriptors, name, false);
}
@Override
public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
// TODO: We shouldn't really allow objects in classes...
return getClassOrObjectDescriptor(name, true);
return getClassOrObjectDescriptor(objectDescriptors, name, true);
}
@NotNull
@@ -145,14 +158,13 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
// Objects are also properties
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
if (classOrObjectDeclaration instanceof JetObjectDeclaration) {
JetObjectDeclaration objectDeclaration = (JetObjectDeclaration) classOrObjectDeclaration;
if (declaresObjectOrEnumConstant(classOrObjectDeclaration)) {
ClassDescriptor classifier = getObjectDescriptor(name);
if (classifier == null) {
throw new IllegalStateException("Object declaration " + name + " found in the DeclarationProvider " + declarationProvider + " but not in the scope " + this);
}
VariableDescriptor propertyDescriptor = resolveSession.getInjector().getDescriptorResolver()
.resolveObjectDeclaration(thisDescriptor, objectDeclaration, classifier, resolveSession.getTrace());
.resolveObjectDeclaration(thisDescriptor, classOrObjectDeclaration, classifier, resolveSession.getTrace());
result.add(propertyDescriptor);
}
@@ -170,7 +182,8 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
@NotNull
@Override
public Collection<ClassDescriptor> getObjectDescriptors() {
throw new UnsupportedOperationException(); // TODO
getAllDescriptors();
return objectDescriptors.values();
}
@Override
@@ -199,49 +212,53 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
for (JetDeclaration declaration : declarationProvider.getAllDeclarations()) {
if (declaration instanceof JetEnumEntry) {
JetEnumEntry jetEnumEntry = (JetEnumEntry) declaration;
Name name = jetEnumEntry.getNameAsName();
if (name != null) {
getProperties(name);
if (!allDescriptorsComputed) {
for (JetDeclaration declaration : declarationProvider.getAllDeclarations()) {
if (declaration instanceof JetEnumEntry) {
JetEnumEntry jetEnumEntry = (JetEnumEntry) declaration;
Name name = jetEnumEntry.getNameAsName();
if (name != null) {
getProperties(name);
getObjectDescriptor(name);
}
}
else if (declaration instanceof JetObjectDeclaration) {
JetClassOrObject classOrObject = (JetClassOrObject) declaration;
Name name = classOrObject.getNameAsName();
if (name != null) {
getProperties(name);
getObjectDescriptor(name);
}
}
else if (declaration instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) declaration;
Name name = classOrObject.getNameAsName();
if (name != null) {
getClassifier(name);
}
}
else if (declaration instanceof JetFunction) {
JetFunction function = (JetFunction) declaration;
getFunctions(function.getNameAsSafeName());
}
else if (declaration instanceof JetProperty) {
JetProperty property = (JetProperty) declaration;
getProperties(property.getNameAsSafeName());
}
else if (declaration instanceof JetParameter) {
JetParameter parameter = (JetParameter) declaration;
Name name = parameter.getNameAsName();
if (name != null) {
getProperties(name);
}
}
else {
throw new IllegalArgumentException("Unsupported declaration kind: " + declaration);
}
}
else if (declaration instanceof JetObjectDeclaration) {
JetClassOrObject classOrObject = (JetClassOrObject) declaration;
Name name = classOrObject.getNameAsName();
if (name != null) {
getProperties(name);
}
}
else if (declaration instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) declaration;
Name name = classOrObject.getNameAsName();
if (name != null) {
getClassifier(name);
}
}
else if (declaration instanceof JetFunction) {
JetFunction function = (JetFunction) declaration;
getFunctions(function.getNameAsSafeName());
}
else if (declaration instanceof JetProperty) {
JetProperty property = (JetProperty) declaration;
getProperties(property.getNameAsSafeName());
}
else if (declaration instanceof JetParameter) {
JetParameter parameter = (JetParameter) declaration;
Name name = parameter.getNameAsName();
if (name != null) {
getProperties(name);
}
}
else {
throw new IllegalArgumentException("Unsupported declaration kind: " + declaration);
}
addExtraDescriptors();
allDescriptorsComputed = true;
}
addExtraDescriptors();
allDescriptorsComputed = true;
return allDescriptors;
}
@@ -86,6 +86,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@NotNull JetClassLikeInfo classLikeInfo
) {
this.resolveSession = resolveSession;
this.name = name;
if (classLikeInfo.getCorrespondingClassOrObject() != null) {
this.resolveSession.getTrace().record(BindingContext.CLASS, classLikeInfo.getCorrespondingClassOrObject(), this);
@@ -95,7 +96,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
JetClassLikeInfo classLikeInfoForMembers =
classLikeInfo.getClassKind() != ClassKind.ENUM_CLASS ? classLikeInfo : noEnumEntries(classLikeInfo);
this.declarationProvider = resolveSession.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfoForMembers);
this.name = name;
this.containingDeclaration = containingDeclaration;
this.unsubstitutedMemberScope = new LazyClassMemberScope(resolveSession, declarationProvider, this);
this.unsubstitutedInnerClassesScope = new InnerClassesScopeWrapper(unsubstitutedMemberScope);
@@ -130,12 +130,13 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
public JetScope getScopeForClassHeaderResolution() {
if (scopeForClassHeaderResolution == null) {
WritableScopeImpl scope = new WritableScopeImpl(
resolveSession.getResolutionScope(declarationProvider.getOwnerInfo().getScopeAnchor()), this, RedeclarationHandler.DO_NOTHING, "Class Header Resolution");
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Class Header Resolution");
for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
scope.addClassifierDescriptor(typeParameterDescriptor);
}
scope.changeLockLevel(WritableScope.LockLevel.READING);
scopeForClassHeaderResolution = scope;
scopeForClassHeaderResolution = new ChainedScope(this, scope, resolveSession.getResolutionScope(declarationProvider.getOwnerInfo().getScopeAnchor()));
}
return scopeForClassHeaderResolution;
}
@@ -143,12 +144,11 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
public JetScope getScopeForMemberDeclarationResolution() {
if (scopeForMemberDeclarationResolution == null) {
WritableScopeImpl scope = new WritableScopeImpl(
getScopeForMemberLookup(), this, RedeclarationHandler.DO_NOTHING, "Member Declaration Resolution");
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Member Declaration Resolution");
scope.addLabeledDeclaration(this);
scope.importScope(getScopeForClassHeaderResolution());
scope.changeLockLevel(WritableScope.LockLevel.READING);
scopeForMemberDeclarationResolution = scope;
scopeForMemberDeclarationResolution = new ChainedScope(this, scope, getScopeForMemberLookup(), getScopeForClassHeaderResolution());
}
return scopeForMemberDeclarationResolution;
}
@@ -159,7 +159,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
if (scopeForPropertyInitializerResolution == null) {
WritableScopeImpl scope = new WritableScopeImpl(
getScopeForMemberDeclarationResolution(), this, RedeclarationHandler.DO_NOTHING, "Property Initializer Resolution");
JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Property Initializer Resolution");
List<ValueParameterDescriptor> parameters = primaryConstructor.getValueParameters();
for (ValueParameterDescriptor valueParameterDescriptor : parameters) {
@@ -167,7 +167,8 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
}
scope.changeLockLevel(WritableScope.LockLevel.READING);
scopeForPropertyInitializerResolution = scope;
scopeForPropertyInitializerResolution = new ChainedScope(this, scope, getScopeForMemberDeclarationResolution());
}
return scopeForPropertyInitializerResolution;
}
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve.lazy;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -141,6 +142,26 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
generateFakeOverrides(name, fromSupertypes, result, FunctionDescriptor.class);
}
private void generateEnumClassObjectMethods() {
DeclarationDescriptor containingDeclaration = thisDescriptor.getContainingDeclaration();
if(containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
if(classDescriptor.getKind() == ClassKind.ENUM_CLASS) {
if(classDescriptor.getClassObjectDescriptor() == thisDescriptor) {
SimpleFunctionDescriptor valuesMethod = DescriptorResolver
.createEnumClassObjectValuesMethod(classDescriptor, thisDescriptor, resolveSession.getTrace());
functionDescriptors.put(valuesMethod.getName(), Collections.<FunctionDescriptor>singleton(valuesMethod));
allDescriptors.add(valuesMethod);
SimpleFunctionDescriptor valueOfMethod = DescriptorResolver.createEnumClassObjectValueOfMethod(classDescriptor,
thisDescriptor,
resolveSession.getTrace());
functionDescriptors.put(valueOfMethod.getName(), Collections.<FunctionDescriptor>singleton(valueOfMethod));
allDescriptors.add(valueOfMethod);
}
}
}
}
@NotNull
@Override
public Set<VariableDescriptor> getProperties(@NotNull Name name) {
@@ -182,22 +203,6 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
}
}
// Enum entries
JetClassOrObject classOrObjectDeclaration = declarationProvider.getClassOrObjectDeclaration(name);
if (classOrObjectDeclaration instanceof JetEnumEntry) {
// TODO: This code seems to be wrong, but it mimics the present behavior of eager resolve
JetEnumEntry jetEnumEntry = (JetEnumEntry) classOrObjectDeclaration;
if (!jetEnumEntry.hasPrimaryConstructor()) {
VariableDescriptor propertyDescriptor = resolveSession.getInjector().getDescriptorResolver()
.resolveObjectDeclarationAsPropertyDescriptor(thisDescriptor,
jetEnumEntry,
resolveSession.getClassDescriptor(jetEnumEntry),
resolveSession.getTrace());
result.add(propertyDescriptor);
}
}
// Members from supertypes
Collection<PropertyDescriptor> fromSupertypes = Lists.newArrayList();
for (JetType supertype : thisDescriptor.getTypeConstructor().getSupertypes()) {
@@ -242,6 +247,8 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
// Nothing else is inherited
}
}
generateEnumClassObjectMethods();
}
@Override
@@ -264,9 +271,14 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
@Nullable
public ConstructorDescriptor getPrimaryConstructor() {
if (!primaryConstructorResolved) {
if (EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT, ClassKind.ENUM_CLASS).contains(thisDescriptor.getKind())) {
Set<ClassKind> generateConstructorsFor =
EnumSet.of(ClassKind.CLASS, ClassKind.ANNOTATION_CLASS, ClassKind.OBJECT, ClassKind.ENUM_CLASS, ClassKind.ENUM_ENTRY);
if (generateConstructorsFor.contains(thisDescriptor.getKind())) {
JetClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
if (thisDescriptor.getKind() != ClassKind.OBJECT) {
if (
thisDescriptor.getKind() != ClassKind.OBJECT // a fake class object of an enum class
&& !declaresObjectOrEnumConstant(classOrObject) // normal objects and enum entries with no constructors
) {
JetClass jetClass = (JetClass) classOrObject;
ConstructorDescriptorImpl constructor = resolveSession.getInjector().getDescriptorResolver()
.resolvePrimaryConstructorDescriptor(thisDescriptor.getScopeForClassHeaderResolution(),
@@ -24,10 +24,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.*;
import java.util.Collections;
@@ -44,12 +41,14 @@ public class LazyPackageDescriptor extends AbstractNamespaceDescriptorImpl imple
@NotNull PackageMemberDeclarationProvider declarationProvider
) {
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), name);
WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Package scope");
resolveSession.getModuleConfiguration().extendNamespaceScope(resolveSession.getTrace(), this, scope);
LazyPackageMemberScope lazyPackageMemberScope = new LazyPackageMemberScope(resolveSession, declarationProvider, this);
scope.importScope(lazyPackageMemberScope);
scope.changeLockLevel(WritableScope.LockLevel.READING);
this.memberScope = scope;
LazyPackageMemberScope lazyPackageMemberScope = new LazyPackageMemberScope(resolveSession, declarationProvider, this);
this.memberScope = new ChainedScope(containingDeclaration, lazyPackageMemberScope, scope);
}
@NotNull
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.lazy;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -32,7 +31,6 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -40,7 +38,6 @@ import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.List;
import java.util.Map;
/**
* @author abreslav
@@ -66,7 +63,6 @@ public class ResolveSession {
private final InjectorForLazyResolve injector;
private final ModuleConfiguration moduleConfiguration;
private final Map<JetEnumEntry, ClassDescriptor> enumEntryClassDescriptorCache = Maps.newHashMap();
private final Function<FqName, Name> classifierAliases;
public ResolveSession(
@@ -136,10 +132,6 @@ public class ResolveSession {
@NotNull
public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) {
if (classOrObject instanceof JetEnumEntry) {
JetEnumEntry enumEntry = (JetEnumEntry) classOrObject;
return getEnumEntryClassDescriptor(enumEntry);
}
if (classOrObject.getParent() instanceof JetClassObject) {
return getClassObjectDescriptor((JetClassObject) classOrObject.getParent());
}
@@ -147,29 +139,15 @@ public class ResolveSession {
Name name = classOrObject.getNameAsName();
assert name != null : "Name is null for " + classOrObject + " " + classOrObject.getText();
ClassifierDescriptor classifier = resolutionScope.getClassifier(name);
if (classifier == null) {
classifier = resolutionScope.getObjectDescriptor(name);
}
if (classifier == null) {
throw new IllegalArgumentException("Could not find a classifier for " + classOrObject + " " + classOrObject.getText());
}
return (ClassDescriptor) classifier;
}
@NotNull
private ClassDescriptor getEnumEntryClassDescriptor(@NotNull JetEnumEntry jetEnumEntry) {
ClassDescriptor classDescriptor = enumEntryClassDescriptorCache.get(jetEnumEntry);
if (classDescriptor != null) {
return classDescriptor;
}
DeclarationDescriptor containingDeclaration = getInjector().getScopeProvider().getResolutionScopeForDeclaration(jetEnumEntry)
.getContainingDeclaration();
LazyClassDescriptor newClassDescriptor = new LazyClassDescriptor(this,
containingDeclaration,
jetEnumEntry.getNameAsName(),
JetClassInfoUtil.createClassLikeInfo(jetEnumEntry));
enumEntryClassDescriptorCache.put(jetEnumEntry, newClassDescriptor);
return newClassDescriptor;
}
/*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) {
LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class));
LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor();
@@ -21,23 +21,14 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import java.util.List;
import org.jetbrains.jet.lang.resolve.scopes.*;
/**
* @author abreslav
*/
* @author abreslav
*/
public class ScopeProvider {
private final ResolveSession resolveSession;
@@ -62,9 +53,10 @@ public class ScopeProvider {
throw new IllegalStateException("Package not found: " + fqName + " maybe the file is not in scope of this resolve session: " + file.getName());
}
WritableScope writableScope = new WritableScopeImpl(
WritableScope fileScope = new WritableScopeImpl(
JetScope.EMPTY, packageDescriptor, RedeclarationHandler.DO_NOTHING, "File scope for declaration resolution");
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH);
fileScope.changeLockLevel(WritableScope.LockLevel.BOTH);
NamespaceDescriptor rootPackageDescriptor = resolveSession.getPackageDescriptorByFqName(FqName.ROOT);
if (rootPackageDescriptor == null) {
@@ -73,37 +65,18 @@ public class ScopeProvider {
// Don't import twice
if (!packageDescriptor.getQualifiedName().equals(FqName.ROOT)) {
writableScope.importScope(rootPackageDescriptor.getMemberScope());
fileScope.importScope(rootPackageDescriptor.getMemberScope());
}
List<JetImportDirective> importDirectives = getFileImports(file);
ImportsResolver.processImportsInFile(true, writableScope, importDirectives,
ImportsResolver.processImportsInFile(true, fileScope, Lists.newArrayList(file.getImportDirectives()),
rootPackageDescriptor.getMemberScope(),
resolveSession.getModuleConfiguration(), resolveSession.getTrace(),
resolveSession.getInjector().getQualifiedExpressionResolver());
writableScope.importScope(packageDescriptor.getMemberScope());
fileScope.changeLockLevel(WritableScope.LockLevel.READING);
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
// TODO: Cache
return writableScope;
}
public static List<JetImportDirective> getFileImports(JetFile file) {
List<JetImportDirective> fileImports = file.getImportDirectives();
List<JetImportDirective> importDirectives = Lists.newArrayList();
if(file.isScript()) {
JetScriptDefinition definition = JetScriptDefinitionProvider.getInstance(file.getProject()).findScriptDefinition(file);
List<ImportPath> imports = definition.getImports();
if(!imports.isEmpty()) {
for (ImportPath importPath : imports) {
importDirectives.add(JetPsiFactory.createImportDirective(file.getProject(), importPath));
}
}
}
importDirectives.addAll(fileImports);
return importDirectives;
return new ChainedScope(packageDescriptor, packageDescriptor.getMemberScope(), fileScope);
}
@NotNull
@@ -131,4 +104,4 @@ public class ScopeProvider {
throw new IllegalStateException("Don't call this method for local declarations: " + jetDeclaration + " " + jetDeclaration.getText());
}
}
}
}
@@ -118,7 +118,7 @@ public class ChainedScope implements JetScope {
@NotNull
@Override
public ReceiverDescriptor getImplicitReceiver() {
throw new UnsupportedOperationException(); // TODO
return ReceiverDescriptor.NO_RECEIVER;
}
@Override
@@ -611,13 +611,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (!results.isNothing()) {
checkSuper(receiver, results, context.trace, callExpression);
result[0] = true;
if (results.isSingleResult()) {
ResolvedCall<FunctionDescriptor> resultingCall = results.getResultingCall();
if (resultingCall instanceof ResolvedCallWithTrace) {
if (((ResolvedCallWithTrace)resultingCall).getStatus() == ResolutionStatus.TYPE_INFERENCE_ERROR) {
return null;
}
}
if (results.isIncomplete()) {
return null;
}
return results.isSingleResult() ? results.getResultingDescriptor() : null;
}
@@ -135,8 +135,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType;
functionDescriptor.setReturnType(safeReturnType);
boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null;
if (!hasDeclaredValueParameters && functionTypeExpected) {
if (!functionLiteral.hasDeclaredReturnType() && functionTypeExpected) {
JetType expectedReturnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType);
if (JetStandardClasses.isUnit(expectedReturnType)) {
functionDescriptor.setReturnType(JetStandardClasses.getUnitType());
@@ -95,6 +95,7 @@ public class JetStandardLibrary {
private ClassDescriptor iterableClass;
private ClassDescriptor comparableClass;
private ClassDescriptor throwableClass;
private ClassDescriptor enumClass;
private JetType stringType;
@@ -115,7 +116,8 @@ public class JetStandardLibrary {
"Ranges.jet",
"Iterables.jet",
"Iterators.jet",
"Arrays.jet"
"Arrays.jet",
"Enum.jet"
);
try {
List<JetFile> files = new LinkedList<JetFile>();
@@ -163,6 +165,7 @@ public class JetStandardLibrary {
this.charSequenceClass = (ClassDescriptor) libraryScope.getClassifier(Name.identifier("CharSequence"));
this.arrayClass = (ClassDescriptor) libraryScope.getClassifier(Name.identifier("Array"));
this.throwableClass = (ClassDescriptor) libraryScope.getClassifier(Name.identifier("Throwable"));
this.enumClass = (ClassDescriptor) libraryScope.getClassifier(Name.identifier("Enum"));
this.iterableClass = (ClassDescriptor) libraryScope.getClassifier(Name.identifier("Iterable"));
this.comparableClass = (ClassDescriptor) libraryScope.getClassifier(Name.identifier("Comparable"));
@@ -208,6 +211,7 @@ public class JetStandardLibrary {
classDescriptors.add(throwableClass);
classDescriptors.add(iterableClass);
classDescriptors.add(comparableClass);
classDescriptors.add(enumClass);
return classDescriptors;
}
@@ -300,6 +304,12 @@ public class JetStandardLibrary {
return throwableClass;
}
@NotNull
public ClassDescriptor getEnum() {
initStdClasses();
return enumClass;
}
@NotNull
public JetType getPrimitiveJetType(PrimitiveType primitiveType) {
return primitiveTypeToJetType.get(primitiveType);
@@ -356,6 +366,11 @@ public class JetStandardLibrary {
return getArrayType(Variance.INVARIANT, argument);
}
@NotNull
public JetType getEnumType(@NotNull JetType argument) {
return getEnumType(Variance.INVARIANT, argument);
}
@NotNull
public JetType getArrayType(@NotNull Variance projectionType, @NotNull JetType argument) {
List<TypeProjection> types = Collections.singletonList(new TypeProjection(projectionType, argument));
@@ -368,6 +383,18 @@ public class JetStandardLibrary {
);
}
@NotNull
public JetType getEnumType(@NotNull Variance projectionType, @NotNull JetType argument) {
List<TypeProjection> types = Collections.singletonList(new TypeProjection(projectionType, argument));
return new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
getEnum().getTypeConstructor(),
false,
types,
getEnum().getMemberScope(types)
);
}
@NotNull
public JetType getArrayElementType(@NotNull JetType arrayType) {
// make non-null?
@@ -25,6 +25,9 @@ import org.jetbrains.jet.lang.types.ref.ClassName;
*/
public class JetStandardLibraryNames {
private JetStandardLibraryNames() {
}
@NotNull
private static ClassName classIn(@NotNull String name, int typeParameterCount) {
return new ClassName(
@@ -41,5 +44,5 @@ public class JetStandardLibraryNames {
public static final ClassName CHAR_SEQUENCE = classIn("CharSequence", 0);
public static final ClassName NUMBER = classIn("Number", 0);
public static final ClassName THROWABLE = classIn("Throwable", 0);
public static final ClassName ENUM = classIn("Enum", 1);
}
@@ -16,6 +16,7 @@
package org.jetbrains.jet.lang.types.lang;
import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.ref.ClassName;
@@ -34,17 +35,23 @@ public enum PrimitiveType {
LONG("Long"),
DOUBLE("Double"),
;
public static final ImmutableSet<PrimitiveType> NUMBER_TYPES = ImmutableSet.of(CHAR, BYTE, SHORT, INT, FLOAT, LONG, DOUBLE);
private final Name typeName;
private final Name arrayTypeName;
private final Name rangeTypeName;
private final ClassName className;
private final ClassName arrayClassName;
private final ClassName rangeClassName;
private PrimitiveType(String typeName) {
this.typeName = Name.identifier(typeName);
this.arrayTypeName = Name.identifier(typeName + "Array");
this.rangeTypeName = Name.identifier(typeName + "Range");
this.className = new ClassName(JetStandardClasses.STANDARD_CLASSES_FQNAME.child(this.typeName), 0);
this.arrayClassName = new ClassName(JetStandardClasses.STANDARD_CLASSES_FQNAME.child(this.arrayTypeName), 0);
this.rangeClassName = new ClassName(JetStandardClasses.STANDARD_CLASSES_FQNAME.child(this.rangeTypeName), 0);
}
@NotNull
@@ -57,6 +64,11 @@ public enum PrimitiveType {
return arrayTypeName;
}
@NotNull
public Name getRangeTypeName() {
return rangeTypeName;
}
@NotNull
public ClassName getClassName() {
return className;
@@ -66,4 +78,9 @@ public enum PrimitiveType {
public ClassName getArrayClassName() {
return arrayClassName;
}
@NotNull
public ClassName getRangeClassName() {
return rangeClassName;
}
}
@@ -46,7 +46,9 @@ import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.plugin.JetLanguage;
import org.jetbrains.jet.util.QualifiedNamesUtil;
@@ -178,7 +180,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa
throw new IllegalStateException("failed to analyze: " + context.getError(), context.getError());
}
final GenerationState state = new GenerationState(project, builderFactory, context, Collections.singletonList(file)) {
final GenerationState state = new GenerationState(builderFactory, context, Collections.singletonList(file)) {
@Override
protected void generateNamespace(FqName fqName, Collection<JetFile> namespaceFiles, CompilationErrorHandler errorHandler, Progress progress) {
PsiManager manager = PsiManager.getInstance(project);
@@ -236,6 +238,30 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa
}
}
@Override
public int hashCode() {
int result = getManager().hashCode();
result = 31 * result + file.hashCode();
result = 31 * result + qualifiedName.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) {
return false;
}
JetLightClass lightClass = (JetLightClass) obj;
if (getManager() != lightClass.getManager()) return false;
if (!file.equals(lightClass.file)) return false;
if (!qualifiedName.equals(lightClass.qualifiedName)) return false;
return true;
}
public static JetLightClass wrapDelegate(JetClass jetClass) {
return new JetLightClass(jetClass.getManager(), (JetFile) jetClass.getContainingFile(), JetPsiUtil.getFQName(jetClass));
}
+33 -105
View File
@@ -54,13 +54,6 @@ public final class jet.Byte : jet.Number, jet.Comparable<jet.Byte> {
public final fun div(/*0*/ other: jet.Int): jet.Int
public final fun div(/*0*/ other: jet.Long): jet.Long
public final fun div(/*0*/ other: jet.Short): jet.Int
public final fun downto(/*0*/ other: jet.Byte): jet.ByteRange
public final fun downto(/*0*/ other: jet.Char): jet.CharRange
public final fun downto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Float): jet.FloatRange
public final fun downto(/*0*/ other: jet.Int): jet.IntRange
public final fun downto(/*0*/ other: jet.Long): jet.LongRange
public final fun downto(/*0*/ other: jet.Short): jet.ShortRange
public open override /*1*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean
public open override /*1*/ fun hashCode(): jet.Int
public final fun inc(): jet.Byte
@@ -108,13 +101,6 @@ public final class jet.Byte : jet.Number, jet.Comparable<jet.Byte> {
public open override /*1*/ fun toInt(): jet.Int
public open override /*1*/ fun toLong(): jet.Long
public open override /*1*/ fun toShort(): jet.Short
public final fun upto(/*0*/ other: jet.Byte): jet.ByteRange
public final fun upto(/*0*/ other: jet.Char): jet.CharRange
public final fun upto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Float): jet.FloatRange
public final fun upto(/*0*/ other: jet.Int): jet.IntRange
public final fun upto(/*0*/ other: jet.Long): jet.LongRange
public final fun upto(/*0*/ other: jet.Short): jet.ShortRange
}
public final class jet.ByteArray : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ size: jet.Int): jet.ByteArray
@@ -140,10 +126,13 @@ public final class jet.ByteRange : jet.Range<jet.Byte>, jet.ByteIterable {
public final val isReversed: jet.Boolean
public open override /*1*/ fun iterator(): jet.ByteIterator
public final val iteratorStart: jet.Byte
public final fun minus(): jet.ByteRange
public final val size: jet.Int
public final val start: jet.Byte
public final fun step(/*0*/ step: jet.Int): jet.ByteIterator
public final class object jet.ByteRange.<no name provided> : jet.Any {
internal final /*constructor*/ fun <init>(): jet.ByteRange.<no name provided>
public final val EMPTY: jet.ByteRange
}
}
public final class jet.Char : jet.Number, jet.Comparable<jet.Char> {
public final /*constructor*/ fun <init>(): jet.Char
@@ -161,13 +150,6 @@ public final class jet.Char : jet.Number, jet.Comparable<jet.Char> {
public final fun div(/*0*/ other: jet.Int): jet.Int
public final fun div(/*0*/ other: jet.Long): jet.Long
public final fun div(/*0*/ other: jet.Short): jet.Int
public final fun downto(/*0*/ other: jet.Byte): jet.CharRange
public final fun downto(/*0*/ other: jet.Char): jet.CharRange
public final fun downto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Float): jet.FloatRange
public final fun downto(/*0*/ other: jet.Int): jet.IntRange
public final fun downto(/*0*/ other: jet.Long): jet.LongRange
public final fun downto(/*0*/ other: jet.Short): jet.ShortRange
public open override /*1*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean
public open override /*1*/ fun hashCode(): jet.Int
public final fun inc(): jet.Char
@@ -212,13 +194,6 @@ public final class jet.Char : jet.Number, jet.Comparable<jet.Char> {
public open override /*1*/ fun toInt(): jet.Int
public open override /*1*/ fun toLong(): jet.Long
public open override /*1*/ fun toShort(): jet.Short
public final fun upto(/*0*/ other: jet.Byte): jet.CharRange
public final fun upto(/*0*/ other: jet.Char): jet.CharRange
public final fun upto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Float): jet.FloatRange
public final fun upto(/*0*/ other: jet.Int): jet.IntRange
public final fun upto(/*0*/ other: jet.Long): jet.LongRange
public final fun upto(/*0*/ other: jet.Short): jet.ShortRange
}
public final class jet.CharArray : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ size: jet.Int): jet.CharArray
@@ -244,10 +219,13 @@ public final class jet.CharRange : jet.Range<jet.Char>, jet.CharIterable {
public final val isReversed: jet.Boolean
public open override /*1*/ fun iterator(): jet.CharIterator
public final val iteratorStart: jet.Char
public final fun minus(): jet.CharRange
public final val size: jet.Int
public final val start: jet.Char
public final fun step(/*0*/ step: jet.Int): jet.CharIterator
public final class object jet.CharRange.<no name provided> : jet.Any {
internal final /*constructor*/ fun <init>(): jet.CharRange.<no name provided>
public final val EMPTY: jet.CharRange
}
}
public abstract trait jet.CharSequence : jet.Any {
public abstract fun get(/*0*/ index: jet.Int): jet.Char
@@ -274,13 +252,6 @@ public final class jet.Double : jet.Number, jet.Comparable<jet.Double> {
public final fun div(/*0*/ other: jet.Int): jet.Double
public final fun div(/*0*/ other: jet.Long): jet.Double
public final fun div(/*0*/ other: jet.Short): jet.Double
public final fun downto(/*0*/ other: jet.Byte): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Char): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Float): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Int): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Long): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Short): jet.DoubleRange
public open override /*1*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean
public open override /*1*/ fun hashCode(): jet.Int
public final fun inc(): jet.Double
@@ -327,13 +298,6 @@ public final class jet.Double : jet.Number, jet.Comparable<jet.Double> {
public open override /*1*/ fun toInt(): jet.Int
public open override /*1*/ fun toLong(): jet.Long
public open override /*1*/ fun toShort(): jet.Short
public final fun upto(/*0*/ other: jet.Byte): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Char): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Float): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Int): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Long): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Short): jet.DoubleRange
}
public final class jet.DoubleArray : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ size: jet.Int): jet.DoubleArray
@@ -357,10 +321,18 @@ public final class jet.DoubleRange : jet.Range<jet.Double> {
public open override /*1*/ fun contains(/*0*/ elem: jet.Double): jet.Boolean
public final val end: jet.Double
public final val isReversed: jet.Boolean
public final fun minus(): jet.DoubleRange
public final val size: jet.Double
public final val start: jet.Double
public final fun step(/*0*/ step: jet.Double): jet.DoubleIterator
public final class object jet.DoubleRange.<no name provided> : jet.Any {
internal final /*constructor*/ fun <init>(): jet.DoubleRange.<no name provided>
public final val EMPTY: jet.DoubleRange
}
}
public abstract class jet.Enum</*0*/ E : jet.Enum<E>> : jet.Any {
public final /*constructor*/ fun </*0*/ E : jet.Enum<E>><init>(/*0*/ name: jet.String, /*1*/ ordinal: jet.Int): jet.Enum<E>
public final fun name(): jet.String
public final fun ordinal(): jet.Int
}
public abstract class jet.ExtensionFunction0</*0*/ in T : jet.Any?, /*1*/ out R : jet.Any?> : jet.Any {
public final /*constructor*/ fun </*0*/ in T : jet.Any?, /*1*/ out R : jet.Any?><init>(): jet.ExtensionFunction0<T, R>
@@ -471,13 +443,6 @@ public final class jet.Float : jet.Number, jet.Comparable<jet.Float> {
public final fun div(/*0*/ other: jet.Int): jet.Float
public final fun div(/*0*/ other: jet.Long): jet.Float
public final fun div(/*0*/ other: jet.Short): jet.Float
public final fun downto(/*0*/ other: jet.Byte): jet.FloatRange
public final fun downto(/*0*/ other: jet.Char): jet.FloatRange
public final fun downto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Float): jet.FloatRange
public final fun downto(/*0*/ other: jet.Int): jet.FloatRange
public final fun downto(/*0*/ other: jet.Long): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Short): jet.FloatRange
public open override /*1*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean
public open override /*1*/ fun hashCode(): jet.Int
public final fun inc(): jet.Float
@@ -525,13 +490,6 @@ public final class jet.Float : jet.Number, jet.Comparable<jet.Float> {
public open override /*1*/ fun toInt(): jet.Int
public open override /*1*/ fun toLong(): jet.Long
public open override /*1*/ fun toShort(): jet.Short
public final fun upto(/*0*/ other: jet.Byte): jet.FloatRange
public final fun upto(/*0*/ other: jet.Char): jet.FloatRange
public final fun upto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Float): jet.FloatRange
public final fun upto(/*0*/ other: jet.Int): jet.FloatRange
public final fun upto(/*0*/ other: jet.Long): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Short): jet.FloatRange
}
public final class jet.FloatArray : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ size: jet.Int): jet.FloatArray
@@ -555,10 +513,13 @@ public final class jet.FloatRange : jet.Range<jet.Float> {
public open override /*1*/ fun contains(/*0*/ elem: jet.Float): jet.Boolean
public final val end: jet.Float
public final val isReversed: jet.Boolean
public final fun minus(): jet.FloatRange
public final val size: jet.Float
public final val start: jet.Float
public final fun step(/*0*/ step: jet.Float): jet.FloatIterator
public final class object jet.FloatRange.<no name provided> : jet.Any {
internal final /*constructor*/ fun <init>(): jet.FloatRange.<no name provided>
public final val EMPTY: jet.FloatRange
}
}
public abstract class jet.Function0</*0*/ out R : jet.Any?> : jet.Any {
public final /*constructor*/ fun </*0*/ out R : jet.Any?><init>(): jet.Function0<R>
@@ -674,13 +635,6 @@ public final class jet.Int : jet.Number, jet.Comparable<jet.Int> {
public final fun div(/*0*/ other: jet.Int): jet.Int
public final fun div(/*0*/ other: jet.Long): jet.Long
public final fun div(/*0*/ other: jet.Short): jet.Int
public final fun downto(/*0*/ other: jet.Byte): jet.IntRange
public final fun downto(/*0*/ other: jet.Char): jet.IntRange
public final fun downto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Float): jet.FloatRange
public final fun downto(/*0*/ other: jet.Int): jet.IntRange
public final fun downto(/*0*/ other: jet.Long): jet.LongRange
public final fun downto(/*0*/ other: jet.Short): jet.IntRange
public open override /*1*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean
public open override /*1*/ fun hashCode(): jet.Int
public final fun inc(): jet.Int
@@ -732,13 +686,6 @@ public final class jet.Int : jet.Number, jet.Comparable<jet.Int> {
public open override /*1*/ fun toInt(): jet.Int
public open override /*1*/ fun toLong(): jet.Long
public open override /*1*/ fun toShort(): jet.Short
public final fun upto(/*0*/ other: jet.Byte): jet.IntRange
public final fun upto(/*0*/ other: jet.Char): jet.IntRange
public final fun upto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Float): jet.FloatRange
public final fun upto(/*0*/ other: jet.Int): jet.IntRange
public final fun upto(/*0*/ other: jet.Long): jet.LongRange
public final fun upto(/*0*/ other: jet.Short): jet.IntRange
public final fun ushr(/*0*/ bits: jet.Int): jet.Int
public final fun xor(/*0*/ other: jet.Int): jet.Int
}
@@ -766,10 +713,13 @@ public final class jet.IntRange : jet.Range<jet.Int>, jet.IntIterable {
public final val isReversed: jet.Boolean
public open override /*1*/ fun iterator(): jet.IntIterator
public final val iteratorStart: jet.Int
public final fun minus(): jet.IntRange
public final val size: jet.Int
public final val start: jet.Int
public final fun step(/*0*/ step: jet.Int): jet.IntIterator
public final class object jet.IntRange.<no name provided> : jet.Any {
internal final /*constructor*/ fun <init>(): jet.IntRange.<no name provided>
public final val EMPTY: jet.IntRange
}
}
public abstract trait jet.Iterable</*0*/ out T : jet.Any?> : jet.Any {
public abstract fun iterator(): jet.Iterator<T>
@@ -796,13 +746,6 @@ public final class jet.Long : jet.Number, jet.Comparable<jet.Long> {
public final fun div(/*0*/ other: jet.Int): jet.Long
public final fun div(/*0*/ other: jet.Long): jet.Long
public final fun div(/*0*/ other: jet.Short): jet.Long
public final fun downto(/*0*/ other: jet.Byte): jet.LongRange
public final fun downto(/*0*/ other: jet.Char): jet.LongRange
public final fun downto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Float): jet.FloatRange
public final fun downto(/*0*/ other: jet.Int): jet.LongRange
public final fun downto(/*0*/ other: jet.Long): jet.LongRange
public final fun downto(/*0*/ other: jet.Short): jet.LongRange
public open override /*1*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean
public open override /*1*/ fun hashCode(): jet.Int
public final fun inc(): jet.Long
@@ -854,13 +797,6 @@ public final class jet.Long : jet.Number, jet.Comparable<jet.Long> {
public open override /*1*/ fun toInt(): jet.Int
public open override /*1*/ fun toLong(): jet.Long
public open override /*1*/ fun toShort(): jet.Short
public final fun upto(/*0*/ other: jet.Byte): jet.LongRange
public final fun upto(/*0*/ other: jet.Char): jet.LongRange
public final fun upto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Float): jet.FloatRange
public final fun upto(/*0*/ other: jet.Int): jet.LongRange
public final fun upto(/*0*/ other: jet.Long): jet.LongRange
public final fun upto(/*0*/ other: jet.Short): jet.LongRange
public final fun ushr(/*0*/ bits: jet.Int): jet.Long
public final fun xor(/*0*/ other: jet.Long): jet.Long
}
@@ -888,10 +824,13 @@ public final class jet.LongRange : jet.Range<jet.Long>, jet.LongIterable {
public final val isReversed: jet.Boolean
public open override /*1*/ fun iterator(): jet.LongIterator
public final val iteratorStart: jet.Long
public final fun minus(): jet.LongRange
public final val size: jet.Long
public final val start: jet.Long
public final fun step(/*0*/ step: jet.Long): jet.LongIterator
public final class object jet.LongRange.<no name provided> : jet.Any {
internal final /*constructor*/ fun <init>(): jet.LongRange.<no name provided>
public final val EMPTY: jet.LongRange
}
}
public final class jet.Nothing {
private final /*constructor*/ fun <init>(): jet.Nothing
@@ -928,13 +867,6 @@ public final class jet.Short : jet.Number, jet.Comparable<jet.Short> {
public final fun div(/*0*/ other: jet.Int): jet.Int
public final fun div(/*0*/ other: jet.Long): jet.Long
public final fun div(/*0*/ other: jet.Short): jet.Int
public final fun downto(/*0*/ other: jet.Byte): jet.ShortRange
public final fun downto(/*0*/ other: jet.Char): jet.ShortRange
public final fun downto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun downto(/*0*/ other: jet.Float): jet.FloatRange
public final fun downto(/*0*/ other: jet.Int): jet.IntRange
public final fun downto(/*0*/ other: jet.Long): jet.LongRange
public final fun downto(/*0*/ other: jet.Short): jet.ShortRange
public open override /*1*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean
public open override /*1*/ fun hashCode(): jet.Int
public final fun inc(): jet.Short
@@ -982,13 +914,6 @@ public final class jet.Short : jet.Number, jet.Comparable<jet.Short> {
public open override /*1*/ fun toInt(): jet.Int
public open override /*1*/ fun toLong(): jet.Long
public open override /*1*/ fun toShort(): jet.Short
public final fun upto(/*0*/ other: jet.Byte): jet.ShortRange
public final fun upto(/*0*/ other: jet.Char): jet.ShortRange
public final fun upto(/*0*/ other: jet.Double): jet.DoubleRange
public final fun upto(/*0*/ other: jet.Float): jet.FloatRange
public final fun upto(/*0*/ other: jet.Int): jet.IntRange
public final fun upto(/*0*/ other: jet.Long): jet.LongRange
public final fun upto(/*0*/ other: jet.Short): jet.ShortRange
}
public final class jet.ShortArray : jet.Any {
public final /*constructor*/ fun <init>(/*0*/ size: jet.Int): jet.ShortArray
@@ -1014,10 +939,13 @@ public final class jet.ShortRange : jet.Range<jet.Short>, jet.ShortIterable {
public final val isReversed: jet.Boolean
public open override /*1*/ fun iterator(): jet.ShortIterator
public final val iteratorStart: jet.Short
public final fun minus(): jet.ShortRange
public final val size: jet.Int
public final val start: jet.Short
public final fun step(/*0*/ step: jet.Int): jet.ShortIterator
public final class object jet.ShortRange.<no name provided> : jet.Any {
internal final /*constructor*/ fun <init>(): jet.ShortRange.<no name provided>
public final val EMPTY: jet.ShortRange
}
}
public final class jet.String : jet.Comparable<jet.String>, jet.CharSequence {
public final /*constructor*/ fun <init>(): jet.String
@@ -0,0 +1,19 @@
fun box() : String {
try {
} finally {
try {
try {
} finally {
try {
} finally {
}
}
} catch (e: Exception) {
try {
} catch (f: Exception) {
} finally {
}
}
return "OK"
}
}
+24
View File
@@ -0,0 +1,24 @@
fun box(): String {
if (IntRange(0, 0) != IntRange.EMPTY) {
return IntRange.EMPTY.toString()
}
if (CharRange(0.toChar(), 0) != CharRange.EMPTY) {
return CharRange.EMPTY.toString()
}
if (ByteRange(0, 0) != ByteRange.EMPTY) {
return ByteRange.EMPTY.toString()
}
if (ShortRange(0, 0) != ShortRange.EMPTY) {
return ShortRange.EMPTY.toString()
}
if (FloatRange(0.toFloat(), 0.toFloat()) != FloatRange.EMPTY) {
return FloatRange.EMPTY.toString()
}
if (LongRange(0, 0) != LongRange.EMPTY) {
return LongRange.EMPTY.toString()
}
if (DoubleRange(0.0, 0.0) != DoubleRange.EMPTY) {
return DoubleRange.EMPTY.toString()
}
return "OK"
}
@@ -0,0 +1,14 @@
package test
enum class Season {
WINTER
SPRING
SUMMER
AUTUMN
}
fun foo(): Season = Season.SPRING
fun box() =
if (foo() == Season.SPRING) "OK"
else "fail"
+6
View File
@@ -0,0 +1,6 @@
enum class State {
O
K
}
fun box() = "${State.O.name()}${State.K.name()}"
@@ -0,0 +1,8 @@
enum class State {
_0
_1
_2
_3
}
fun box() = if(State._0.ordinal()==0 && State._1.ordinal() == 1 && State._2.ordinal() == 2 && State._3.ordinal() == 3) "OK" else "fail"
@@ -0,0 +1,6 @@
enum class State {
O
K
}
fun box() = "${State.O}${State.K}"
+11
View File
@@ -0,0 +1,11 @@
enum class Color {
RED
BLUE
}
fun box() = if(
Color.valueOf("RED") == Color.RED
&& Color.valueOf("BLUE") == Color.BLUE
&& Color.values()[0] == Color.RED
&& Color.values()[1] == Color.BLUE
) "OK" else "fail"
@@ -0,0 +1,7 @@
trait A {
fun foo(x: Int, y: Int = x + 20, z: Int = y * 2) = z
}
class B : A {}
fun box() = if (B().foo(1) == 42) "OK" else "Fail"
@@ -0,0 +1,5 @@
class A(val expected: Int) {
fun foo(x: Int, y: Int = x + 20, z: Int = y * 2) = z == expected
}
fun box() = if (A(42).foo(1)) "OK" else "Fail"
@@ -1,10 +1,10 @@
fun box() : String {
var cnt = 0
for (len in 4 downto 1) {
for (len in 4 downTo 1) {
cnt++
}
for (n in -(1..5))
for (n in (1..5).reversed)
cnt++
return if(cnt == 9) "OK" else cnt.toString()
@@ -0,0 +1 @@
fun box() = foo()
@@ -0,0 +1,4 @@
private val a = "OK"
fun foo() : String {
return "${a}"
}
@@ -0,0 +1,3 @@
fun main(args: Array<String>) {
kotlin.assert(true)
}
@@ -0,0 +1,10 @@
fun main(args: Array<String>) {
try {
} finally {
try {
} catch (e: Throwable) {
}
}
}
fun box() = "OK"
@@ -0,0 +1,6 @@
class A(
val i : Int,
val j : Int = i
)
fun box() = if (A(1).j == 1) "OK" else "fail"
@@ -0,0 +1,11 @@
fun box(): String {
javaClass<Boolean>()
javaClass<Byte>()
javaClass<Short>()
javaClass<Char>()
javaClass<Int>()
javaClass<Long>()
javaClass<Float>()
javaClass<Double>()
return "OK"
}
@@ -0,0 +1,12 @@
fun foo(): Int {
try {
} finally {
try {
return 1
} catch (e: Throwable) {
return 2
}
}
}
fun box() = if (foo() == 1) "OK" else "Fail"
@@ -0,0 +1 @@
open class Foo(var foo: String?, open protected val bar: String?)
@@ -0,0 +1,8 @@
fun foo() {
if (1==1) {
1.javaClass
} else {
}
}
fun box() = "OK"
@@ -0,0 +1,7 @@
fun box(): String {
val iterator: Iterator<Int> = (0..0).iterator()
for (i in iterator) {
return "OK"
}
return "fail"
}
@@ -0,0 +1,10 @@
fun box(): String {
var i = 0
{
if (1 == 1) {
i++
} else {
}
}()
return "OK"
}
@@ -0,0 +1,9 @@
fun foo(condition: Boolean): String {
val u = if (condition) {
"OK"
} else {
}
return u.toString()
}
fun box() = foo(true)
+13 -28
View File
@@ -2,38 +2,23 @@ fun box() : String {
val r1 = IntRange(1, 4)
if(r1.end != 4 || r1.isReversed || r1.size != 4) return "fail"
val r3 = -(0..5)
if(r3.start != 5 || r3.end != 0 || !r3.isReversed || r3.size != 6) return "fail"
val r2 = ByteRange(1, 4)
if(r2.end != 4.toByte() || r2.isReversed || r2.size != 4) return "fail"
val r4 = -r3
if(r4.end != 5 || r4.isReversed || r4.size != 6) return "fail"
val r3 = ShortRange(1, 4)
if(r3.end != 4.toShort() || r3.isReversed || r3.size != 4) return "fail"
val r5 = ByteRange(1, 4)
if(r5.end != 4.toByte() || r5.isReversed || r5.size != 4) return "fail"
val r4 = CharRange('a', 4)
if(r4.end != 'd' || r4.isReversed || r4.size != 4) return "fail"
val r7 = -(0.toByte()..5.toByte())
if(r7.start != 5.toByte() || r7.end != 0.toByte() || !r7.isReversed) return "fail"
val r5 = FloatRange(0.0.toFloat(), 1.0.toFloat())
if(r5.end != 1.0.toFloat() || r5.isReversed || r5.size != 1.0.toFloat()) return "fail"
val r9 = -r7
if(r9.end != 5.toByte() || r9.isReversed) return "fail"
val r6 = DoubleRange(0.0, 1.0)
if(r6.end != 1.0 || r6.isReversed || r6.size != 1.0) return "fail"
val r10 = ShortRange(1, 4)
if(r10.end != 4.toShort() || r10.isReversed || r10.size != 4) return "fail"
val r12 = -(0.toShort()..5.toShort())
if(r12.start != 5.toShort() || r12.end != 0.toShort() || !r12.isReversed) return "fail"
val r13 = -r12
if(r13.end != 5.toShort() || r13.isReversed) return "fail"
val r14 = CharRange('a', 4)
if(r14.end != 'd' || r14.isReversed || r14.size != 4) return "fail"
val r16 = -('a'..'e')
if(r16.start != 'e' || r16.end != 'a' || !r16.isReversed) return "fail"
val r17 = -r16
if(r17.end != 'e' || r17.isReversed) return "fail"
val r7 = LongRange(1, 4)
if(r7.end != 4.toLong() || r7.isReversed || r7.size != 4.toLong()) return "fail"
return "OK"
}
}
+38 -38
View File
@@ -1,82 +1,82 @@
fun testInt () : String {
val r1 = 1 upto 4
if(r1.end != 4 || r1.isReversed || r1.size != 4) return "int upto fail"
val r1 = 1 rangeTo 4
if(r1.end != 4 || r1.isReversed || r1.size != 4) return "int rangeTo fail"
val r2 = 4 upto 1
if(r2.start != 0 || r2.size != 0) return "int negative upto fail"
val r2 = 4 rangeTo 1
if(r2.start != 0 || r2.size != 0) return "int negative rangeTo fail"
val r3 = 5 downto 0
if(r3.start != 5 || r3.end != 0 || !r3.isReversed || r3.size != 6) return "int downto fail"
val r3 = 5 downTo 0
if(r3.start != 5 || r3.end != 0 || !r3.isReversed || r3.size != 6) return "int downTo fail"
val r4 = 5 downto 6
if(r4.start != 0 || r4.end != 0 || !r3.isReversed || r4.size != 0) return "int negative downto fail"
val r4 = 5 downTo 6
if(r4.start != 0 || r4.end != 0 || !r3.isReversed || r4.size != 0) return "int negative downTo fail"
return "OK"
}
fun testByte () : String {
val r1 = 1.toByte() upto 4.toByte()
if(r1.end != 4.toByte() || r1.isReversed || r1.size != 4) return "byte upto fail"
val r1 = 1.toByte() rangeTo 4.toByte()
if(r1.end != 4.toByte() || r1.isReversed || r1.size != 4) return "byte rangeTo fail"
val r2 = 4.toByte() upto 1.toByte()
if(r2.start != 0.toByte() || r2.size != 0) return "byte negative upto fail"
val r2 = 4.toByte() rangeTo 1.toByte()
if(r2.start != 0.toByte() || r2.size != 0) return "byte negative rangeTo fail"
val r3 = 5.toByte() downto 0.toByte()
if(r3.start != 5.toByte() || r3.end != 0.toByte() || !r3.isReversed || r3.size != 6) return "byte downto fail"
val r3 = 5.toByte() downTo 0.toByte()
if(r3.start != 5.toByte() || r3.end != 0.toByte() || !r3.isReversed || r3.size != 6) return "byte downTo fail"
val r4 = 5.toByte() downto 6.toByte()
if(r4.start != 0.toByte() || r4.end != 0.toByte() || !r3.isReversed || r4.size != 0) return "byte negative downto fail"
val r4 = 5.toByte() downTo 6.toByte()
if(r4.start != 0.toByte() || r4.end != 0.toByte() || !r3.isReversed || r4.size != 0) return "byte negative downTo fail"
return "OK"
}
fun testShort () : String {
val r1 = 1.toShort() upto 4.toShort()
if(r1.end != 4.toShort() || r1.isReversed || r1.size != 4) return "short upto fail"
val r1 = 1.toShort() rangeTo 4.toShort()
if(r1.end != 4.toShort() || r1.isReversed || r1.size != 4) return "short rangeTo fail"
val r2 = 4.toShort() upto 1.toShort()
if(r2.start != 0.toShort() || r2.size != 0) return "short negative upto fail"
val r2 = 4.toShort() rangeTo 1.toShort()
if(r2.start != 0.toShort() || r2.size != 0) return "short negative rangeTo fail"
val r3 = 5.toShort() downto 0.toShort()
if(r3.start != 5.toShort() || r3.end != 0.toShort() || !r3.isReversed || r3.size != 6) return "short downto fail"
val r3 = 5.toShort() downTo 0.toShort()
if(r3.start != 5.toShort() || r3.end != 0.toShort() || !r3.isReversed || r3.size != 6) return "short downTo fail"
val r4 = 5.toShort() downto 6.toShort()
if(r4.start != 0.toShort() || r4.end != 0.toShort() || !r3.isReversed || r4.size != 0) return "short negative downto fail"
val r4 = 5.toShort() downTo 6.toShort()
if(r4.start != 0.toShort() || r4.end != 0.toShort() || !r3.isReversed || r4.size != 0) return "short negative downTo fail"
return "OK"
}
fun testLong () : String {
val r1 = 1.toLong() upto 4.toLong()
if(r1.end != 4.toLong() || r1.isReversed || r1.size != 4.toLong()) return "long upto fail"
val r1 = 1.toLong() rangeTo 4.toLong()
if(r1.end != 4.toLong() || r1.isReversed || r1.size != 4.toLong()) return "long rangeTo fail"
val r2 = 4.toLong() upto 1.toLong()
val r2 = 4.toLong() rangeTo 1.toLong()
if(r2.start != 0.toLong() || r2.size != 0.toLong()) return "short negative long fail"
val r3 = 5.toLong() downto 0.toLong()
if(r3.start != 5.toLong() || r3.end != 0.toLong() || !r3.isReversed || r3.size != 6.toLong()) return "long downto fail"
val r3 = 5.toLong() downTo 0.toLong()
if(r3.start != 5.toLong() || r3.end != 0.toLong() || !r3.isReversed || r3.size != 6.toLong()) return "long downTo fail"
val r4 = 5.toLong() downto 6.toLong()
if(r4.start != 0.toLong() || r4.end != 0.toLong() || !r3.isReversed || r4.size != 0.toLong()) return "long negative downto fail"
val r4 = 5.toLong() downTo 6.toLong()
if(r4.start != 0.toLong() || r4.end != 0.toLong() || !r3.isReversed || r4.size != 0.toLong()) return "long negative downTo fail"
return "OK"
}
fun testChar () : String {
val r1 = 'a' upto 'd'
if(r1.end != 'd' || r1.isReversed || r1.size != 4) return "char upto fail"
val r1 = 'a' rangeTo 'd'
if(r1.end != 'd' || r1.isReversed || r1.size != 4) return "char rangeTo fail"
val r2 = 'd' upto 'a'
val r2 = 'd' rangeTo 'a'
if(r2.start != 0.toChar() || r2.size != 0) return "char negative long fail"
val r3 = 'd' downto 'a'
if(r3.start != 'd' || r3.end != 'a' || !r3.isReversed || r3.size != 4) return "char downto fail"
val r3 = 'd' downTo 'a'
if(r3.start != 'd' || r3.end != 'a' || !r3.isReversed || r3.size != 4) return "char downTo fail"
val r4 = 'a' downto 'd'
if(r4.start != 0.toChar() || r4.end != 0.toChar() || !r3.isReversed || r4.size != 0) return "char negative downto fail"
val r4 = 'a' downTo 'd'
if(r4.start != 0.toChar() || r4.end != 0.toChar() || !r3.isReversed || r4.size != 0) return "char negative downTo fail"
return "OK"
}
+2 -2
View File
@@ -21,12 +21,12 @@ fun box(): String {
}
sb.append(";")
for (i in 0 downto 0) {
for (i in 0 downTo 0) {
ap(i)
}
sb.append(";")
for (i in 1 downto 0) {
for (i in 1 downTo 0) {
ap(i)
}

Some files were not shown because too many files have changed in this diff Show More