Merge branch 'master' of github.com:JetBrains/kotlin

This commit is contained in:
James Strachan
2012-05-28 17:16:23 +01:00
105 changed files with 2364 additions and 2037 deletions
+3
View File
@@ -410,6 +410,9 @@
<inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UtilityClassWithoutPrivateConstructor" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreClassesWithOnlyMain" value="false" />
<option name="ignorableAnnotations">
<value />
</option>
</inspection_tool>
<inspection_tool class="VolatileLongOrDoubleField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
+1 -3
View File
@@ -26,8 +26,6 @@
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
<method>
<option name="AntTarget" enabled="false" antfile="file://$PROJECT_DIR$/js_backend_tests.xml" target="copy_lib" />
</method>
<method />
</configuration>
</component>
@@ -198,7 +198,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
ClassDescriptor function = state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name);
final CodegenContext.ClosureContext closureContext = context.intoClosure(
final CodegenContexts.ClosureContext closureContext = context.intoClosure(
funDescriptor, function, name.getInternalName(), this, state.getInjector().getJetTypeMapper());
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
@@ -35,25 +35,6 @@ import java.util.LinkedHashMap;
* @author alex.tkachman
*/
public abstract class CodegenContext {
public static final CodegenContext STATIC = new CodegenContext(null, OwnerKind.NAMESPACE, null, null) {
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "ROOT";
}
};
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT);
private final DeclarationDescriptor contextType;
@@ -121,31 +102,31 @@ public abstract class CodegenContext {
}
public CodegenContext intoNamespace(NamespaceDescriptor descriptor) {
return new NamespaceContext(descriptor, this);
return new CodegenContexts.NamespaceContext(descriptor, this);
}
public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
return new ClassContext(descriptor, kind, this, typeMapper);
return new CodegenContexts.ClassContext(descriptor, kind, this, typeMapper);
}
public CodegenContext intoAnonymousClass(@NotNull ObjectOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
return new AnonymousClassContext(descriptor, kind, this, closure, typeMapper);
return new CodegenContexts.AnonymousClassContext(descriptor, kind, this, closure, typeMapper);
}
public MethodContext intoFunction(FunctionDescriptor descriptor) {
return new MethodContext(descriptor, getContextKind(), this);
public CodegenContexts.MethodContext intoFunction(FunctionDescriptor descriptor) {
return new CodegenContexts.MethodContext(descriptor, getContextKind(), this);
}
public ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) {
public CodegenContexts.ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) {
if(descriptor == null) {
descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.<AnnotationDescriptor>emptyList(), true)
.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PUBLIC);
}
return new ConstructorContext(descriptor, getContextKind(), this, typeMapper);
return new CodegenContexts.ConstructorContext(descriptor, getContextKind(), this, typeMapper);
}
public ClosureContext intoClosure(FunctionDescriptor funDescriptor, ClassDescriptor classDescriptor, String internalClassName, ClosureCodegen closureCodegen, JetTypeMapper typeMapper) {
return new ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
public CodegenContexts.ClosureContext intoClosure(FunctionDescriptor funDescriptor, ClassDescriptor classDescriptor, String internalClassName, ClosureCodegen closureCodegen, JetTypeMapper typeMapper) {
return new CodegenContexts.ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
}
public FrameMap prepareFrame(JetTypeMapper mapper) {
@@ -190,7 +171,7 @@ public abstract class CodegenContext {
}
public int getTypeInfoConstantIndex(JetType type) {
if (parentContext != STATIC) { return parentContext.getTypeInfoConstantIndex(type); }
if (parentContext != CodegenContexts.STATIC) { return parentContext.getTypeInfoConstantIndex(type); }
if(typeInfoConstants == null) {
typeInfoConstants = new LinkedHashMap<JetType, Integer>();
@@ -242,7 +223,7 @@ public abstract class CodegenContext {
CallableMemberDescriptor.Kind.DECLARATION
);
JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null;
myAccessor.setType(pd.getType(), Collections.<TypeParameterDescriptor>emptyList(), pd.getExpectedThisObject(), receiverType);
myAccessor.setType(pd.getType(), Collections.<TypeParameterDescriptorImpl>emptyList(), pd.getExpectedThisObject(), receiverType);
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
@@ -280,174 +261,4 @@ public abstract class CodegenContext {
this.accessors.putAll(accessors);
}
}
public abstract static class ReceiverContext extends CodegenContext {
final CallableDescriptor receiverDescriptor;
public ReceiverContext(CallableDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) {
super(contextType, contextKind, parentContext, closureCodegen);
receiverDescriptor = contextType.getReceiverParameter().exists() ? contextType : null;
}
@Override
protected CallableDescriptor getReceiverDescriptor() {
return receiverDescriptor;
}
}
public static class MethodContext extends ReceiverContext {
public MethodContext(FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return getParentContext().getThisDescriptor();
}
public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) {
return getParentContext().lookupInContext(d, v, result);
}
public Type enclosingClassType(JetTypeMapper typeMapper) {
return getParentContext().enclosingClassType(typeMapper);
}
@Override
public boolean isStatic() {
return getParentContext().isStatic();
}
protected StackValue getOuterExpression(StackValue prefix) {
return getParentContext().getOuterExpression(prefix);
}
@Override
public String toString() {
return "Method: " + getContextDescriptor();
}
}
public static class ConstructorContext extends MethodContext {
public ConstructorContext(ConstructorDescriptor contextType, OwnerKind kind, CodegenContext parent, JetTypeMapper typeMapper) {
super(contextType, kind, parent);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? local1
: null;
}
protected StackValue getOuterExpression(StackValue prefix) {
return outerExpression;
}
@Override
public String toString() {
return "Constructor: " + getContextDescriptor().getName();
}
}
public static class ClassContext extends CodegenContext {
public ClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, null);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, typeMapper.getFQName(contextType), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
}
public static class AnonymousClassContext extends CodegenContext {
public AnonymousClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closure, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, closure);
final Type type = enclosingClassType(typeMapper);
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextType.getDefaultType(), MapTypeMode.IMPL);
outerExpression = type != null
? StackValue.field(type, owner.getInternalName(), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Anonymous: " + getThisDescriptor();
}
}
public static class ClosureContext extends ReceiverContext {
private ClassDescriptor classDescriptor;
public ClosureContext(FunctionDescriptor contextType, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, String internalClassName, JetTypeMapper typeMapper) {
super(contextType, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen);
this.classDescriptor = classDescriptor;
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, internalClassName, "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return classDescriptor;
}
@Override
public DeclarationDescriptor getContextDescriptor() {
return classDescriptor;
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Closure: " + classDescriptor;
}
}
public static class NamespaceContext extends CodegenContext {
public NamespaceContext(NamespaceDescriptor contextType, CodegenContext parent) {
super(contextType, OwnerKind.NAMESPACE, parent, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "Namespace: " + getContextDescriptor().getName();
}
}
}
@@ -0,0 +1,223 @@
/*
* 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.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
/**
* @author Stepan Koltsov
*/
public class CodegenContexts {
public static final CodegenContext STATIC = new CodegenContext(null, OwnerKind.NAMESPACE, null, null) {
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "ROOT";
}
};
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT);
public abstract static class ReceiverContext extends CodegenContext {
final CallableDescriptor receiverDescriptor;
public ReceiverContext(CallableDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) {
super(contextType, contextKind, parentContext, closureCodegen);
receiverDescriptor = contextType.getReceiverParameter().exists() ? contextType : null;
}
@Override
protected CallableDescriptor getReceiverDescriptor() {
return receiverDescriptor;
}
}
public static class MethodContext extends ReceiverContext {
public MethodContext(FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return getParentContext().getThisDescriptor();
}
public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) {
return getParentContext().lookupInContext(d, v, result);
}
public Type enclosingClassType(JetTypeMapper typeMapper) {
return getParentContext().enclosingClassType(typeMapper);
}
@Override
public boolean isStatic() {
return getParentContext().isStatic();
}
protected StackValue getOuterExpression(StackValue prefix) {
return getParentContext().getOuterExpression(prefix);
}
@Override
public String toString() {
return "Method: " + getContextDescriptor();
}
}
public static class ConstructorContext extends MethodContext {
public ConstructorContext(ConstructorDescriptor contextType, OwnerKind kind, CodegenContext parent, JetTypeMapper typeMapper) {
super(contextType, kind, parent);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? local1
: null;
}
protected StackValue getOuterExpression(StackValue prefix) {
return outerExpression;
}
@Override
public String toString() {
return "Constructor: " + getContextDescriptor().getName();
}
}
public static class ClassContext extends CodegenContext {
public ClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, null);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, typeMapper.getFQName(contextType), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
}
public static class AnonymousClassContext extends CodegenContext {
public AnonymousClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closure, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, closure);
final Type type = enclosingClassType(typeMapper);
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextType.getDefaultType(), MapTypeMode.IMPL);
outerExpression = type != null
? StackValue.field(type, owner.getInternalName(), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Anonymous: " + getThisDescriptor();
}
}
public static class ClosureContext extends ReceiverContext {
private ClassDescriptor classDescriptor;
public ClosureContext(FunctionDescriptor contextType, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, String internalClassName, JetTypeMapper typeMapper) {
super(contextType, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen);
this.classDescriptor = classDescriptor;
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, internalClassName, "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return classDescriptor;
}
@Override
public DeclarationDescriptor getContextDescriptor() {
return classDescriptor;
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Closure: " + classDescriptor;
}
}
public static class NamespaceContext extends CodegenContext {
public NamespaceContext(NamespaceDescriptor contextType, CodegenContext parent) {
super(contextType, OwnerKind.NAMESPACE, parent, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "Namespace: " + getContextDescriptor().getName();
}
}
}
@@ -54,7 +54,7 @@ public class CodegenUtil {
invokeDescriptor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
fd.getExpectedThisObject(),
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<TypeParameterDescriptorImpl>emptyList(),
fd.getValueParameters(),
fd.getReturnType(),
Modality.FINAL,
@@ -1093,7 +1093,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
if (descriptor instanceof TypeParameterDescriptor) {
if (descriptor instanceof TypeParameterDescriptorImpl) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
v.invokevirtual("jet/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
v.checkcast(asmType(typeParameterDescriptor.getClassObjectType()));
@@ -1162,7 +1162,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
propertyDescriptor = propertyDescriptor.getOriginal();
boolean isInsideClass = ((containingDeclaration == context.getThisDescriptor()) ||
(context.getParentContext() instanceof CodegenContext.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
&& contextKind() != OwnerKind.TRAIT_IMPL;
Method getter;
Method setter;
@@ -1438,8 +1438,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private StackValue generateReceiver(DeclarationDescriptor provided) {
assert context instanceof CodegenContext.ReceiverContext;
CodegenContext.ReceiverContext cur = (CodegenContext.ReceiverContext) context;
assert context instanceof CodegenContexts.ReceiverContext;
CodegenContexts.ReceiverContext cur = (CodegenContexts.ReceiverContext) context;
if (cur.getReceiverDescriptor() == provided) {
StackValue result = cur.getReceiverExpression(typeMapper);
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, null);
@@ -1458,7 +1458,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
cur = context;
StackValue result = StackValue.local(0, TYPE_OBJECT);
while (cur != null) {
if(cur instanceof CodegenContext.MethodContext && !(cur instanceof CodegenContext.ConstructorContext))
if(cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext))
cur = cur.getParentContext();
if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
@@ -1474,7 +1474,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
result = cur.getOuterExpression(result);
if(cur instanceof CodegenContext.ConstructorContext) {
if(cur instanceof CodegenContexts.ConstructorContext) {
cur = cur.getParentContext();
}
cur = cur.getParentContext();
@@ -2614,7 +2614,7 @@ If finally block is present, its last expression is the value of try expression.
JetExpression left = expression.getLeft();
JetType leftType = bindingContext.get(BindingContext.EXPRESSION_TYPE, left);
DeclarationDescriptor descriptor = rightType.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor || descriptor instanceof TypeParameterDescriptor) {
if (descriptor instanceof ClassDescriptor || descriptor instanceof TypeParameterDescriptorImpl) {
StackValue value = genQualified(receiver, left);
value.put(JetTypeMapper.boxType(value.type), v);
assert leftType != null;
@@ -69,7 +69,7 @@ public class FunctionCodegen {
JvmMethodSignature jvmMethod, boolean needJetAnnotations,
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
CodegenContext.MethodContext funContext = owner.intoFunction(functionDescriptor);
CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor);
final JetExpression bodyExpression = f.getBodyExpression();
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
@@ -78,7 +78,7 @@ public class FunctionCodegen {
private void generatedMethod(JetExpression bodyExpressions,
JvmMethodSignature jvmSignature,
boolean needJetAnnotations, @Nullable String propertyTypeSignature,
CodegenContext.MethodContext context,
CodegenContexts.MethodContext context,
FunctionDescriptor functionDescriptor,
JetDeclarationWithBody fun
)
@@ -301,7 +301,7 @@ public class FunctionCodegen {
}
}
static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) {
static void generateDefaultIfNeeded(CodegenContexts.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
if(kind != OwnerKind.TRAIT_IMPL) {
@@ -449,7 +449,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
CodegenContexts.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
JvmMethodSignature constructorMethod;
CallableMethod callableMethod;
@@ -463,7 +463,7 @@ public class JetTypeMapper {
return asmType;
}
if (descriptor instanceof TypeParameterDescriptor) {
if (descriptor instanceof TypeParameterDescriptorImpl) {
Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
if (signatureVisitor != null) {
@@ -722,7 +722,7 @@ public class JetTypeMapper {
signatureVisitor.writeInterfaceBoundEnd();
}
}
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptorImpl) {
signatureVisitor.writeInterfaceBound();
mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeInterfaceBoundEnd();
@@ -966,7 +966,7 @@ public class JetTypeMapper {
public boolean isGenericsArray(JetType type) {
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
if(declarationDescriptor instanceof TypeParameterDescriptor)
if(declarationDescriptor instanceof TypeParameterDescriptorImpl)
return true;
if(standardLibrary.getArray().equals(declarationDescriptor))
@@ -23,7 +23,6 @@ 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.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.objectweb.asm.MethodVisitor;
@@ -57,7 +56,7 @@ public class NamespaceCodegen {
public void generate(JetFile file) {
NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor);
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
final FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state);
final PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, state);
@@ -100,7 +99,7 @@ public class NamespaceCodegen {
mv.visitCode();
FrameMap frameMap = new FrameMap();
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC, state);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContexts.STATIC, state);
for (JetDeclaration declaration : namespace.getDeclarations()) {
if (declaration instanceof JetProperty) {
@@ -106,9 +106,9 @@ public class ObjectOrClosureCodegen {
FunctionDescriptor fd = (FunctionDescriptor) d;
// we generate method
assert context instanceof CodegenContext.ReceiverContext;
assert context instanceof CodegenContexts.ReceiverContext;
CodegenContext.ReceiverContext fcontext = (CodegenContext.ReceiverContext) context;
CodegenContexts.ReceiverContext fcontext = (CodegenContexts.ReceiverContext) context;
if(fcontext.getReceiverDescriptor() != fd)
return null;
@@ -34,7 +34,6 @@ import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport;
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -246,7 +245,6 @@ public class KotlinToJVMBytecodeCompiler {
public AnalyzeExhaust invoke() {
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory.EMPTY,
configuration.getEnvironment().getCompilerDependencies());
}
}, environment.getSourceFiles()
@@ -17,16 +17,42 @@
package org.jetbrains.jet.di;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisContext;
import org.jetbrains.jet.lang.resolve.BodyResolver;
import org.jetbrains.jet.lang.resolve.ControlFlowAnalyzer;
import org.jetbrains.jet.lang.resolve.DeclarationsChecker;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration;
import org.jetbrains.jet.lang.resolve.java.PsiClassFinderForJvm;
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.DelegationResolver;
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
import org.jetbrains.jet.lang.resolve.OverloadResolver;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */
@@ -42,7 +68,6 @@ public class InjectorForTopDownAnalyzerForJvm {
private final TopDownAnalysisParameters topDownAnalysisParameters;
private final ObservableBindingTrace observableBindingTrace;
private final ModuleDescriptor moduleDescriptor;
private final JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory;
private final CompilerDependencies compilerDependencies;
private CompilerSpecialMode compilerSpecialMode;
private JavaBridgeConfiguration javaBridgeConfiguration;
@@ -69,7 +94,6 @@ public class InjectorForTopDownAnalyzerForJvm {
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
@NotNull ObservableBindingTrace observableBindingTrace,
@NotNull ModuleDescriptor moduleDescriptor,
JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies
) {
this.topDownAnalyzer = new TopDownAnalyzer();
@@ -82,7 +106,6 @@ public class InjectorForTopDownAnalyzerForJvm {
this.topDownAnalysisParameters = topDownAnalysisParameters;
this.observableBindingTrace = observableBindingTrace;
this.moduleDescriptor = moduleDescriptor;
this.jetControlFlowDataTraceFactory = jetControlFlowDataTraceFactory;
this.compilerDependencies = compilerDependencies;
this.compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
this.javaBridgeConfiguration = new JavaBridgeConfiguration();
@@ -126,7 +149,6 @@ public class InjectorForTopDownAnalyzerForJvm {
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.bodyResolver.setTrace(observableBindingTrace);
this.controlFlowAnalyzer.setFlowDataTraceFactory(jetControlFlowDataTraceFactory);
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.*;
@@ -50,9 +49,8 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
@NotNull
public AnalyzeExhaust analyzeFiles(@NotNull Project project,
@NotNull Collection<JetFile> files,
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
return analyzeFilesWithJavaIntegration(project, files, filesToAnalyzeCompletely, flowDataTraceFactory,
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely) {
return analyzeFilesWithJavaIntegration(project, files, filesToAnalyzeCompletely,
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR), true);
}
@@ -60,22 +58,19 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
@Override
public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
@NotNull Predicate<PsiFile> filesForBodiesResolve,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull BindingTrace headersTraceContext,
@NotNull BodiesResolveContext bodiesResolveContext
) {
return analyzeBodiesInFilesWithJavaIntegration(
project, filesForBodiesResolve, flowDataTraceFactory,
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR),
project, filesForBodiesResolve, compilerDependenciesForProduction(CompilerSpecialMode.REGULAR),
headersTraceContext, bodiesResolveContext);
}
public static AnalyzeExhaust analyzeOneFileWithJavaIntegrationAndCheckForErrors(
JetFile file, JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies) {
JetFile file, @NotNull CompilerDependencies compilerDependencies) {
AnalyzingUtils.checkForSyntacticErrors(file);
AnalyzeExhaust analyzeExhaust = analyzeOneFileWithJavaIntegration(file, flowDataTraceFactory, compilerDependencies);
AnalyzeExhaust analyzeExhaust = analyzeOneFileWithJavaIntegration(file, compilerDependencies);
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
@@ -83,24 +78,20 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
}
public static AnalyzeExhaust analyzeOneFileWithJavaIntegration(
JetFile file, JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies) {
JetFile file, @NotNull CompilerDependencies compilerDependencies) {
return analyzeFilesWithJavaIntegration(file.getProject(), Collections.singleton(file),
Predicates.<PsiFile>alwaysTrue(), flowDataTraceFactory, compilerDependencies);
Predicates.<PsiFile>alwaysTrue(), compilerDependencies);
}
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies) {
return analyzeFilesWithJavaIntegration(
project, files, filesToAnalyzeCompletely,
flowDataTraceFactory, compilerDependencies, false);
project, files, filesToAnalyzeCompletely, compilerDependencies, false);
}
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies,
boolean storeContextForBodiesResolve) {
BindingTraceContext bindingTraceContext = new BindingTraceContext();
@@ -112,8 +103,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
project, topDownAnalysisParameters,
new ObservableBindingTrace(bindingTraceContext), owner, flowDataTraceFactory,
compilerDependencies);
new ObservableBindingTrace(bindingTraceContext), owner, compilerDependencies);
try {
injector.getTopDownAnalyzer().analyzeFiles(files);
BodiesResolveContext bodiesResolveContext = storeContextForBodiesResolve ?
@@ -127,7 +117,6 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
public static AnalyzeExhaust analyzeBodiesInFilesWithJavaIntegration(
Project project, Predicate<PsiFile> filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies,
@NotNull BindingTrace traceContext,
@NotNull BodiesResolveContext bodiesResolveContext) {
@@ -140,8 +129,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
project, topDownAnalysisParameters,
new ObservableBindingTrace(traceContext), owner, flowDataTraceFactory,
compilerDependencies);
new ObservableBindingTrace(traceContext), owner, compilerDependencies);
try {
injector.getTopDownAnalyzer().doProcessForBodies(bodiesResolveContext);
@@ -157,7 +145,6 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
Project project = files.iterator().next().getProject();
return analyzeFilesWithJavaIntegration(project, files, Predicates.<PsiFile>alwaysFalse(),
JetControlFlowDataTraceFactory.EMPTY, compilerDependencies);
return analyzeFilesWithJavaIntegration(project, files, Predicates.<PsiFile>alwaysFalse(), compilerDependencies);
}
}
@@ -49,7 +49,7 @@ import java.util.*;
/**
* @author abreslav
*/
public class JavaDescriptorResolver {
public class JavaDescriptorResolver implements DependencyClassByQualifiedNameResolver {
public static final Name JAVA_ROOT = Name.special("<java_root>");
@@ -107,14 +107,14 @@ public class JavaDescriptorResolver {
@NotNull
private final TypeParameterDescriptorOrigin origin;
@NotNull
final TypeParameterDescriptor descriptor;
final TypeParameterDescriptorImpl descriptor;
final PsiTypeParameter psiTypeParameter;
@Nullable
private final List<JetType> upperBoundsForKotlin;
@Nullable
private final List<JetType> lowerBoundsForKotlin;
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter) {
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter) {
this.origin = TypeParameterDescriptorOrigin.JAVA;
this.descriptor = descriptor;
this.psiTypeParameter = psiTypeParameter;
@@ -122,7 +122,7 @@ public class JavaDescriptorResolver {
this.lowerBoundsForKotlin = null;
}
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter,
private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter,
List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
this.descriptor = descriptor;
@@ -307,6 +307,11 @@ public class JavaDescriptorResolver {
return clazz;
}
@Override
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName) {
return resolveClass(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
}
private ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule, @NotNull List<Runnable> tasks) {
if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
// TODO: only if -$$TImpl class is created by Kotlin
@@ -603,10 +608,10 @@ public class JavaDescriptorResolver {
@NotNull
private final TypeVariableResolver typeVariableResolver;
@NotNull
private final TypeParameterDescriptor typeParameterDescriptor;
private final TypeParameterDescriptorImpl typeParameterDescriptor;
protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner,
String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptor typeParameterDescriptor)
String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptorImpl typeParameterDescriptor)
{
if (name.isEmpty()) {
throw new IllegalStateException();
@@ -682,7 +687,7 @@ public class JavaDescriptorResolver {
@Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification(
TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
reified,
@@ -757,7 +762,7 @@ public class JavaDescriptorResolver {
@NotNull
private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(), // TODO
false,
@@ -769,7 +774,7 @@ public class JavaDescriptorResolver {
}
private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) {
TypeParameterDescriptor typeParameterDescriptor = typeParameter.descriptor;
TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor;
if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
List<?> upperBounds = typeParameter.upperBoundsForKotlin;
if (upperBounds.size() == 0){
@@ -947,6 +952,11 @@ public class JavaDescriptorResolver {
return scopeData.namespaceDescriptor;
}
@Override
public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) {
return resolveNamespace(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
}
private NamespaceDescriptorParent resolveParentNamespace(FqName fqName) {
if (fqName.isRoot()) {
return FAKE_ROOT_MODULE;
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
@@ -17,12 +17,7 @@
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import java.util.ArrayList;
import java.util.List;
@@ -20,7 +20,6 @@ import com.google.common.base.Predicate;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
@@ -35,13 +34,11 @@ public interface AnalyzerFacade {
@NotNull
AnalyzeExhaust analyzeFiles(@NotNull Project project,
@NotNull Collection<JetFile> files,
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory);
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely);
@NotNull
AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
@NotNull Predicate<PsiFile> filesForBodiesResolve,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull BindingTrace traceContext,
@NotNull BodiesResolveContext bodiesResolveContext);
}
@@ -17,16 +17,36 @@
package org.jetbrains.jet.di;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisContext;
import org.jetbrains.jet.lang.resolve.BodyResolver;
import org.jetbrains.jet.lang.resolve.ControlFlowAnalyzer;
import org.jetbrains.jet.lang.resolve.DeclarationsChecker;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.DelegationResolver;
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
import org.jetbrains.jet.lang.resolve.OverloadResolver;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */
@@ -42,7 +62,6 @@ public class InjectorForTopDownAnalyzerBasic {
private final TopDownAnalysisParameters topDownAnalysisParameters;
private final ObservableBindingTrace observableBindingTrace;
private final ModuleDescriptor moduleDescriptor;
private final JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory;
private final ModuleConfiguration moduleConfiguration;
private DeclarationResolver declarationResolver;
private AnnotationResolver annotationResolver;
@@ -63,7 +82,6 @@ public class InjectorForTopDownAnalyzerBasic {
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
@NotNull ObservableBindingTrace observableBindingTrace,
@NotNull ModuleDescriptor moduleDescriptor,
JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory,
@NotNull ModuleConfiguration moduleConfiguration
) {
this.topDownAnalyzer = new TopDownAnalyzer();
@@ -76,7 +94,6 @@ public class InjectorForTopDownAnalyzerBasic {
this.topDownAnalysisParameters = topDownAnalysisParameters;
this.observableBindingTrace = observableBindingTrace;
this.moduleDescriptor = moduleDescriptor;
this.jetControlFlowDataTraceFactory = jetControlFlowDataTraceFactory;
this.moduleConfiguration = moduleConfiguration;
this.declarationResolver = new DeclarationResolver();
this.annotationResolver = new AnnotationResolver();
@@ -114,7 +131,6 @@ public class InjectorForTopDownAnalyzerBasic {
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.bodyResolver.setTrace(observableBindingTrace);
this.controlFlowAnalyzer.setFlowDataTraceFactory(jetControlFlowDataTraceFactory);
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.psi.*;
import java.util.List;
@@ -64,7 +65,7 @@ public interface JetControlFlowBuilder {
// Subroutines
void enterSubroutine(@NotNull JetDeclaration subroutine);
void exitSubroutine(@NotNull JetDeclaration subroutine);
Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine);
@NotNull
JetElement getCurrentSubroutine();
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.psi.*;
import java.util.List;
@@ -157,9 +158,9 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
}
@Override
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
assert builder != null;
builder.exitSubroutine(subroutine);
return builder.exitSubroutine(subroutine);
}
@NotNull
@@ -1,180 +0,0 @@
/*
* 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.lang.cfg;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author svtk
*/
public class JetControlFlowGraphTraverser<D> {
private final Pseudocode pseudocode;
private final boolean lookInside;
private final boolean straightDirection;
private final Map<Instruction, Pair<D, D>> dataMap = Maps.newLinkedHashMap();
public static <D> JetControlFlowGraphTraverser<D> create(@NotNull Pseudocode pseudocode, boolean lookInside, boolean straightDirection) {
return new JetControlFlowGraphTraverser<D>(pseudocode, lookInside, straightDirection);
}
private JetControlFlowGraphTraverser(@NotNull Pseudocode pseudocode, boolean lookInside, boolean straightDirection) {
this.pseudocode = pseudocode;
this.lookInside = lookInside;
this.straightDirection = straightDirection;
}
@NotNull
private Instruction getStartInstruction(@NotNull Pseudocode pseudocode) {
return straightDirection ? pseudocode.getEnterInstruction() : pseudocode.getSinkInstruction();
}
public void collectInformationFromInstructionGraph(
@NotNull D initialDataValue,
@NotNull D initialDataValueForEnterInstruction,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy) {
initializeDataMap(pseudocode, initialDataValue);
dataMap.put(getStartInstruction(pseudocode),
Pair.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction));
boolean[] changed = new boolean[1];
changed[0] = true;
while (changed[0]) {
changed[0] = false;
traverseSubGraph(pseudocode, instructionDataMergeStrategy, Collections.<Instruction>emptyList(), changed, false);
}
}
private void initializeDataMap(
@NotNull Pseudocode pseudocode,
@NotNull D initialDataValue) {
List<Instruction> instructions = pseudocode.getInstructions();
Pair<D, D> initialPair = Pair.create(initialDataValue, initialDataValue);
for (Instruction instruction : instructions) {
dataMap.put(instruction, initialPair);
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
initializeDataMap(((LocalDeclarationInstruction) instruction).getBody(), initialDataValue);
}
}
}
private void traverseSubGraph(
@NotNull Pseudocode pseudocode,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy,
@NotNull Collection<Instruction> previousSubGraphInstructions,
boolean[] changed,
boolean isLocal) {
List<Instruction> instructions = pseudocode.getInstructions();
Instruction startInstruction = getStartInstruction(pseudocode);
if (!straightDirection) {
instructions = Lists.newArrayList(instructions);
Collections.reverse(instructions);
}
for (Instruction instruction : instructions) {
boolean isStart = straightDirection ? instruction instanceof SubroutineEnterInstruction : instruction instanceof SubroutineSinkInstruction;
if (!isLocal && isStart) continue;
Collection<Instruction> allPreviousInstructions;
Collection<Instruction> previousInstructions = straightDirection
? instruction.getPreviousInstructions()
: instruction.getNextInstructions();
if (instruction == startInstruction && !previousSubGraphInstructions.isEmpty()) {
allPreviousInstructions = Lists.newArrayList(previousInstructions);
allPreviousInstructions.addAll(previousSubGraphInstructions);
}
else {
allPreviousInstructions = previousInstructions;
}
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
traverseSubGraph(subroutinePseudocode, instructionDataMergeStrategy, previousInstructions, changed, true);
Instruction lastInstruction = straightDirection ? subroutinePseudocode.getSinkInstruction() : subroutinePseudocode.getEnterInstruction();
Pair<D, D> previousValue = dataMap.get(instruction);
Pair<D, D> newValue = dataMap.get(lastInstruction);
if (!previousValue.equals(newValue)) {
changed[0] = true;
dataMap.put(instruction, newValue);
}
continue;
}
Pair<D, D> previousDataValue = dataMap.get(instruction);
Collection<D> incomingEdgesData = Sets.newHashSet();
for (Instruction previousInstruction : allPreviousInstructions) {
Pair<D, D> previousData = dataMap.get(previousInstruction);
if (previousData != null) {
incomingEdgesData.add(previousData.getSecond());
}
}
Pair<D, D> mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData);
if (!mergedData.equals(previousDataValue)) {
changed[0] = true;
dataMap.put(instruction, mergedData);
}
}
}
public void traverseAndAnalyzeInstructionGraph(
@NotNull InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
traverseAndAnalyzeInstructionGraph(pseudocode, instructionDataAnalyzeStrategy);
}
private void traverseAndAnalyzeInstructionGraph(
@NotNull Pseudocode pseudocode,
@NotNull InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
List<Instruction> instructions = pseudocode.getInstructions();
if (!straightDirection) {
instructions = Lists.newArrayList(instructions);
Collections.reverse(instructions);
}
for (Instruction instruction : instructions) {
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody(), instructionDataAnalyzeStrategy);
}
Pair<D, D> pair = dataMap.get(instruction);
instructionDataAnalyzeStrategy.execute(instruction,
pair != null ? pair.getFirst() : null,
pair != null ? pair.getSecond() : null);
}
}
public D getResultInfo() {
return dataMap.get(pseudocode.getExitInstruction()).getFirst();
}
interface InstructionDataMergeStrategy<D> {
Pair<D, D> execute(@NotNull Instruction instruction, @NotNull Collection<D> incomingEdgesData);
}
interface InstructionDataAnalyzeStrategy<D> {
void execute(@NotNull Instruction instruction, @Nullable D enterData, @Nullable D exitData);
}
}
@@ -21,6 +21,10 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.LocalDeclarationInstruction;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowInstructionsGenerator;
import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
@@ -45,12 +49,21 @@ public class JetControlFlowProcessor {
private final JetControlFlowBuilder builder;
private final BindingTrace trace;
public JetControlFlowProcessor(BindingTrace trace, JetControlFlowBuilder builder) {
this.builder = builder;
public JetControlFlowProcessor(BindingTrace trace) {
this.builder = new JetControlFlowInstructionsGenerator();
this.trace = trace;
}
public void generate(@NotNull JetDeclaration subroutine) {
public Pseudocode generatePseudocode(@NotNull JetDeclaration subroutine) {
Pseudocode pseudocode = generate(subroutine);
((PseudocodeImpl)pseudocode).postProcess();
for (LocalDeclarationInstruction localDeclarationInstruction : pseudocode.getLocalDeclarations()) {
((PseudocodeImpl)localDeclarationInstruction.getBody()).postProcess();
}
return pseudocode;
}
private Pseudocode generate(@NotNull JetDeclaration subroutine) {
builder.enterSubroutine(subroutine);
if (subroutine instanceof JetDeclarationWithBody) {
JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine;
@@ -67,7 +80,7 @@ public class JetControlFlowProcessor {
else {
subroutine.accept(new CFPVisitor(false));
}
builder.exitSubroutine(subroutine);
return builder.exitSubroutine(subroutine);
}
private void processLocalDeclaration(@NotNull JetDeclaration subroutine) {
@@ -17,15 +17,16 @@
package org.jetbrains.jet.lang.cfg;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*;
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableInitState;
import org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
@@ -33,13 +34,14 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.JetMainDetector;
import java.util.*;
import static org.jetbrains.jet.lang.cfg.PseudocodeVariablesData.VariableUseState.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
@@ -49,52 +51,22 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
*/
public class JetFlowInformationProvider {
private final Map<JetElement, Pseudocode> pseudocodeMap;
private final JetDeclaration subroutine;
private final Pseudocode pseudocode;
private final PseudocodeVariablesData pseudocodeVariablesData;
private BindingTrace trace;
public JetFlowInformationProvider(@NotNull JetDeclaration declaration, @NotNull final JetExpression bodyExpression, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @NotNull BindingTrace trace) {
public JetFlowInformationProvider(
@NotNull JetDeclaration declaration,
@NotNull BindingTrace trace) {
subroutine = declaration;
this.trace = trace;
final JetPseudocodeTrace pseudocodeTrace = flowDataTraceFactory.createTrace(declaration);
pseudocodeMap = new HashMap<JetElement, Pseudocode>();
final Map<JetElement, Instruction> representativeInstructions = new HashMap<JetElement, Instruction>();
final Map<JetExpression, LoopInfo> loopInfo = Maps.newHashMap();
JetPseudocodeTrace wrappedTrace = new JetPseudocodeTrace() {
@Override
public void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode) {
pseudocodeTrace.recordControlFlowData(element, pseudocode);
pseudocodeMap.put(element, pseudocode);
}
@Override
public void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction) {
Instruction oldValue = representativeInstructions.put(element, instruction);
// assert oldValue == null : element.getText();
pseudocodeTrace.recordRepresentativeInstruction(element, instruction);
}
@Override
public void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
loopInfo.put(expression, blockInfo);
pseudocodeTrace.recordLoopInfo(expression, blockInfo);
}
@Override
public void close() {
pseudocodeTrace.close();
for (Pseudocode pseudocode : pseudocodeMap.values()) {
pseudocode.postProcess();
}
}
};
JetControlFlowInstructionsGenerator instructionsGenerator = new JetControlFlowInstructionsGenerator(wrappedTrace);
new JetControlFlowProcessor(trace, instructionsGenerator).generate(declaration);
wrappedTrace.close();
pseudocode = new JetControlFlowProcessor(trace).generatePseudocode(declaration);
pseudocodeVariablesData = new PseudocodeVariablesData(pseudocode, trace.getBindingContext());
}
private void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull final Collection<JetElement> returnedExpressions) {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
private void collectReturnExpressions(@NotNull final Collection<JetElement> returnedExpressions) {
final Set<Instruction> instructions = Sets.newHashSet(pseudocode.getInstructions());
SubroutineExitInstruction exitInstruction = pseudocode.getExitInstruction();
for (Instruction previousInstruction : exitInstruction.getPreviousInstructions()) {
@@ -148,15 +120,16 @@ public class JetFlowInformationProvider {
});
}
}
public void checkDefiniteReturn(@NotNull final JetDeclarationWithBody function, final @NotNull JetType expectedReturnType) {
assert function instanceof JetDeclaration;
public void checkDefiniteReturn(final @NotNull JetType expectedReturnType) {
assert subroutine instanceof JetDeclarationWithBody;
JetDeclarationWithBody function = (JetDeclarationWithBody) subroutine;
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression == null) return;
List<JetElement> returnedExpressions = Lists.newArrayList();
collectReturnExpressions(function.asElement(), returnedExpressions);
collectReturnExpressions(returnedExpressions);
boolean nothingReturned = returnedExpressions.isEmpty();
@@ -166,8 +139,8 @@ public class JetFlowInformationProvider {
trace.report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType));
}
final boolean blockBody = function.hasBlockBody();
final Set<JetElement> rootUnreachableElements = collectUnreachableCode(function.asElement());
final Set<JetElement> rootUnreachableElements = collectUnreachableCode();
for (JetElement element : rootUnreachableElements) {
trace.report(UNREACHABLE_CODE.on(element));
}
@@ -195,10 +168,7 @@ public class JetFlowInformationProvider {
}
}
private Set<JetElement> collectUnreachableCode(@NotNull JetElement subroutine) {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
private Set<JetElement> collectUnreachableCode() {
Collection<JetElement> unreachableElements = Lists.newArrayList();
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
if (deadInstruction instanceof JetElementInstruction &&
@@ -213,73 +183,61 @@ public class JetFlowInformationProvider {
////////////////////////////////////////////////////////////////////////////////
// Uninitialized variables analysis
public void markUninitializedVariables(@NotNull JetElement subroutine, final boolean processLocalDeclaration) {
final Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
JetControlFlowGraphTraverser<Map<VariableDescriptor, VariableInitializers>> traverser = JetControlFlowGraphTraverser.create(pseudocode, false, true);
Collection<VariableDescriptor> usedVariables = collectUsedVariables(pseudocode);
final Collection<VariableDescriptor> declaredVariables = collectDeclaredVariables(subroutine);
Map<VariableDescriptor, VariableInitializers> initialMapForStartInstruction = prepareInitialMapForStartInstruction(usedVariables, declaredVariables);
traverser.collectInformationFromInstructionGraph(Collections.<VariableDescriptor, VariableInitializers>emptyMap(), initialMapForStartInstruction,
new JetControlFlowGraphTraverser.InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitializers>>() {
@Override
public Pair<Map<VariableDescriptor, VariableInitializers>, Map<VariableDescriptor, VariableInitializers>> execute(
@NotNull Instruction instruction,
@NotNull Collection<Map<VariableDescriptor, VariableInitializers>> incomingEdgesData) {
Map<VariableDescriptor, VariableInitializers> enterInstructionData = mergeIncomingEdgesData(incomingEdgesData);
Map<VariableDescriptor, VariableInitializers> exitInstructionData = addVariableInitializerFromCurrentInstructionIfAny(instruction, enterInstructionData);
return Pair.create(enterInstructionData, exitInstructionData);
}
});
public void markUninitializedVariables(final boolean processLocalDeclaration) {
final Collection<VariableDescriptor> varWithUninitializedErrorGenerated = Sets.newHashSet();
final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet();
final boolean processClassOrObject = subroutine instanceof JetClassOrObject;
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableInitializers>>() {
Map<Instruction, Edges<Map<VariableDescriptor,VariableInitState>>> initializers = pseudocodeVariablesData.getVariableInitializers();
final Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode);
PseudocodeTraverser.traverse(pseudocode, true, true, initializers, new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState>>() {
@Override
public void execute(@NotNull Instruction instruction, @Nullable Map<VariableDescriptor, VariableInitializers> enterData, @Nullable Map<VariableDescriptor, VariableInitializers> exitData) {
assert enterData != null && exitData != null;
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, true);
public void execute(@NotNull Instruction instruction,
@Nullable Map<VariableDescriptor, VariableInitState> in,
@Nullable Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState> out) {
assert in != null && out != null;
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, true, trace.getBindingContext());
if (variableDescriptor == null) return;
if (!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction)) return;
VariableInitState outInitState = out.get(variableDescriptor);
if (instruction instanceof ReadValueInstruction) {
JetElement element = ((ReadValueInstruction) instruction).getElement();
boolean error = checkBackingField(variableDescriptor, element);
if (!error && declaredVariables.contains(variableDescriptor)) {
checkIsInitialized(variableDescriptor, element, exitData.get(variableDescriptor), varWithUninitializedErrorGenerated);
checkIsInitialized(variableDescriptor, element, outInitState, varWithUninitializedErrorGenerated);
}
return;
}
else if (instruction instanceof WriteValueInstruction) {
JetElement element = ((WriteValueInstruction) instruction).getlValue();
boolean error = checkBackingField(variableDescriptor, element);
if (!(element instanceof JetExpression)) return;
if (!error && !processLocalDeclaration) { // error has been generated before, while processing outer function of this local declaration
error = checkValReassignment(variableDescriptor, (JetExpression) element, enterData.get(variableDescriptor), varWithValReassignErrorGenerated);
}
if (!error && processClassOrObject) {
error = checkAssignmentBeforeDeclaration(variableDescriptor, (JetExpression) element, enterData.get(variableDescriptor), exitData.get(variableDescriptor));
}
if (!error && processClassOrObject) {
checkInitializationUsingBackingField(variableDescriptor, (JetExpression) element, enterData.get(variableDescriptor), exitData.get(variableDescriptor));
}
JetElement element = ((WriteValueInstruction) instruction).getlValue();
boolean error = checkBackingField(variableDescriptor, element);
if (!(element instanceof JetExpression)) return;
PseudocodeVariablesData.VariableInitState inInitState = in.get(variableDescriptor);
if (!error && !processLocalDeclaration) { // error has been generated before, while processing outer function of this local declaration
error = checkValReassignment(variableDescriptor, (JetExpression) element, inInitState, varWithValReassignErrorGenerated);
}
if (!error && processClassOrObject) {
error = checkAssignmentBeforeDeclaration(variableDescriptor, (JetExpression) element, inInitState, outInitState);
}
if (!error && processClassOrObject) {
checkInitializationUsingBackingField(variableDescriptor, (JetExpression) element, inInitState, outInitState);
}
}
});
recordInitializedVariables(declaredVariables, traverser.getResultInfo());
analyzeLocalDeclarations(pseudocode, processLocalDeclaration);
Pseudocode pseudocode = pseudocodeVariablesData.getPseudocode();
recordInitializedVariables(pseudocode, initializers);
for (LocalDeclarationInstruction instruction : pseudocode.getLocalDeclarations()) {
recordInitializedVariables(instruction.getBody(), initializers);
}
}
private void checkIsInitialized(@NotNull VariableDescriptor variableDescriptor,
@NotNull JetElement element,
@NotNull VariableInitializers variableInitializers,
private void checkIsInitialized(@NotNull VariableDescriptor variableDescriptor,
@NotNull JetElement element,
@NotNull PseudocodeVariablesData.VariableInitState variableInitState,
@NotNull Collection<VariableDescriptor> varWithUninitializedErrorGenerated) {
if (!(element instanceof JetSimpleNameExpression)) return;
boolean isInitialized = variableInitializers.isInitialized();
boolean isInitialized = variableInitState.isInitialized;
if (variableDescriptor instanceof PropertyDescriptor) {
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) {
isInitialized = true;
@@ -288,7 +246,8 @@ public class JetFlowInformationProvider {
if (!isInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
varWithUninitializedErrorGenerated.add(variableDescriptor);
if (variableDescriptor instanceof ValueParameterDescriptor) {
trace.report(Errors.UNINITIALIZED_PARAMETER.on((JetSimpleNameExpression) element, (ValueParameterDescriptor) variableDescriptor));
trace.report(Errors.UNINITIALIZED_PARAMETER.on((JetSimpleNameExpression) element,
(ValueParameterDescriptor) variableDescriptor));
}
else {
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
@@ -296,17 +255,13 @@ public class JetFlowInformationProvider {
}
}
private boolean checkValReassignment(@NotNull VariableDescriptor variableDescriptor,
@NotNull JetExpression expression,
@NotNull VariableInitializers enterInitializers,
private boolean checkValReassignment(@NotNull VariableDescriptor variableDescriptor,
@NotNull JetExpression expression,
@NotNull VariableInitState enterInitState,
@NotNull Collection<VariableDescriptor> varWithValReassignErrorGenerated) {
boolean isInitializedNotHere = enterInitializers.isInitialized();
Set<JetElement> possibleLocalInitializers = enterInitializers.getPossibleLocalInitializers();
if (possibleLocalInitializers.size() == 1) {
JetElement initializer = possibleLocalInitializers.iterator().next();
if (initializer instanceof JetProperty && initializer == expression.getParent()) {
isInitializedNotHere = false;
}
boolean isInitializedNotHere = enterInitState.isInitialized;
if (expression.getParent() instanceof JetProperty && ((JetProperty)expression).getInitializer() != null) {
isInitializedNotHere = false;
}
boolean hasBackingField = true;
if (variableDescriptor instanceof PropertyDescriptor) {
@@ -348,17 +303,17 @@ public class JetFlowInformationProvider {
}
return false;
}
private boolean checkAssignmentBeforeDeclaration(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitializers enterInitializers, @NotNull VariableInitializers exitInitializers) {
if (!enterInitializers.isDeclared() && !exitInitializers.isDeclared() && !enterInitializers.isInitialized() && exitInitializers.isInitialized()) {
private boolean checkAssignmentBeforeDeclaration(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitState enterInitState, @NotNull VariableInitState exitInitState) {
if (!enterInitState.isDeclared && !exitInitState.isDeclared && !enterInitState.isInitialized && exitInitState.isInitialized) {
trace.report(Errors.INITIALIZATION_BEFORE_DECLARATION.on(expression, variableDescriptor));
return true;
}
return false;
}
private boolean checkInitializationUsingBackingField(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitializers enterInitializers, @NotNull VariableInitializers exitInitializers) {
if (variableDescriptor instanceof PropertyDescriptor && !enterInitializers.isInitialized() && exitInitializers.isInitialized()) {
private boolean checkInitializationUsingBackingField(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitState enterInitState, @NotNull VariableInitState exitInitState) {
if (variableDescriptor instanceof PropertyDescriptor && !enterInitState.isInitialized && exitInitState.isInitialized) {
if (!variableDescriptor.isVar()) return false;
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) return false;
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
@@ -397,7 +352,9 @@ public class JetFlowInformationProvider {
}
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
boolean insideSelfAccessors = PsiTreeUtil.isAncestor(property, element, false);
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor) && !insideSelfAccessors) { // not to generate error in accessors of abstract properties, there is one: declared accessor of abstract property
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor) &&
!insideSelfAccessors) { // not to generate error in accessors of abstract properties, there is one: declared accessor of abstract property
if (((PropertyDescriptor) variableDescriptor).getModality() == Modality.ABSTRACT) {
trace.report(NO_BACKING_FIELD_ABSTRACT_PROPERTY.on(element));
}
@@ -436,173 +393,44 @@ public class JetFlowInformationProvider {
return false;
}
private void recordInitializedVariables(Collection<VariableDescriptor> declaredVariables, Map<VariableDescriptor, VariableInitializers> resultInfo) {
for (Map.Entry<VariableDescriptor, VariableInitializers> entry : resultInfo.entrySet()) {
VariableDescriptor variable = entry.getKey();
if (variable instanceof PropertyDescriptor && declaredVariables.contains(variable)) {
VariableInitializers initializers = entry.getValue();
trace.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) variable, initializers.isInitialized());
}
}
}
private void analyzeLocalDeclarations(Pseudocode pseudocode, boolean processLocalDeclaration) {
for (Instruction instruction : pseudocode.getInstructions()) {
if (instruction instanceof LocalDeclarationInstruction) {
JetElement element = ((LocalDeclarationInstruction) instruction).getElement();
markUninitializedVariables(element, processLocalDeclaration);
}
}
}
private Map<VariableDescriptor, VariableInitializers> addVariableInitializerFromCurrentInstructionIfAny(Instruction instruction, Map<VariableDescriptor, VariableInitializers> enterInstructionData) {
Map<VariableDescriptor, VariableInitializers> exitInstructionData = Maps.newHashMap(enterInstructionData);
if (instruction instanceof WriteValueInstruction) {
VariableDescriptor variable = extractVariableDescriptorIfAny(instruction, false);
VariableInitializers enterInitializers = enterInstructionData.get(variable);
VariableInitializers initializationAtThisElement = new VariableInitializers(((WriteValueInstruction) instruction).getElement(), enterInitializers);
exitInstructionData.put(variable, initializationAtThisElement);
}
else if (instruction instanceof VariableDeclarationInstruction) {
VariableDescriptor variable = extractVariableDescriptorIfAny(instruction, false);
VariableInitializers enterInitializers = enterInstructionData.get(variable);
if (enterInitializers == null || !enterInitializers.isInitialized() || !enterInitializers.isDeclared()) {
JetElement element = ((VariableDeclarationInstruction) instruction).getElement();
if (element instanceof JetProperty) {
JetProperty property = (JetProperty) element;
if (property.getInitializer() == null) {
boolean isInitialized = enterInitializers != null && enterInitializers.isInitialized();
VariableInitializers variableDeclarationInfo = new VariableInitializers(isInitialized, true);
exitInstructionData.put(variable, variableDeclarationInfo);
}
}
}
}
return exitInstructionData;
}
private Map<VariableDescriptor, VariableInitializers> mergeIncomingEdgesData(Collection<Map<VariableDescriptor, VariableInitializers>> incomingEdgesData) {
Set<VariableDescriptor> variablesInScope = Sets.newHashSet();
for (Map<VariableDescriptor, VariableInitializers> edgeData : incomingEdgesData) {
variablesInScope.addAll(edgeData.keySet());
}
Map<VariableDescriptor, VariableInitializers> enterInstructionData = Maps.newHashMap();
for (VariableDescriptor variable : variablesInScope) {
Set<VariableInitializers> edgesDataForVariable = Sets.newHashSet();
for (Map<VariableDescriptor, VariableInitializers> edgeData : incomingEdgesData) {
VariableInitializers initializers = edgeData.get(variable);
if (initializers != null) {
edgesDataForVariable.add(initializers);
}
}
enterInstructionData.put(variable, new VariableInitializers(edgesDataForVariable));
}
return enterInstructionData;
}
private Map<VariableDescriptor, VariableInitializers> prepareInitialMapForStartInstruction(Collection<VariableDescriptor> usedVariables, Collection<VariableDescriptor> declaredVariables) {
Map<VariableDescriptor, VariableInitializers> initialMapForStartInstruction = Maps.newHashMap();
VariableInitializers isInitializedForExternalVariable = new VariableInitializers(true);
VariableInitializers isNotInitializedForDeclaredVariable = new VariableInitializers(false);
private void recordInitializedVariables(@NotNull Pseudocode pseudocode, @NotNull Map<Instruction, Edges<Map<VariableDescriptor,PseudocodeVariablesData.VariableInitState>>> initializersMap) {
Edges<Map<VariableDescriptor, VariableInitState>> initializers = initializersMap.get(pseudocode.getExitInstruction());
Set<VariableDescriptor> usedVariables = pseudocodeVariablesData.getUsedVariables(pseudocode);
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode);
for (VariableDescriptor variable : usedVariables) {
if (declaredVariables.contains(variable)) {
initialMapForStartInstruction.put(variable, isNotInitializedForDeclaredVariable);
}
else {
initialMapForStartInstruction.put(variable, isInitializedForExternalVariable);
if (variable instanceof PropertyDescriptor && declaredVariables.contains(variable)) {
PseudocodeVariablesData.VariableInitState variableInitState = initializers.in.get(variable);
if (variableInitState == null) return;
trace.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) variable, variableInitState.isInitialized);
}
}
return initialMapForStartInstruction;
}
////////////////////////////////////////////////////////////////////////////////
public void markNotOnlyInvokedFunctionVariables(@NotNull JetElement subroutine, List<? extends VariableDescriptor> variables) {
final List<VariableDescriptor> functionVariables = Lists.newArrayList();
for (VariableDescriptor variable : variables) {
if (JetStandardClasses.isFunctionType(variable.getReturnType())) {
functionVariables.add(variable);
}
}
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
JetControlFlowGraphTraverser.<Void>create(pseudocode, true, true).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
@Override
public void execute(@NotNull Instruction instruction, Void enterData, Void exitData) {
if (instruction instanceof ReadValueInstruction) {
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, false);
if (variableDescriptor != null && functionVariables.contains(variableDescriptor)) {
//check that we only invoke this variable
JetElement element = ((ReadValueInstruction) instruction).getElement();
if (element instanceof JetSimpleNameExpression && !(element.getParent() instanceof JetCallExpression)) {
trace.report(Errors.FUNCTION_PARAMETERS_OF_INLINE_FUNCTION.on((JetSimpleNameExpression) element, variableDescriptor));
}
}
}
}
});
}
////////////////////////////////////////////////////////////////////////////////
// "Unused variable" & "unused value" analyses
public void markUnusedVariables(@NotNull JetElement subroutine) {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
JetControlFlowGraphTraverser<Map<VariableDescriptor, VariableStatus>> traverser = JetControlFlowGraphTraverser.create(pseudocode, true, false);
final Collection<VariableDescriptor> declaredVariables = collectDeclaredVariables(subroutine);
Map<VariableDescriptor, VariableStatus> sinkInstructionData = Maps.newHashMap();
traverser.collectInformationFromInstructionGraph(Collections.<VariableDescriptor, VariableStatus>emptyMap(), sinkInstructionData, new JetControlFlowGraphTraverser.InstructionDataMergeStrategy<Map<VariableDescriptor, VariableStatus>>() {
public void markUnusedVariables() {
Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> variableStatusData = pseudocodeVariablesData.getVariableUseStatusData();
InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableUseState>> variableStatusAnalyzeStrategy =
new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, PseudocodeVariablesData.VariableUseState>>() {
@Override
public Pair<Map<VariableDescriptor, VariableStatus>, Map<VariableDescriptor, VariableStatus>> execute(@NotNull Instruction instruction, @NotNull Collection<Map<VariableDescriptor, VariableStatus>> incomingEdgesData) {
Map<VariableDescriptor, VariableStatus> enterResult = Maps.newHashMap();
for (Map<VariableDescriptor, VariableStatus> edgeData : incomingEdgesData) {
for (Map.Entry<VariableDescriptor, VariableStatus> entry : edgeData.entrySet()) {
VariableDescriptor variableDescriptor = entry.getKey();
VariableStatus variableStatus = entry.getValue();
enterResult.put(variableDescriptor, variableStatus.merge(enterResult.get(variableDescriptor)));
}
}
Map<VariableDescriptor, VariableStatus> exitResult = Maps.newHashMap(enterResult);
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, true);
if (variableDescriptor != null) {
if (instruction instanceof ReadValueInstruction) {
exitResult.put(variableDescriptor, VariableStatus.READ);
}
else if (instruction instanceof WriteValueInstruction) {
VariableStatus variableStatus = enterResult.get(variableDescriptor);
if (variableStatus == null) variableStatus = VariableStatus.UNUSED;
switch(variableStatus) {
case UNUSED:
case ONLY_WRITTEN:
exitResult.put(variableDescriptor, VariableStatus.ONLY_WRITTEN);
break;
case WRITTEN:
case READ:
exitResult.put(variableDescriptor, VariableStatus.WRITTEN);
}
}
}
return new Pair<Map<VariableDescriptor, VariableStatus>, Map<VariableDescriptor, VariableStatus>>(enterResult, exitResult);
}
});
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableStatus>>() {
@Override
public void execute(@NotNull Instruction instruction, @Nullable Map<VariableDescriptor, VariableStatus> enterData, @Nullable Map<VariableDescriptor, VariableStatus> exitData) {
assert enterData != null && exitData != null;
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, false);
public void execute(@NotNull Instruction instruction,
@Nullable Map<VariableDescriptor, PseudocodeVariablesData.VariableUseState> in,
@Nullable Map<VariableDescriptor, VariableUseState> out) {
assert in != null && out != null;
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(instruction.getOwner());
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, false,
trace.getBindingContext());
if (variableDescriptor == null || !declaredVariables.contains(variableDescriptor) ||
!DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return;
VariableStatus variableStatus = enterData.get(variableDescriptor);
PseudocodeVariablesData.VariableUseState variableUseState = in.get(variableDescriptor);
if (instruction instanceof WriteValueInstruction) {
if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor)) return;
JetElement element = ((WriteValueInstruction) instruction).getElement();
if (variableStatus != VariableStatus.READ) {
if (element instanceof JetBinaryExpression && ((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
if (variableUseState != LAST_READ) {
if (element instanceof JetBinaryExpression &&
((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
JetExpression right = ((JetBinaryExpression) element).getRight();
if (right != null) {
trace.report(Errors.UNUSED_VALUE.on(right, right, variableDescriptor));
@@ -621,7 +449,7 @@ public class JetFlowInformationProvider {
if (element instanceof JetNamedDeclaration) {
PsiElement nameIdentifier = ((JetNamedDeclaration) element).getNameIdentifier();
if (nameIdentifier == null) return;
if (variableStatus == null || variableStatus == VariableStatus.UNUSED) {
if (!VariableUseState.isUsed(variableUseState)) {
if (element instanceof JetProperty) {
trace.report(Errors.UNUSED_VARIABLE.on((JetProperty) element, variableDescriptor));
}
@@ -629,8 +457,9 @@ public class JetFlowInformationProvider {
PsiElement psiElement = element.getParent().getParent();
if (psiElement instanceof JetFunction) {
boolean isMain = (psiElement instanceof JetNamedFunction) && JetMainDetector.isMain((JetNamedFunction) psiElement);
if (psiElement instanceof JetFunctionLiteral) return;
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement);
assert descriptor instanceof FunctionDescriptor;
assert descriptor instanceof FunctionDescriptor : psiElement.getText();
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
if (!isMain && !functionDescriptor.getModality().isOverridable() && functionDescriptor.getOverriddenDescriptors().isEmpty()) {
trace.report(Errors.UNUSED_PARAMETER.on((JetParameter) element, variableDescriptor));
@@ -638,52 +467,34 @@ public class JetFlowInformationProvider {
}
}
}
else if (variableStatus == VariableStatus.ONLY_WRITTEN && element instanceof JetProperty) {
else if (variableUseState == ONLY_WRITTEN_NEVER_READ && element instanceof JetProperty) {
trace.report(Errors.ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE.on((JetNamedDeclaration) element, variableDescriptor));
}
else if (variableStatus == VariableStatus.WRITTEN && element instanceof JetProperty) {
else if (variableUseState == LAST_WRITTEN && element instanceof JetProperty) {
JetExpression initializer = ((JetProperty) element).getInitializer();
if (initializer != null) {
trace.report(Errors.VARIABLE_WITH_REDUNDANT_INITIALIZER.on(initializer, variableDescriptor));
}
}
}
}
}
});
}
private static enum VariableStatus {
READ(3),
WRITTEN(2),
ONLY_WRITTEN(1),
UNUSED(0);
private int importance;
private VariableStatus(int importance) {
this.importance = importance;
}
public VariableStatus merge(@Nullable VariableStatus variableStatus) {
if (variableStatus == null || importance > variableStatus.importance) return this;
return variableStatus;
}
};
PseudocodeTraverser.traverse(pseudocode, false, true, variableStatusData, variableStatusAnalyzeStrategy);
}
////////////////////////////////////////////////////////////////////////////////
// "Unused literals" in block
public void markUnusedLiteralsInBlock(@NotNull JetElement subroutine) {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
public void markUnusedLiteralsInBlock() {
assert pseudocode != null;
JetControlFlowGraphTraverser<Void> traverser = JetControlFlowGraphTraverser.create(pseudocode, true, true);
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
PseudocodeTraverser.traverse(
pseudocode, true, new InstructionAnalyzeStrategy() {
@Override
public void execute(@NotNull Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) {
public void execute(@NotNull Instruction instruction) {
if (!(instruction instanceof ReadValueInstruction)) return;
JetElement element = ((ReadValueInstruction) instruction).getElement();
JetElement element =
((ReadValueInstruction) instruction).getElement();
if (!(element instanceof JetFunctionLiteralExpression
|| element instanceof JetConstantExpression
|| element instanceof JetStringTemplateExpression
@@ -694,7 +505,8 @@ public class JetFlowInformationProvider {
if (parent instanceof JetBlockExpression) {
if (!JetPsiUtil.isImplicitlyUsed(element)) {
if (element instanceof JetFunctionLiteralExpression) {
trace.report(Errors.UNUSED_FUNCTION_LITERAL.on((JetFunctionLiteralExpression) element));
trace.report(Errors.UNUSED_FUNCTION_LITERAL
.on((JetFunctionLiteralExpression) element));
}
else {
trace.report(Errors.UNUSED_EXPRESSION.on(element));
@@ -704,133 +516,4 @@ public class JetFlowInformationProvider {
}
});
}
////////////////////////////////////////////////////////////////////////////////
// Util methods 7
@Nullable
private VariableDescriptor extractVariableDescriptorIfAny(Instruction instruction, boolean onlyReference) {
JetElement element = null;
if (instruction instanceof ReadValueInstruction) {
element = ((ReadValueInstruction) instruction).getElement();
}
else if (instruction instanceof WriteValueInstruction) {
element = ((WriteValueInstruction) instruction).getlValue();
}
else if (instruction instanceof VariableDeclarationInstruction) {
element = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement();
}
return BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), element, onlyReference);
}
private Collection<VariableDescriptor> collectUsedVariables(Pseudocode pseudocode) {
final Set<VariableDescriptor> usedVariables = Sets.newHashSet();
JetControlFlowGraphTraverser.<Void>create(pseudocode, true, true).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
@Override
public void execute(@NotNull Instruction instruction, Void enterData, Void exitData) {
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, false);
if (variableDescriptor != null) {
usedVariables.add(variableDescriptor);
}
}
});
return usedVariables;
}
private Collection<VariableDescriptor> collectDeclaredVariables(JetElement element) {
final Pseudocode pseudocode = pseudocodeMap.get(element);
assert pseudocode != null;
final Set<VariableDescriptor> declaredVariables = Sets.newHashSet();
JetControlFlowGraphTraverser.<Void>create(pseudocode, false, true).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
@Override
public void execute(@NotNull Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) {
if (instruction instanceof VariableDeclarationInstruction) {
JetDeclaration variableDeclarationElement = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement();
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement);
if (descriptor != null) {
assert descriptor instanceof VariableDescriptor;
declaredVariables.add((VariableDescriptor) descriptor);
}
}
}
});
return declaredVariables;
}
////////////////////////////////////////////////////////////////////////////////
// Local class for uninitialized variables analysis
private static class VariableInitializers {
private Set<JetElement> possibleLocalInitializers = Sets.newHashSet();
private boolean isInitialized;
private boolean isDeclared;
public VariableInitializers(boolean isInitialized) {
this(isInitialized, false);
}
public VariableInitializers(boolean isInitialized, boolean isDeclared) {
this.isInitialized = isInitialized;
this.isDeclared = isDeclared;
}
public VariableInitializers(JetElement element, @Nullable VariableInitializers previous) {
isInitialized = true;
isDeclared = element instanceof JetProperty || (previous != null && previous.isDeclared());
possibleLocalInitializers.add(element);
}
public VariableInitializers(Set<VariableInitializers> edgesData) {
isInitialized = true;
isDeclared = true;
for (VariableInitializers edgeData : edgesData) {
if (!edgeData.isInitialized) {
isInitialized = false;
}
if (!edgeData.isDeclared) {
isDeclared = false;
}
possibleLocalInitializers.addAll(edgeData.possibleLocalInitializers);
}
}
public Set<JetElement> getPossibleLocalInitializers() {
return possibleLocalInitializers;
}
public boolean isInitialized() {
return isInitialized;
}
public boolean isDeclared() {
return isDeclared;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof VariableInitializers)) return false;
VariableInitializers that = (VariableInitializers) o;
if (isDeclared != that.isDeclared) return false;
if (isInitialized != that.isInitialized) return false;
if (possibleLocalInitializers != null
? !possibleLocalInitializers.equals(that.possibleLocalInitializers)
: that.possibleLocalInitializers != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = possibleLocalInitializers != null ? possibleLocalInitializers.hashCode() : 0;
result = 31 * result + (isInitialized ? 1 : 0);
result = 31 * result + (isDeclared ? 1 : 0);
return result;
}
}
}
@@ -0,0 +1,204 @@
/*
* 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.lang.cfg;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author svtk
*/
public class PseudocodeTraverser {
@NotNull
private static Instruction getStartInstruction(@NotNull Pseudocode pseudocode, boolean directOrder) {
return directOrder ? pseudocode.getEnterInstruction() : pseudocode.getSinkInstruction();
}
public static <D> Map<Instruction, Edges<D>> collectData(
@NotNull Pseudocode pseudocode, boolean directOrder, boolean lookInside,
@NotNull D initialDataValue, @NotNull D initialDataValueForEnterInstruction,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy) {
Map<Instruction, Edges<D>> edgesMap = Maps.newLinkedHashMap();
initializeEdgesMap(pseudocode, lookInside, edgesMap, initialDataValue);
edgesMap.put(getStartInstruction(pseudocode, directOrder), Edges.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction));
boolean[] changed = new boolean[1];
changed[0] = true;
while (changed[0]) {
changed[0] = false;
collectDataFromSubgraph(pseudocode, directOrder, lookInside, edgesMap, instructionDataMergeStrategy,
Collections.<Instruction>emptyList(), changed, false);
}
return edgesMap;
}
private static <D> void initializeEdgesMap(
@NotNull Pseudocode pseudocode, boolean lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull D initialDataValue) {
List<Instruction> instructions = pseudocode.getInstructions();
Edges<D> initialEdge = Edges.create(initialDataValue, initialDataValue);
for (Instruction instruction : instructions) {
edgesMap.put(instruction, initialEdge);
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
initializeEdgesMap(((LocalDeclarationInstruction) instruction).getBody(), lookInside, edgesMap, initialDataValue);
}
}
}
private static <D> void collectDataFromSubgraph(
@NotNull Pseudocode pseudocode, boolean directOrder, boolean lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull InstructionDataMergeStrategy<D> instructionDataMergeStrategy,
@NotNull Collection<Instruction> previousSubGraphInstructions,
boolean[] changed, boolean isLocal) {
List<Instruction> instructions = directOrder ? pseudocode.getInstructions() : pseudocode.getReversedInstructions();
Instruction startInstruction = getStartInstruction(pseudocode, directOrder);
for (Instruction instruction : instructions) {
boolean isStart = directOrder ? instruction instanceof SubroutineEnterInstruction : instruction instanceof SubroutineSinkInstruction;
if (!isLocal && isStart) continue;
Collection<Instruction> allPreviousInstructions;
Collection<Instruction> previousInstructions = directOrder ? instruction.getPreviousInstructions() : instruction.getNextInstructions();
if (instruction == startInstruction && !previousSubGraphInstructions.isEmpty()) {
allPreviousInstructions = Lists.newArrayList(previousInstructions);
allPreviousInstructions.addAll(previousSubGraphInstructions);
}
else {
allPreviousInstructions = previousInstructions;
}
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
collectDataFromSubgraph(subroutinePseudocode, directOrder, lookInside, edgesMap, instructionDataMergeStrategy,
previousInstructions,
changed, true);
Instruction lastInstruction = directOrder ? subroutinePseudocode.getSinkInstruction() : subroutinePseudocode.getEnterInstruction();
Edges<D> previousValue = edgesMap.get(instruction);
Edges<D> newValue = edgesMap.get(lastInstruction);
if (!previousValue.equals(newValue)) {
changed[0] = true;
edgesMap.put(instruction, newValue);
}
continue;
}
Edges<D> previousDataValue = edgesMap.get(instruction);
Collection<D> incomingEdgesData = Sets.newHashSet();
for (Instruction previousInstruction : allPreviousInstructions) {
Edges<D> previousData = edgesMap.get(previousInstruction);
if (previousData != null) {
incomingEdgesData.add(previousData.out);
}
}
Edges<D> mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData);
if (!mergedData.equals(previousDataValue)) {
changed[0] = true;
edgesMap.put(instruction, mergedData);
}
}
}
public static void traverse(
@NotNull Pseudocode pseudocode, boolean directOrder,
InstructionAnalyzeStrategy instructionAnalyzeStrategy) {
List<Instruction> instructions = directOrder ? pseudocode.getInstructions() : pseudocode.getReversedInstructions();
for (Instruction instruction : instructions) {
if (instruction instanceof LocalDeclarationInstruction) {
traverse(((LocalDeclarationInstruction) instruction).getBody(), directOrder, instructionAnalyzeStrategy);
}
instructionAnalyzeStrategy.execute(instruction);
}
}
public static <D> void traverse(
@NotNull Pseudocode pseudocode, boolean directOrder, boolean lookInside,
@NotNull Map<Instruction, Edges<D>> edgesMap,
@NotNull InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
List<Instruction> instructions = directOrder ? pseudocode.getInstructions() : pseudocode.getReversedInstructions();
for (Instruction instruction : instructions) {
if (lookInside && instruction instanceof LocalDeclarationInstruction) {
traverse(((LocalDeclarationInstruction) instruction).getBody(), directOrder, lookInside, edgesMap,
instructionDataAnalyzeStrategy);
}
Edges<D> edges = edgesMap.get(instruction);
instructionDataAnalyzeStrategy.execute(instruction, edges != null ? edges.in : null, edges != null ? edges.out : null);
}
}
public interface InstructionDataMergeStrategy<D> {
Edges<D> execute(@NotNull Instruction instruction, @NotNull Collection<D> incomingEdgesData);
}
public interface InstructionDataAnalyzeStrategy<D> {
void execute(@NotNull Instruction instruction, @Nullable D enterData, @Nullable D exitData);
}
public interface InstructionAnalyzeStrategy {
void execute(@NotNull Instruction instruction);
}
public static class Edges<T> {
public final T in;
public final T out;
Edges(@NotNull T in, @NotNull T out) {
this.in = in;
this.out = out;
}
public static <T> Edges<T> create(@NotNull T in, @NotNull T out) {
return new Edges<T>(in, out);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Edges)) return false;
Edges edges = (Edges) o;
if (in != null ? !in.equals(edges.in) : edges.in != null) return false;
if (out != null ? !out.equals(edges.out) : edges.out != null) return false;
return true;
}
@Override
public int hashCode() {
int result = in != null ? in.hashCode() : 0;
result = 31 * result + (out != null ? out.hashCode() : 0);
return result;
}
}
}
@@ -0,0 +1,348 @@
/*
* 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.lang.cfg;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*;
import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/**
* @author svtk
*/
public class PseudocodeVariablesData {
private final Pseudocode pseudocode;
private final BindingContext bindingContext;
private final Map<Pseudocode, Set<VariableDescriptor>> declaredVariablesInEachDeclaration = Maps.newHashMap();
private final Map<Pseudocode, Set<VariableDescriptor>> usedVariablesInEachDeclaration = Maps.newHashMap();
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializersMap;
private Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> variableStatusMap;
public PseudocodeVariablesData(@NotNull Pseudocode pseudocode, @NotNull BindingContext bindingContext) {
this.pseudocode = pseudocode;
this.bindingContext = bindingContext;
}
@NotNull
public Pseudocode getPseudocode() {
return pseudocode;
}
@NotNull
public Set<VariableDescriptor> getUsedVariables(@NotNull Pseudocode pseudocode) {
Set<VariableDescriptor> usedVariables = usedVariablesInEachDeclaration.get(pseudocode);
if (usedVariables == null) {
final Set<VariableDescriptor> result = Sets.newHashSet();
PseudocodeTraverser.traverse(pseudocode, true, new InstructionAnalyzeStrategy() {
@Override
public void execute(@NotNull Instruction instruction) {
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, false,
bindingContext);
if (variableDescriptor != null) {
result.add(variableDescriptor);
}
}
});
usedVariables = Collections.unmodifiableSet(result);
usedVariablesInEachDeclaration.put(pseudocode, usedVariables);
}
return usedVariables;
}
@NotNull
public Set<VariableDescriptor> getDeclaredVariables(@NotNull Pseudocode pseudocode) {
Set<VariableDescriptor> declaredVariables = declaredVariablesInEachDeclaration.get(pseudocode);
if (declaredVariables == null) {
declaredVariables = Sets.newHashSet();
for (Instruction instruction : pseudocode.getInstructions()) {
if (instruction instanceof VariableDeclarationInstruction) {
JetDeclaration variableDeclarationElement = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement();
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement);
if (descriptor != null) {
assert descriptor instanceof VariableDescriptor;
declaredVariables.add((VariableDescriptor) descriptor);
}
}
}
declaredVariables = Collections.unmodifiableSet(declaredVariables);
declaredVariablesInEachDeclaration.put(pseudocode, declaredVariables);
}
return declaredVariables;
}
// variable initializers
@NotNull
public Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers() {
if (variableInitializersMap == null) {
variableInitializersMap = getVariableInitializers(pseudocode);
}
return variableInitializersMap;
}
@NotNull
private Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> getVariableInitializers(@NotNull Pseudocode pseudocode) {
Set<VariableDescriptor> usedVariables = getUsedVariables(pseudocode);
Set<VariableDescriptor> declaredVariables = getDeclaredVariables(pseudocode);
Map<VariableDescriptor, VariableInitState> initialMap = Collections.emptyMap();
final Map<VariableDescriptor, VariableInitState> initialMapForStartInstruction = prepareInitializersMapForStartInstruction(
usedVariables, declaredVariables);
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializersMap = PseudocodeTraverser.collectData(
pseudocode, /* directOrder = */ true, /* lookInside = */ false,
initialMap, initialMapForStartInstruction, new PseudocodeTraverser.InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>>() {
@Override
public Edges<Map<VariableDescriptor, VariableInitState>> execute(
@NotNull Instruction instruction, @NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData) {
Map<VariableDescriptor, VariableInitState> enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData);
Map<VariableDescriptor, VariableInitState> exitInstructionData =
addVariableInitStateFromCurrentInstructionIfAny(instruction, enterInstructionData);
return Edges.create(enterInstructionData, exitInstructionData);
}
});
for (LocalDeclarationInstruction localDeclarationInstruction : pseudocode.getLocalDeclarations()) {
Pseudocode localPseudocode = localDeclarationInstruction.getBody();
Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> initializersForLocalDeclaration = getVariableInitializers(localPseudocode);
for (Instruction instruction : initializersForLocalDeclaration.keySet()) {
//todo
if (!variableInitializersMap.containsKey(instruction)) {
variableInitializersMap.put(instruction, initializersForLocalDeclaration.get(instruction));
}
}
variableInitializersMap.putAll(initializersForLocalDeclaration);
}
return variableInitializersMap;
}
@NotNull
private Map<VariableDescriptor, VariableInitState> prepareInitializersMapForStartInstruction(
@NotNull Collection<VariableDescriptor> usedVariables,
@NotNull Collection<VariableDescriptor> declaredVariables) {
Map<VariableDescriptor, VariableInitState> initialMapForStartInstruction = Maps.newHashMap();
VariableInitState initializedForExternalVariable = VariableInitState.create(true);
VariableInitState notInitializedForDeclaredVariable = VariableInitState.create(false);
for (VariableDescriptor variable : usedVariables) {
if (declaredVariables.contains(variable)) {
initialMapForStartInstruction.put(variable, notInitializedForDeclaredVariable);
}
else {
initialMapForStartInstruction.put(variable, initializedForExternalVariable);
}
}
return initialMapForStartInstruction;
}
@NotNull
private Map<VariableDescriptor, VariableInitState> mergeIncomingEdgesDataForInitializers(
@NotNull Collection<Map<VariableDescriptor, VariableInitState>> incomingEdgesData) {
Set<VariableDescriptor> variablesInScope = Sets.newHashSet();
for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) {
variablesInScope.addAll(edgeData.keySet());
}
Map<VariableDescriptor, VariableInitState> enterInstructionData = Maps.newHashMap();
for (VariableDescriptor variable : variablesInScope) {
Set<VariableInitState> edgesDataForVariable = Sets.newHashSet();
for (Map<VariableDescriptor, VariableInitState> edgeData : incomingEdgesData) {
VariableInitState initState = edgeData.get(variable);
if (initState != null) {
edgesDataForVariable.add(initState);
}
}
enterInstructionData.put(variable, VariableInitState.create(edgesDataForVariable));
}
return enterInstructionData;
}
@NotNull
private Map<VariableDescriptor, VariableInitState> addVariableInitStateFromCurrentInstructionIfAny(
@NotNull Instruction instruction, @NotNull Map<VariableDescriptor, VariableInitState> enterInstructionData) {
if (!(instruction instanceof WriteValueInstruction) && !(instruction instanceof VariableDeclarationInstruction)) {
return enterInstructionData;
}
VariableDescriptor variable = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, false, bindingContext);
if (variable == null) {
return enterInstructionData;
}
Map<VariableDescriptor, VariableInitState> exitInstructionData = Maps.newHashMap(enterInstructionData);
if (instruction instanceof WriteValueInstruction) {
VariableInitState enterInitState = enterInstructionData.get(variable);
VariableInitState initializationAtThisElement =
VariableInitState.create(((WriteValueInstruction) instruction).getElement() instanceof JetProperty, enterInitState);
exitInstructionData.put(variable, initializationAtThisElement);
}
else { // instruction instanceof VariableDeclarationInstruction
VariableInitState enterInitState = enterInstructionData.get(variable);
if (enterInitState == null || !enterInitState.isInitialized || !enterInitState.isDeclared) {
boolean isInitialized = enterInitState != null && enterInitState.isInitialized;
VariableInitState variableDeclarationInfo = VariableInitState.create(isInitialized, true);
exitInstructionData.put(variable, variableDeclarationInfo);
}
}
return exitInstructionData;
}
// variable use
@NotNull
public Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> getVariableUseStatusData() {
if (variableStatusMap == null) {
Map<VariableDescriptor, VariableUseState> sinkInstructionData = Maps.newHashMap();
for (VariableDescriptor usedVariable : usedVariablesInEachDeclaration.get(pseudocode)) {
sinkInstructionData.put(usedVariable, VariableUseState.UNUSED);
}
InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>> collectVariableUseStatusStrategy = new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>>() {
@Override
public Edges<Map<VariableDescriptor, VariableUseState>> execute(@NotNull Instruction instruction,
@NotNull Collection<Map<VariableDescriptor, VariableUseState>> incomingEdgesData) {
Map<VariableDescriptor, VariableUseState> enterResult = Maps.newHashMap();
for (Map<VariableDescriptor, VariableUseState> edgeData : incomingEdgesData) {
for (Map.Entry<VariableDescriptor, VariableUseState> entry : edgeData.entrySet()) {
VariableDescriptor variableDescriptor = entry.getKey();
VariableUseState variableUseState = entry.getValue();
enterResult.put(variableDescriptor, variableUseState.merge(enterResult.get(variableDescriptor)));
}
}
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, true,
bindingContext);
if (variableDescriptor == null ||
(!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction))) {
return Edges.create(enterResult, enterResult);
}
Map<VariableDescriptor, VariableUseState> exitResult = Maps.newHashMap(enterResult);
if (instruction instanceof ReadValueInstruction) {
exitResult.put(variableDescriptor, VariableUseState.LAST_READ);
}
else { //instruction instanceof WriteValueInstruction
VariableUseState variableUseState = enterResult.get(variableDescriptor);
if (variableUseState == null) {
variableUseState = VariableUseState.UNUSED;
}
switch (variableUseState) {
case UNUSED:
case ONLY_WRITTEN_NEVER_READ:
exitResult.put(variableDescriptor, VariableUseState.ONLY_WRITTEN_NEVER_READ);
break;
case LAST_WRITTEN:
case LAST_READ:
exitResult.put(variableDescriptor, VariableUseState.LAST_WRITTEN);
}
}
return Edges.create(enterResult, exitResult);
}
};
variableStatusMap = PseudocodeTraverser.collectData(pseudocode, false, true,
Collections.<VariableDescriptor, VariableUseState>emptyMap(),
sinkInstructionData, collectVariableUseStatusStrategy);
}
return variableStatusMap;
}
public static class VariableInitState {
public final boolean isInitialized;
public final boolean isDeclared;
private VariableInitState(boolean isInitialized, boolean isDeclared) {
this.isInitialized = isInitialized;
this.isDeclared = isDeclared;
}
private static final VariableInitState VS_TT = new VariableInitState(true, true);
private static final VariableInitState VS_TF = new VariableInitState(true, false);
private static final VariableInitState VS_FT = new VariableInitState(false, true);
private static final VariableInitState VS_FF = new VariableInitState(false, false);
private static VariableInitState create(boolean isInitialized, boolean isDeclared) {
if (isInitialized) {
if (isDeclared) return VS_TT;
return VS_TF;
}
if (isDeclared) return VS_FT;
return VS_FF;
}
private static VariableInitState create(boolean isInitialized) {
return create(isInitialized, false);
}
private static VariableInitState create(boolean isDeclaredHere, @Nullable VariableInitState mergedEdgesData) {
return create(true, isDeclaredHere || (mergedEdgesData != null && mergedEdgesData.isDeclared));
}
private static VariableInitState create(@NotNull Set<VariableInitState> edgesData) {
boolean isInitialized = true;
boolean isDeclared = true;
for (VariableInitState edgeData : edgesData) {
if (!edgeData.isInitialized) {
isInitialized = false;
}
if (!edgeData.isDeclared) {
isDeclared = false;
}
}
return create(isInitialized, isDeclared);
}
}
public static enum VariableUseState {
LAST_READ(3),
LAST_WRITTEN(2),
ONLY_WRITTEN_NEVER_READ(1),
UNUSED(0);
private final int importance;
VariableUseState(int importance) {
this.importance = importance;
}
private VariableUseState merge(@Nullable VariableUseState variableUseState) {
if (variableUseState == null || importance > variableUseState.importance) return this;
return variableUseState;
}
public static boolean isUsed(@Nullable VariableUseState variableUseState) {
return variableUseState != null && variableUseState != UNUSED;
}
}
}
@@ -35,12 +35,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
private final Stack<BlockInfo> allBlocks = new Stack<BlockInfo>();
private final JetPseudocodeTrace trace;
public JetControlFlowInstructionsGenerator(JetPseudocodeTrace trace) {
this.trace = trace;
}
private void pushBuilder(JetElement scopingElement, JetElement subroutine) {
JetControlFlowInstructionsGeneratorWorker worker = new JetControlFlowInstructionsGeneratorWorker(scopingElement, subroutine);
builders.push(worker);
@@ -49,7 +43,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
private JetControlFlowInstructionsGeneratorWorker popBuilder(@NotNull JetElement element) {
JetControlFlowInstructionsGeneratorWorker worker = builders.pop();
trace.recordControlFlowData(element, worker.getPseudocode());
if (!builders.isEmpty()) {
builder = builders.peek();
}
@@ -72,7 +65,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
}
@Override
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
super.exitSubroutine(subroutine);
JetControlFlowInstructionsGeneratorWorker worker = popBuilder(subroutine);
if (!builders.empty()) {
@@ -80,32 +73,29 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
LocalDeclarationInstruction instruction = new LocalDeclarationInstruction(subroutine, worker.getPseudocode());
builder.add(instruction);
}
return worker.getPseudocode();
}
private class JetControlFlowInstructionsGeneratorWorker implements JetControlFlowBuilder {
private final Pseudocode pseudocode;
private final PseudocodeImpl pseudocode;
private final Label error;
private final Label sink;
private final JetElement returnSubroutine;
private JetControlFlowInstructionsGeneratorWorker(@NotNull JetElement scopingElement, @NotNull JetElement returnSubroutine) {
this.pseudocode = new Pseudocode(scopingElement);
this.pseudocode = new PseudocodeImpl(scopingElement);
this.error = pseudocode.createLabel("error");
this.sink = pseudocode.createLabel("sink");
this.returnSubroutine = returnSubroutine;
}
public Pseudocode getPseudocode() {
public PseudocodeImpl getPseudocode() {
return pseudocode;
}
private void add(@NotNull Instruction instruction) {
pseudocode.addInstruction(instruction);
if (instruction instanceof JetElementInstruction) {
JetElementInstruction elementInstruction = (JetElementInstruction) instruction;
trace.recordRepresentativeInstruction(elementInstruction.getElement(), instruction);
}
}
@NotNull
@@ -127,7 +117,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
loopInfo.push(blockInfo);
elementToBlockInfo.put(expression, blockInfo);
allBlocks.push(blockInfo);
trace.recordLoopInfo(expression, blockInfo);
pseudocode.recordLoopInfo(expression, blockInfo);
return blockInfo;
}
@@ -202,7 +192,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
}
@Override
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
bindLabel(getExitPoint(subroutine));
pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>"));
bindLabel(error);
@@ -211,6 +201,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
pseudocode.addSinkInstruction(new SubroutineSinkInstruction(subroutine, "<SINK>"));
elementToBlockInfo.remove(subroutine);
allBlocks.pop();
return null;
}
@Override
@@ -1,54 +0,0 @@
/*
* 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.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.LoopInfo;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetExpression;
/**
* @author abreslav
*/
public interface JetPseudocodeTrace {
JetPseudocodeTrace EMPTY = new JetPseudocodeTrace() {
@Override
public void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode) {
}
@Override
public void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction) {
}
@Override
public void close() {
}
@Override
public void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
}
};
void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode);
void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction);
void close();
void recordLoopInfo(JetExpression expression, LoopInfo blockInfo);
}
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.ArrayList;
import java.util.Collection;
@@ -40,6 +41,12 @@ public class LocalDeclarationInstruction extends InstructionWithNext {
return body;
}
@NotNull
@Override
public JetDeclaration getElement() {
return (JetDeclaration) super.getElement();
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
@@ -16,343 +16,37 @@
package org.jetbrains.jet.lang.cfg.pseudocode;
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.cfg.Label;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author abreslav
*/
public class Pseudocode {
public class PseudocodeLabel implements Label {
private final String name;
private Integer targetInstructionIndex;
private PseudocodeLabel(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
public Integer getTargetInstructionIndex() {
return targetInstructionIndex;
}
public void setTargetInstructionIndex(int targetInstructionIndex) {
this.targetInstructionIndex = targetInstructionIndex;
}
@Nullable
private List<Instruction> resolve() {
assert targetInstructionIndex != null;
return mutableInstructionList.subList(getTargetInstructionIndex(), mutableInstructionList.size());
}
public Instruction resolveToInstruction() {
assert targetInstructionIndex != null;
return mutableInstructionList.get(targetInstructionIndex);
}
}
private final List<Instruction> mutableInstructionList = new ArrayList<Instruction>();
private final List<Instruction> instructions = new ArrayList<Instruction>();
private List<Instruction> deadInstructions;
private final List<PseudocodeLabel> labels = new ArrayList<PseudocodeLabel>();
private final List<PseudocodeLabel> allowedDeadLabels = new ArrayList<PseudocodeLabel>();
private final List<PseudocodeLabel> stopAllowDeadLabels = new ArrayList<PseudocodeLabel>();
private final JetElement correspondingElement;
private SubroutineExitInstruction exitInstruction;
private SubroutineSinkInstruction sinkInstruction;
private SubroutineExitInstruction errorInstruction;
private boolean postPrecessed = false;
public Pseudocode(JetElement correspondingElement) {
this.correspondingElement = correspondingElement;
}
public JetElement getCorrespondingElement() {
return correspondingElement;
}
public PseudocodeLabel createLabel(String name) {
PseudocodeLabel label = new PseudocodeLabel(name);
labels.add(label);
return label;
}
public void allowDead(Label label) {
allowedDeadLabels.add((PseudocodeLabel) label);
}
public void stopAllowDead(Label label) {
stopAllowDeadLabels.add((PseudocodeLabel) label);
}
* @author svtk
*/
public interface Pseudocode {
@NotNull
JetElement getCorrespondingElement();
@NotNull
public List<Instruction> getInstructions() {
return instructions;
}
@Deprecated //for tests only
@NotNull
public List<Instruction> getMutableInstructionList() {
return mutableInstructionList;
}
@NotNull
public List<Instruction> getDeadInstructions() {
if (deadInstructions != null) {
return deadInstructions;
}
deadInstructions = Lists.newArrayList();
Collection<Instruction> allowedDeadInstructions = collectAllowedDeadInstructions();
for (Instruction instruction : mutableInstructionList) {
if (((InstructionImpl)instruction).isDead()) {
if (!allowedDeadInstructions.contains(instruction)) {
deadInstructions.add(instruction);
}
}
}
return deadInstructions;
}
@Deprecated //for tests only
@NotNull
public List<PseudocodeLabel> getLabels() {
return labels;
}
public void addExitInstruction(SubroutineExitInstruction exitInstruction) {
addInstruction(exitInstruction);
assert this.exitInstruction == null;
this.exitInstruction = exitInstruction;
}
public void addSinkInstruction(SubroutineSinkInstruction sinkInstruction) {
addInstruction(sinkInstruction);
assert this.sinkInstruction == null;
this.sinkInstruction = sinkInstruction;
}
public void addErrorInstruction(SubroutineExitInstruction errorInstruction) {
addInstruction(errorInstruction);
assert this.errorInstruction == null;
this.errorInstruction = errorInstruction;
}
public void addInstruction(Instruction instruction) {
mutableInstructionList.add(instruction);
instruction.setOwner(this);
}
Set<LocalDeclarationInstruction> getLocalDeclarations();
@NotNull
public SubroutineExitInstruction getExitInstruction() {
return exitInstruction;
}
List<Instruction> getInstructions();
@NotNull
public SubroutineSinkInstruction getSinkInstruction() {
return sinkInstruction;
}
List<Instruction> getReversedInstructions();
@NotNull
public SubroutineEnterInstruction getEnterInstruction() {
return (SubroutineEnterInstruction) mutableInstructionList.get(0);
}
public void bindLabel(Label label) {
((PseudocodeLabel) label).setTargetInstructionIndex(mutableInstructionList.size());
}
public void postProcess() {
if (postPrecessed) return;
postPrecessed = true;
for (int i = 0, instructionsSize = mutableInstructionList.size(); i < instructionsSize; i++) {
processInstruction(mutableInstructionList.get(i), i);
}
getExitInstruction().setSink(getSinkInstruction());
Set<Instruction> reachableInstructions = collectReachableInstructions();
for (Instruction instruction : mutableInstructionList) {
if (reachableInstructions.contains(instruction)) {
instructions.add(instruction);
}
}
markDeadInstructions();
}
private void processInstruction(Instruction instruction, final int currentPosition) {
instruction.accept(new InstructionVisitor() {
@Override
public void visitInstructionWithNext(InstructionWithNext instruction) {
instruction.setNext(getNextPosition(currentPosition));
}
@Override
public void visitJump(AbstractJumpInstruction instruction) {
instruction.setResolvedTarget(getJumpTarget(instruction.getTargetLabel()));
}
@Override
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
instruction.setNext(getNextPosition(currentPosition));
List<Label> targetLabels = instruction.getTargetLabels();
for (Label targetLabel : targetLabels) {
instruction.setResolvedTarget(targetLabel, getJumpTarget(targetLabel));
}
}
@Override
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
Instruction nextInstruction = getNextPosition(currentPosition);
Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
if (instruction.onTrue()) {
instruction.setNextOnFalse(nextInstruction);
instruction.setNextOnTrue(jumpTarget);
}
else {
instruction.setNextOnFalse(jumpTarget);
instruction.setNextOnTrue(nextInstruction);
}
visitJump(instruction);
}
@Override
public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
instruction.getBody().postProcess();
instruction.setNext(getSinkInstruction());
}
@Override
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
// Nothing
}
@Override
public void visitSubroutineSink(SubroutineSinkInstruction instruction) {
// Nothing
}
@Override
public void visitInstruction(Instruction instruction) {
throw new UnsupportedOperationException(instruction.toString());
}
});
}
private Set<Instruction> collectReachableInstructions() {
Set<Instruction> visited = Sets.newHashSet();
traverseNextInstructions(getEnterInstruction(), visited);
if (!visited.contains(getExitInstruction())) {
visited.add(getExitInstruction());
}
if (!visited.contains(errorInstruction)) {
visited.add(errorInstruction);
}
if (!visited.contains(getSinkInstruction())) {
visited.add(getSinkInstruction());
}
return visited;
}
private void traverseNextInstructions(@NotNull Instruction instruction, @NotNull Set<Instruction> visited) {
if (visited.contains(instruction)) return;
visited.add(instruction);
for (Instruction nextInstruction : instruction.getNextInstructions()) {
if (nextInstruction == null) continue; //todo it might be null on incomplete code
traverseNextInstructions(nextInstruction, visited);
}
}
private void markDeadInstructions() {
Set<Instruction> instructionSet = Sets.newHashSet(instructions);
for (Instruction instruction : mutableInstructionList) {
if (!instructionSet.contains(instruction)) {
((InstructionImpl)instruction).die();
for (Instruction nextInstruction : instruction.getNextInstructions()) {
nextInstruction.getPreviousInstructions().remove(instruction);
}
}
}
}
List<Instruction> getDeadInstructions();
@NotNull
private Set<Instruction> prepareAllowedDeadInstructions() {
Set<Instruction> allowedDeadStartInstructions = Sets.newHashSet();
for (PseudocodeLabel allowedDeadLabel : allowedDeadLabels) {
Instruction allowedDeadInstruction = getJumpTarget(allowedDeadLabel);
if (((InstructionImpl)allowedDeadInstruction).isDead()) {
allowedDeadStartInstructions.add(allowedDeadInstruction);
}
}
return allowedDeadStartInstructions;
}
@NotNull
private Set<Instruction> prepareStopAllowedDeadInstructions() {
Set<Instruction> stopAllowedDeadInstructions = Sets.newHashSet();
for (PseudocodeLabel stopAllowedDeadLabel : stopAllowDeadLabels) {
Instruction stopAllowDeadInsruction = getJumpTarget(stopAllowedDeadLabel);
if (((InstructionImpl)stopAllowDeadInsruction).isDead()) {
stopAllowedDeadInstructions.add(stopAllowDeadInsruction);
}
}
return stopAllowedDeadInstructions;
}
SubroutineExitInstruction getExitInstruction();
@NotNull
private Collection<Instruction> collectAllowedDeadInstructions() {
Set<Instruction> allowedDeadStartInstructions = prepareAllowedDeadInstructions();
Set<Instruction> stopAllowDeadInstructions = prepareStopAllowedDeadInstructions();
Set<Instruction> allowedDeadInstructions = Sets.newHashSet();
for (Instruction allowedDeadStartInstruction : allowedDeadStartInstructions) {
collectAllowedDeadInstructions(allowedDeadStartInstruction, allowedDeadInstructions, stopAllowDeadInstructions);
}
return allowedDeadInstructions;
}
private void collectAllowedDeadInstructions(Instruction allowedDeadInstruction, Set<Instruction> instructionSet, Set<Instruction> stopAllowDeadInstructions) {
if (instructionSet.contains(allowedDeadInstruction) || stopAllowDeadInstructions.contains(allowedDeadInstruction)) return;
if (((InstructionImpl)allowedDeadInstruction).isDead()) {
instructionSet.add(allowedDeadInstruction);
for (Instruction instruction : allowedDeadInstruction.getNextInstructions()) {
collectAllowedDeadInstructions(instruction, instructionSet, stopAllowDeadInstructions);
}
}
}
SubroutineSinkInstruction getSinkInstruction();
@NotNull
private Instruction getJumpTarget(@NotNull Label targetLabel) {
return ((PseudocodeLabel)targetLabel).resolveToInstruction();
}
@NotNull
private Instruction getNextPosition(int currentPosition) {
int targetPosition = currentPosition + 1;
assert targetPosition < mutableInstructionList.size() : currentPosition;
return mutableInstructionList.get(targetPosition);
}
SubroutineEnterInstruction getEnterInstruction();
}
@@ -0,0 +1,423 @@
/*
* 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.lang.cfg.pseudocode;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.Label;
import org.jetbrains.jet.lang.cfg.LoopInfo;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetExpression;
import java.util.*;
/**
* @author abreslav
* @author svtk
*/
public class PseudocodeImpl implements Pseudocode {
public class PseudocodeLabel implements Label {
private final String name;
private Integer targetInstructionIndex;
private PseudocodeLabel(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
public Integer getTargetInstructionIndex() {
return targetInstructionIndex;
}
public void setTargetInstructionIndex(int targetInstructionIndex) {
this.targetInstructionIndex = targetInstructionIndex;
}
@Nullable
private List<Instruction> resolve() {
assert targetInstructionIndex != null;
return mutableInstructionList.subList(getTargetInstructionIndex(), mutableInstructionList.size());
}
public Instruction resolveToInstruction() {
assert targetInstructionIndex != null;
return mutableInstructionList.get(targetInstructionIndex);
}
}
private final List<Instruction> mutableInstructionList = new ArrayList<Instruction>();
private final List<Instruction> instructions = new ArrayList<Instruction>();
private List<Instruction> reversedInstructions = null;
private List<Instruction> deadInstructions;
private Set<LocalDeclarationInstruction> localDeclarations = null;
//todo getters
private final Map<JetElement, Instruction> representativeInstructions = new HashMap<JetElement, Instruction>();
private final Map<JetExpression, LoopInfo> loopInfo = Maps.newHashMap();
private final List<PseudocodeLabel> labels = new ArrayList<PseudocodeLabel>();
private final List<PseudocodeLabel> allowedDeadLabels = new ArrayList<PseudocodeLabel>();
private final List<PseudocodeLabel> stopAllowDeadLabels = new ArrayList<PseudocodeLabel>();
private final JetElement correspondingElement;
private SubroutineExitInstruction exitInstruction;
private SubroutineSinkInstruction sinkInstruction;
private SubroutineExitInstruction errorInstruction;
private boolean postPrecessed = false;
public PseudocodeImpl(JetElement correspondingElement) {
this.correspondingElement = correspondingElement;
}
@NotNull
@Override
public JetElement getCorrespondingElement() {
return correspondingElement;
}
@NotNull
@Override
public Set<LocalDeclarationInstruction> getLocalDeclarations() {
if (localDeclarations == null) {
localDeclarations = getLocalDeclarations(this);
}
return localDeclarations;
}
@NotNull
private static Set<LocalDeclarationInstruction> getLocalDeclarations(@NotNull Pseudocode pseudocode) {
Set<LocalDeclarationInstruction> localDeclarations = Sets.newLinkedHashSet();
for (Instruction instruction : pseudocode.getInstructions()) {
if (instruction instanceof LocalDeclarationInstruction) {
localDeclarations.add((LocalDeclarationInstruction) instruction);
localDeclarations.addAll(getLocalDeclarations(((LocalDeclarationInstruction)instruction).getBody()));
}
}
return localDeclarations;
}
/*package*/ PseudocodeLabel createLabel(String name) {
PseudocodeLabel label = new PseudocodeLabel(name);
labels.add(label);
return label;
}
/*package*/ void allowDead(Label label) {
allowedDeadLabels.add((PseudocodeLabel) label);
}
/*package*/ void stopAllowDead(Label label) {
stopAllowDeadLabels.add((PseudocodeLabel) label);
}
@Override
@NotNull
public List<Instruction> getInstructions() {
return instructions;
}
@NotNull
@Override
public List<Instruction> getReversedInstructions() {
if (reversedInstructions == null) {
LinkedHashSet<Instruction> traversedInstructions = Sets.newLinkedHashSet();
traverseInstructionsInReverseOrder(sinkInstruction, traversedInstructions);
reversedInstructions = Lists.newArrayList(traversedInstructions);
}
return reversedInstructions;
}
private static void traverseInstructionsInReverseOrder(@NotNull Instruction instruction,
@NotNull LinkedHashSet<Instruction> instructions) {
if (instructions.contains(instruction)) return;
instructions.add(instruction);
for (Instruction previousInstruction : instruction.getPreviousInstructions()) {
traverseInstructionsInReverseOrder(previousInstruction, instructions);
}
}
//for tests only
@NotNull
public List<Instruction> getAllInstructions() {
return mutableInstructionList;
}
@Override
@NotNull
public List<Instruction> getDeadInstructions() {
if (deadInstructions != null) {
return deadInstructions;
}
deadInstructions = Lists.newArrayList();
Collection<Instruction> allowedDeadInstructions = collectAllowedDeadInstructions();
for (Instruction instruction : mutableInstructionList) {
if (((InstructionImpl)instruction).isDead()) {
if (!allowedDeadInstructions.contains(instruction)) {
deadInstructions.add(instruction);
}
}
}
return deadInstructions;
}
//for tests only
@NotNull
public List<PseudocodeLabel> getLabels() {
return labels;
}
/*package*/ void addExitInstruction(SubroutineExitInstruction exitInstruction) {
addInstruction(exitInstruction);
assert this.exitInstruction == null;
this.exitInstruction = exitInstruction;
}
/*package*/ void addSinkInstruction(SubroutineSinkInstruction sinkInstruction) {
addInstruction(sinkInstruction);
assert this.sinkInstruction == null;
this.sinkInstruction = sinkInstruction;
}
/*package*/ void addErrorInstruction(SubroutineExitInstruction errorInstruction) {
addInstruction(errorInstruction);
assert this.errorInstruction == null;
this.errorInstruction = errorInstruction;
}
/*package*/ void addInstruction(Instruction instruction) {
mutableInstructionList.add(instruction);
instruction.setOwner(this);
if (instruction instanceof JetElementInstruction) {
JetElementInstruction elementInstruction = (JetElementInstruction) instruction;
representativeInstructions.put(elementInstruction.getElement(), instruction);
}
}
/*package*/ void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
loopInfo.put(expression, blockInfo);
}
@Override
@NotNull
public SubroutineExitInstruction getExitInstruction() {
return exitInstruction;
}
@Override
@NotNull
public SubroutineSinkInstruction getSinkInstruction() {
return sinkInstruction;
}
@Override
@NotNull
public SubroutineEnterInstruction getEnterInstruction() {
return (SubroutineEnterInstruction) mutableInstructionList.get(0);
}
/*package*/ void bindLabel(Label label) {
((PseudocodeLabel) label).setTargetInstructionIndex(mutableInstructionList.size());
}
public void postProcess() {
if (postPrecessed) return;
postPrecessed = true;
errorInstruction.setSink(getSinkInstruction());
exitInstruction.setSink(getSinkInstruction());
for (int i = 0, instructionsSize = mutableInstructionList.size(); i < instructionsSize; i++) {
processInstruction(mutableInstructionList.get(i), i);
}
Set<Instruction> reachableInstructions = collectReachableInstructions();
for (Instruction instruction : mutableInstructionList) {
if (reachableInstructions.contains(instruction)) {
instructions.add(instruction);
}
}
markDeadInstructions();
}
private void processInstruction(Instruction instruction, final int currentPosition) {
instruction.accept(new InstructionVisitor() {
@Override
public void visitInstructionWithNext(InstructionWithNext instruction) {
instruction.setNext(getNextPosition(currentPosition));
}
@Override
public void visitJump(AbstractJumpInstruction instruction) {
instruction.setResolvedTarget(getJumpTarget(instruction.getTargetLabel()));
}
@Override
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
instruction.setNext(getNextPosition(currentPosition));
List<Label> targetLabels = instruction.getTargetLabels();
for (Label targetLabel : targetLabels) {
instruction.setResolvedTarget(targetLabel, getJumpTarget(targetLabel));
}
}
@Override
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
Instruction nextInstruction = getNextPosition(currentPosition);
Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
if (instruction.onTrue()) {
instruction.setNextOnFalse(nextInstruction);
instruction.setNextOnTrue(jumpTarget);
}
else {
instruction.setNextOnFalse(jumpTarget);
instruction.setNextOnTrue(nextInstruction);
}
visitJump(instruction);
}
@Override
public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
((PseudocodeImpl)instruction.getBody()).postProcess();
instruction.setNext(getSinkInstruction());
}
@Override
public void visitSubroutineExit(SubroutineExitInstruction instruction) {
// Nothing
}
@Override
public void visitSubroutineSink(SubroutineSinkInstruction instruction) {
// Nothing
}
@Override
public void visitInstruction(Instruction instruction) {
throw new UnsupportedOperationException(instruction.toString());
}
});
}
private Set<Instruction> collectReachableInstructions() {
Set<Instruction> visited = Sets.newHashSet();
traverseNextInstructions(getEnterInstruction(), visited);
if (!visited.contains(getExitInstruction())) {
visited.add(getExitInstruction());
}
if (!visited.contains(errorInstruction)) {
visited.add(errorInstruction);
}
if (!visited.contains(getSinkInstruction())) {
visited.add(getSinkInstruction());
}
return visited;
}
private void traverseNextInstructions(@NotNull Instruction instruction, @NotNull Set<Instruction> visited) {
if (visited.contains(instruction)) return;
visited.add(instruction);
for (Instruction nextInstruction : instruction.getNextInstructions()) {
if (nextInstruction == null) continue; //todo it might be null on incomplete code
traverseNextInstructions(nextInstruction, visited);
}
}
private void markDeadInstructions() {
Set<Instruction> instructionSet = Sets.newHashSet(instructions);
for (Instruction instruction : mutableInstructionList) {
if (!instructionSet.contains(instruction)) {
((InstructionImpl)instruction).die();
for (Instruction nextInstruction : instruction.getNextInstructions()) {
nextInstruction.getPreviousInstructions().remove(instruction);
}
}
}
}
@NotNull
private Set<Instruction> prepareAllowedDeadInstructions() {
Set<Instruction> allowedDeadStartInstructions = Sets.newHashSet();
for (PseudocodeLabel allowedDeadLabel : allowedDeadLabels) {
Instruction allowedDeadInstruction = getJumpTarget(allowedDeadLabel);
if (((InstructionImpl)allowedDeadInstruction).isDead()) {
allowedDeadStartInstructions.add(allowedDeadInstruction);
}
}
return allowedDeadStartInstructions;
}
@NotNull
private Set<Instruction> prepareStopAllowedDeadInstructions() {
Set<Instruction> stopAllowedDeadInstructions = Sets.newHashSet();
for (PseudocodeLabel stopAllowedDeadLabel : stopAllowDeadLabels) {
Instruction stopAllowDeadInsruction = getJumpTarget(stopAllowedDeadLabel);
if (((InstructionImpl)stopAllowDeadInsruction).isDead()) {
stopAllowedDeadInstructions.add(stopAllowDeadInsruction);
}
}
return stopAllowedDeadInstructions;
}
@NotNull
private Collection<Instruction> collectAllowedDeadInstructions() {
Set<Instruction> allowedDeadStartInstructions = prepareAllowedDeadInstructions();
Set<Instruction> stopAllowDeadInstructions = prepareStopAllowedDeadInstructions();
Set<Instruction> allowedDeadInstructions = Sets.newHashSet();
for (Instruction allowedDeadStartInstruction : allowedDeadStartInstructions) {
collectAllowedDeadInstructions(allowedDeadStartInstruction, allowedDeadInstructions, stopAllowDeadInstructions);
}
return allowedDeadInstructions;
}
private void collectAllowedDeadInstructions(Instruction allowedDeadInstruction, Set<Instruction> instructionSet, Set<Instruction> stopAllowDeadInstructions) {
if (instructionSet.contains(allowedDeadInstruction) || stopAllowDeadInstructions.contains(allowedDeadInstruction)) return;
if (((InstructionImpl)allowedDeadInstruction).isDead()) {
instructionSet.add(allowedDeadInstruction);
for (Instruction instruction : allowedDeadInstruction.getNextInstructions()) {
collectAllowedDeadInstructions(instruction, instructionSet, stopAllowDeadInstructions);
}
}
}
@NotNull
private Instruction getJumpTarget(@NotNull Label targetLabel) {
return ((PseudocodeLabel)targetLabel).resolveToInstruction();
}
@NotNull
private Instruction getNextPosition(int currentPosition) {
int targetPosition = currentPosition + 1;
assert targetPosition < mutableInstructionList.size() : currentPosition;
return mutableInstructionList.get(targetPosition);
}
}
@@ -0,0 +1,86 @@
/*
* 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.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection;
/**
* @author svtk
*/
public class PseudocodeUtil {
public static Pseudocode generatePseudocode(@NotNull JetDeclaration declaration, @NotNull final BindingContext bindingContext) {
BindingTrace mockTrace = new BindingTrace() {
@Override
public BindingContext getBindingContext() {
return bindingContext;
}
@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
}
@Override
public <K> void record(WritableSlice<K, Boolean> slice, K key) {
}
@Override
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return bindingContext.get(slice, key);
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return bindingContext.getKeys(slice);
}
@Override
public void report(@NotNull Diagnostic diagnostic) {
}
};
return new JetControlFlowProcessor(mockTrace).generatePseudocode(declaration);
}
@Nullable
public static VariableDescriptor extractVariableDescriptorIfAny(@NotNull Instruction instruction, boolean onlyReference, @NotNull BindingContext bindingContext) {
JetElement element = null;
if (instruction instanceof ReadValueInstruction) {
element = ((ReadValueInstruction) instruction).getElement();
}
else if (instruction instanceof WriteValueInstruction) {
element = ((WriteValueInstruction) instruction).getlValue();
}
else if (instruction instanceof VariableDeclarationInstruction) {
element = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement();
}
return BindingContextUtils.extractVariableDescriptorIfAny(bindingContext, element, onlyReference);
}
}
@@ -46,10 +46,8 @@ public class SubroutineExitInstruction extends InstructionImpl {
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
if (sinkInstruction != null) {
return Collections.<Instruction>singleton(sinkInstruction);
}
return Collections.emptyList();
assert sinkInstruction != null;
return Collections.<Instruction>singleton(sinkInstruction);
}
@Override
@@ -48,7 +48,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
}
public final ClassDescriptorImpl initialize(boolean sealed,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull Collection<JetType> supertypes,
@NotNull JetScope memberDeclarations,
@NotNull Set<ConstructorDescriptor> constructors,
@@ -57,7 +57,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
}
public final ClassDescriptorImpl initialize(boolean sealed,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull Collection<JetType> supertypes,
@NotNull JetScope memberDeclarations,
@NotNull Set<ConstructorDescriptor> constructors,
@@ -77,12 +77,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
protected FunctionDescriptorImpl initialize(
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor expectedThisObject,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
@Nullable JetType unsubstitutedReturnType,
@Nullable Modality modality,
@NotNull Visibility visibility) {
this.typeParameters = typeParameters;
this.typeParameters = Lists.newArrayList(typeParameters);
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
this.unsubstitutedReturnType = unsubstitutedReturnType;
this.modality = modality;
@@ -126,7 +126,7 @@ public class FunctionDescriptorUtil {
assert JetStandardClasses.isFunctionType(functionType);
functionDescriptor.initialize(JetStandardClasses.getReceiverType(functionType),
expectedThisObject,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<TypeParameterDescriptorImpl>emptyList(),
JetStandardClasses.getValueParameters(functionDescriptor, functionType),
JetStandardClasses.getReturnTypeFromFunctionType(functionType),
modality,
@@ -112,17 +112,17 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
setType(outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
}
public void setType(@NotNull JetType outType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull ReceiverDescriptor expectedThisObject, @Nullable JetType receiverType) {
public void setType(@NotNull JetType outType, @NotNull List<? extends TypeParameterDescriptor> typeParameters, @NotNull ReceiverDescriptor expectedThisObject, @Nullable JetType receiverType) {
ReceiverDescriptor receiver = receiverType == null
? NO_RECEIVER
: new ExtensionReceiver(this, receiverType);
setType(outType, typeParameters, expectedThisObject, receiver);
}
public void setType(@NotNull JetType outType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull ReceiverDescriptor expectedThisObject, @NotNull ReceiverDescriptor receiver) {
public void setType(@NotNull JetType outType, @NotNull List<? extends TypeParameterDescriptor> typeParameters, @NotNull ReceiverDescriptor expectedThisObject, @NotNull ReceiverDescriptor receiver) {
setOutType(outType);
this.typeParameters = typeParameters;
this.typeParameters = Lists.newArrayList(typeParameters);
this.receiver = receiver;
this.expectedThisObject = expectedThisObject;
@@ -54,7 +54,7 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
public SimpleFunctionDescriptorImpl initialize(
@Nullable JetType receiverType,
@NotNull ReceiverDescriptor expectedThisObject,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
@Nullable JetType unsubstitutedReturnType,
@Nullable Modality modality,
@@ -16,251 +16,45 @@
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.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.jetbrains.jet.util.lazy.LazyValue;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.Variance;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author abreslav
*/
public class TypeParameterDescriptor extends DeclarationDescriptorImpl implements ClassifierDescriptor {
public static TypeParameterDescriptor createWithDefaultBound(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
TypeParameterDescriptor typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index);
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound());
typeParameterDescriptor.setInitialized();
return typeParameterDescriptor;
}
public interface TypeParameterDescriptor extends ClassifierDescriptor {
boolean isReified();
public static TypeParameterDescriptor createForFurtherModification(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
return new TypeParameterDescriptor(containingDeclaration, annotations, reified, variance, name, index);
}
// 0-based
private final int index;
private final Variance variance;
private final Set<JetType> upperBounds;
private JetType upperBoundsAsType;
private final TypeConstructor typeConstructor;
private JetType defaultType;
private final Set<JetType> classObjectUpperBounds = Sets.newLinkedHashSet();
private JetType classObjectBoundsAsType;
private final boolean reified;
private boolean initialized = false;
private TypeParameterDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
super(containingDeclaration, annotations, name);
this.index = index;
this.variance = variance;
this.upperBounds = Sets.newLinkedHashSet();
this.reified = reified;
// TODO: Should we actually pass the annotations on to the type constructor?
this.typeConstructor = new TypeConstructorImpl(
this,
annotations,
false,
name.getName(),
Collections.<TypeParameterDescriptor>emptyList(),
upperBounds);
}
private void checkInitialized() {
if (!initialized) {
throw new IllegalStateException("Type parameter descriptor in not initialized: " + nameForAssertions());
}
}
private void checkUninitialized() {
if (initialized) {
throw new IllegalStateException("Type parameter descriptor is already initialized: " + nameForAssertions());
}
}
private String nameForAssertions() {
DeclarationDescriptor owner = getContainingDeclaration();
return getName() + " declared in " + (owner == null ? "<no owner>" : owner.getName());
}
public void setInitialized() {
checkUninitialized();
initialized = true;
}
public boolean isReified() {
checkInitialized();
return reified;
}
public Variance getVariance() {
checkInitialized();
return variance;
}
public void addUpperBound(@NotNull JetType bound) {
checkUninitialized();
doAddUpperBound(bound);
}
private void doAddUpperBound(JetType bound) {
upperBounds.add(bound); // TODO : Duplicates?
}
public void addDefaultUpperBound() {
checkUninitialized();
if (upperBounds.isEmpty()) {
doAddUpperBound(JetStandardClasses.getDefaultBound());
}
}
Variance getVariance();
@NotNull
public Set<JetType> getUpperBounds() {
checkInitialized();
return upperBounds;
}
Set<JetType> getUpperBounds();
@NotNull
public JetType getUpperBoundsAsType() {
checkInitialized();
if (upperBoundsAsType == null) {
assert upperBounds != null : "Upper bound list is null in " + getName();
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
if (upperBoundsAsType == null) {
upperBoundsAsType = JetStandardClasses.getNothingType();
}
}
return upperBoundsAsType;
}
JetType getUpperBoundsAsType();
@NotNull
public Set<JetType> getLowerBounds() {
//checkInitialized();
return Collections.singleton(JetStandardClasses.getNothingType());
}
Set<JetType> getLowerBounds();
@NotNull
public JetType getLowerBoundsAsType() {
checkInitialized();
return JetStandardClasses.getNothingType();
}
JetType getLowerBoundsAsType();
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
//checkInitialized();
return typeConstructor;
}
@Override
public String toString() {
try {
return DescriptorRenderer.TEXT.render(this);
} catch (Exception e) {
return this.getClass().getName() + "@" + System.identityHashCode(this);
}
}
TypeConstructor getTypeConstructor();
@NotNull
@Override
@Deprecated // Use the static method TypeParameterDescriptor.substitute()
public TypeParameterDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException();
}
TypeParameterDescriptor substitute(TypeSubstitutor substitutor);
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
checkInitialized();
return visitor.visitTypeParameterDescriptor(this, data);
}
int getIndex();
@NotNull
@Override
public JetType getDefaultType() {
//checkInitialized();
if (defaultType == null) {
defaultType = new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
getTypeConstructor(),
TypeUtils.hasNullableLowerBound(this),
Collections.<TypeProjection>emptyList(),
new LazyScopeAdapter(new LazyValue<JetScope>() {
@Override
protected JetScope compute() {
return getUpperBoundsAsType().getMemberScope();
}
}));
}
return defaultType;
}
@Override
public JetType getClassObjectType() {
checkInitialized();
if (classObjectUpperBounds.isEmpty()) return null;
if (classObjectBoundsAsType == null) {
classObjectBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, classObjectUpperBounds);
if (classObjectBoundsAsType == null) {
classObjectBoundsAsType = JetStandardClasses.getNothingType();
}
}
return classObjectBoundsAsType;
}
@Override
public boolean isClassObjectAValue() {
return true;
}
public void addClassObjectBound(@NotNull JetType bound) {
checkUninitialized();
classObjectUpperBounds.add(bound); // TODO : Duplicates?
}
public int getIndex() {
checkInitialized();
return index;
}
@NotNull
public TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) {
TypeParameterDescriptor copy = new TypeParameterDescriptor(newOwner, Lists.newArrayList(getAnnotations()), reified, variance, getName(), index);
copy.upperBounds.addAll(this.upperBounds);
copy.initialized = this.initialized;
return copy;
}
TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner);
}
@@ -0,0 +1,275 @@
/*
* 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.lang.descriptors;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.jetbrains.jet.util.lazy.LazyValue;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author abreslav
*/
public class TypeParameterDescriptorImpl extends DeclarationDescriptorImpl implements TypeParameterDescriptor {
public static TypeParameterDescriptor createWithDefaultBound(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
TypeParameterDescriptorImpl typeParameterDescriptor = createForFurtherModification(containingDeclaration, annotations, reified, variance, name, index);
typeParameterDescriptor.addUpperBound(JetStandardClasses.getDefaultBound());
typeParameterDescriptor.setInitialized();
return typeParameterDescriptor;
}
public static TypeParameterDescriptorImpl createForFurtherModification(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
return new TypeParameterDescriptorImpl(containingDeclaration, annotations, reified, variance, name, index);
}
// 0-based
private final int index;
private final Variance variance;
private final Set<JetType> upperBounds;
private JetType upperBoundsAsType;
private final TypeConstructor typeConstructor;
private JetType defaultType;
private final Set<JetType> classObjectUpperBounds = Sets.newLinkedHashSet();
private JetType classObjectBoundsAsType;
private final boolean reified;
private boolean initialized = false;
private TypeParameterDescriptorImpl(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
boolean reified,
@NotNull Variance variance,
@NotNull Name name,
int index) {
super(containingDeclaration, annotations, name);
this.index = index;
this.variance = variance;
this.upperBounds = Sets.newLinkedHashSet();
this.reified = reified;
// TODO: Should we actually pass the annotations on to the type constructor?
this.typeConstructor = new TypeConstructorImpl(
this,
annotations,
false,
name.getName(),
Collections.<TypeParameterDescriptor>emptyList(),
upperBounds);
}
private void checkInitialized() {
if (!initialized) {
throw new IllegalStateException("Type parameter descriptor in not initialized: " + nameForAssertions());
}
}
private void checkUninitialized() {
if (initialized) {
throw new IllegalStateException("Type parameter descriptor is already initialized: " + nameForAssertions());
}
}
private String nameForAssertions() {
DeclarationDescriptor owner = getContainingDeclaration();
return getName() + " declared in " + (owner == null ? "<no owner>" : owner.getName());
}
public void setInitialized() {
checkUninitialized();
initialized = true;
}
@Override
public boolean isReified() {
checkInitialized();
return reified;
}
@Override
public Variance getVariance() {
checkInitialized();
return variance;
}
public void addUpperBound(@NotNull JetType bound) {
checkUninitialized();
doAddUpperBound(bound);
}
private void doAddUpperBound(JetType bound) {
upperBounds.add(bound); // TODO : Duplicates?
}
public void addDefaultUpperBound() {
checkUninitialized();
if (upperBounds.isEmpty()) {
doAddUpperBound(JetStandardClasses.getDefaultBound());
}
}
@Override
@NotNull
public Set<JetType> getUpperBounds() {
checkInitialized();
return upperBounds;
}
@Override
@NotNull
public JetType getUpperBoundsAsType() {
checkInitialized();
if (upperBoundsAsType == null) {
assert upperBounds != null : "Upper bound list is null in " + getName();
assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
if (upperBoundsAsType == null) {
upperBoundsAsType = JetStandardClasses.getNothingType();
}
}
return upperBoundsAsType;
}
@Override
@NotNull
public Set<JetType> getLowerBounds() {
//checkInitialized();
return Collections.singleton(JetStandardClasses.getNothingType());
}
@Override
@NotNull
public JetType getLowerBoundsAsType() {
checkInitialized();
return JetStandardClasses.getNothingType();
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
//checkInitialized();
return typeConstructor;
}
@Override
public String toString() {
try {
return DescriptorRenderer.TEXT.render(this);
} catch (Exception e) {
return this.getClass().getName() + "@" + System.identityHashCode(this);
}
}
@NotNull
@Override
@Deprecated // Use the static method TypeParameterDescriptor.substitute()
public TypeParameterDescriptor substitute(TypeSubstitutor substitutor) {
throw new UnsupportedOperationException();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
checkInitialized();
return visitor.visitTypeParameterDescriptor(this, data);
}
@NotNull
@Override
public JetType getDefaultType() {
//checkInitialized();
if (defaultType == null) {
defaultType = new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
getTypeConstructor(),
TypeUtils.hasNullableLowerBound(this),
Collections.<TypeProjection>emptyList(),
new LazyScopeAdapter(new LazyValue<JetScope>() {
@Override
protected JetScope compute() {
return getUpperBoundsAsType().getMemberScope();
}
}));
}
return defaultType;
}
@Override
public JetType getClassObjectType() {
checkInitialized();
if (classObjectUpperBounds.isEmpty()) return null;
if (classObjectBoundsAsType == null) {
classObjectBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, classObjectUpperBounds);
if (classObjectBoundsAsType == null) {
classObjectBoundsAsType = JetStandardClasses.getNothingType();
}
}
return classObjectBoundsAsType;
}
@Override
public boolean isClassObjectAValue() {
return true;
}
public void addClassObjectBound(@NotNull JetType bound) {
checkUninitialized();
classObjectUpperBounds.add(bound); // TODO : Duplicates?
}
@Override
public int getIndex() {
checkInitialized();
return index;
}
@Override
@NotNull
public TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) {
TypeParameterDescriptorImpl
copy = new TypeParameterDescriptorImpl(newOwner, Lists.newArrayList(getAnnotations()), reified, variance, getName(), index);
copy.upperBounds.addAll(this.upperBounds);
copy.initialized = this.initialized;
return copy;
}
}
@@ -16,22 +16,15 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetFile;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
@@ -37,7 +36,6 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
public class ControlFlowAnalyzer {
private TopDownAnalysisParameters topDownAnalysisParameters;
private BindingTrace trace;
private JetControlFlowDataTraceFactory flowDataTraceFactory;
@Inject
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
@@ -49,11 +47,6 @@ public class ControlFlowAnalyzer {
this.trace = trace;
}
@Inject
public void setFlowDataTraceFactory(JetControlFlowDataTraceFactory flowDataTraceFactory) {
this.flowDataTraceFactory = flowDataTraceFactory;
}
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
for (JetClass aClass : bodiesResolveContext.getClasses().keySet()) {
if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue;
@@ -86,8 +79,8 @@ public class ControlFlowAnalyzer {
private void checkClassOrObject(JetClassOrObject klass) {
// A pseudocode of class initialization corresponds to a class
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, (JetExpression) klass, flowDataTraceFactory, trace);
flowInformationProvider.markUninitializedVariables((JetElement) klass, topDownAnalysisParameters.isDeclaredLocally());
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, trace);
flowInformationProvider.markUninitializedVariables(topDownAnalysisParameters.isDeclaredLocally());
}
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) {
@@ -105,16 +98,16 @@ public class ControlFlowAnalyzer {
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression == null) return;
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) function, bodyExpression, flowDataTraceFactory, trace);
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) function, trace);
flowInformationProvider.checkDefiniteReturn(function, expectedReturnType);
flowInformationProvider.checkDefiniteReturn(expectedReturnType);
// Property accessor is checked through initialization of a class check (at 'checkClassOrObject')
boolean isPropertyAccessor = function instanceof JetPropertyAccessor;
flowInformationProvider.markUninitializedVariables(function.asElement(), topDownAnalysisParameters.isDeclaredLocally() || isPropertyAccessor);
flowInformationProvider.markUninitializedVariables(topDownAnalysisParameters.isDeclaredLocally() || isPropertyAccessor);
flowInformationProvider.markUnusedVariables(function.asElement());
flowInformationProvider.markUnusedVariables();
flowInformationProvider.markUnusedLiteralsInBlock(function.asElement());
flowInformationProvider.markUnusedLiteralsInBlock();
}
}
@@ -79,7 +79,7 @@ public class DescriptorResolver {
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
int index = 0;
for (JetTypeParameter typeParameter : classElement.getTypeParameters()) {
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
descriptor,
annotationResolver.createAnnotationStubs(typeParameter.getModifierList(), trace),
!typeParameter.hasModifier(JetTokens.ERASED_KEYWORD),
@@ -175,7 +175,7 @@ public class DescriptorResolver {
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function descriptor header scope");
innerScope.addLabeledDeclaration(functionDescriptor);
List<TypeParameterDescriptor> 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);
@@ -307,8 +307,8 @@ public class DescriptorResolver {
}
}
public List<TypeParameterDescriptor> resolveTypeParameters(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, List<JetTypeParameter> typeParameters, BindingTrace trace) {
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>();
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);
result.add(resolveTypeParameter(containingDescriptor, extensibleScope, typeParameter, i, trace));
@@ -316,12 +316,12 @@ public class DescriptorResolver {
return result;
}
private TypeParameterDescriptor resolveTypeParameter(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, JetTypeParameter typeParameter, int index, BindingTrace trace) {
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);
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
containingDescriptor,
annotationResolver.createAnnotationStubs(typeParameter.getModifierList(), trace),
!typeParameter.hasModifier(JetTokens.ERASED_KEYWORD),
@@ -346,14 +346,15 @@ public class DescriptorResolver {
isClassObjectConstraint = classObjectConstraint;
}
}
public void resolveGenericBounds(@NotNull JetTypeParameterListOwner declaration, JetScope scope, List<TypeParameterDescriptor> 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();
Map<Name, TypeParameterDescriptor> parameterByName = Maps.newHashMap();
Map<Name, TypeParameterDescriptorImpl> parameterByName = Maps.newHashMap();
for (int i = 0; i < typeParameters.size(); i++) {
JetTypeParameter jetTypeParameter = typeParameters.get(i);
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
TypeParameterDescriptorImpl typeParameterDescriptor = parameters.get(i);
parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
@@ -373,7 +374,7 @@ public class DescriptorResolver {
if (referencedName == null) {
continue;
}
TypeParameterDescriptor typeParameterDescriptor = parameterByName.get(referencedName);
TypeParameterDescriptorImpl typeParameterDescriptor = parameterByName.get(referencedName);
JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
JetType bound = null;
if (boundTypeReference != null) {
@@ -405,7 +406,7 @@ public class DescriptorResolver {
}
}
for (TypeParameterDescriptor parameter : parameters) {
for (TypeParameterDescriptorImpl parameter : parameters) {
parameter.addDefaultUpperBound();
parameter.setInitialized();
@@ -551,7 +552,7 @@ public class DescriptorResolver {
return variableDescriptor;
}
public JetScope getPropertyDeclarationInnerScope(@NotNull JetScope outerScope, @NotNull List<TypeParameterDescriptor> typeParameters,
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)).setDebugName("Property declaration inner scope");
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
@@ -583,7 +584,7 @@ public class DescriptorResolver {
CallableMemberDescriptor.Kind.DECLARATION
);
List<TypeParameterDescriptor> typeParameterDescriptors;
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
JetScope scopeWithTypeParameters;
JetType receiverType = null;
@@ -275,7 +275,7 @@ public class DescriptorUtils {
ClassDescriptor clazz = (ClassDescriptor) classifier;
return clazz.getKind() == ClassKind.OBJECT || clazz.getKind() == ClassKind.ENUM_ENTRY;
}
else if (classifier instanceof TypeParameterDescriptor) {
else if (classifier instanceof TypeParameterDescriptorImpl) {
return false;
}
else {
@@ -212,7 +212,7 @@ public class OverridingUtil {
if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
return type;
}
else if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
else if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptorImpl) {
return ((TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor()).getUpperBoundsAsType();
}
else {
@@ -23,7 +23,6 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -188,7 +187,7 @@ public class TopDownAnalyzer {
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(Predicates.<PsiFile>alwaysFalse(), true, false);
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
project, topDownAnalysisParameters, new ObservableBindingTrace(trace),
JetStandardClasses.FAKE_STANDARD_CLASSES_MODULE, null, ModuleConfiguration.EMPTY);
JetStandardClasses.FAKE_STANDARD_CLASSES_MODULE, ModuleConfiguration.EMPTY);
injector.getTopDownAnalyzer().doProcessStandardLibraryNamespace(outerScope, standardLibraryNamespace, files);
}
@@ -220,7 +219,7 @@ public class TopDownAnalyzer {
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
project, topDownAnalysisParameters, new ObservableBindingTrace(trace), moduleDescriptor,
JetControlFlowDataTraceFactory.EMPTY, ModuleConfiguration.EMPTY);
ModuleConfiguration.EMPTY);
injector.getTopDownAnalyzer().doProcess(outerScope, new NamespaceLikeBuilder() {
@@ -395,7 +395,7 @@ public class TypeHierarchyResolver {
JetClass jetClass = entry.getKey();
MutableClassDescriptor descriptor = entry.getValue();
descriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(),
descriptor.getTypeConstructor().getParameters(), trace);
(List) descriptor.getTypeConstructor().getParameters(), trace);
descriptorResolver.resolveSupertypes(jetClass, descriptor, trace);
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
@@ -528,7 +528,7 @@ public class TypeHierarchyResolver {
if (projections.size() > 1) {
TypeConstructor typeConstructor = entry.getKey();
DeclarationDescriptor declarationDescriptor = typeConstructor.getDeclarationDescriptor();
assert declarationDescriptor instanceof TypeParameterDescriptor : declarationDescriptor;
assert declarationDescriptor instanceof TypeParameterDescriptorImpl : declarationDescriptor;
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor;
// Immediate arguments of supertypes cannot be projected
@@ -95,7 +95,7 @@ public class TypeResolver {
return;
}
if (classifierDescriptor instanceof TypeParameterDescriptor) {
if (classifierDescriptor instanceof TypeParameterDescriptorImpl) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, typeParameterDescriptor);
@@ -21,6 +21,7 @@ import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
@@ -88,7 +89,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
@NotNull
private TypeValue getTypeValueFor(@NotNull JetType type) {
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof TypeParameterDescriptor) {
if (declarationDescriptor instanceof TypeParameterDescriptorImpl) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor;
// Checking that this is not a T?, but exactly T
if (typeParameterDescriptor.getDefaultType().isNullable() == type.isNullable()) {
@@ -488,7 +489,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
@Override
public TypeProjection get(TypeConstructor key) {
DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor();
if (declarationDescriptor instanceof TypeParameterDescriptor) {
if (declarationDescriptor instanceof TypeParameterDescriptorImpl) {
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
if (!unknownTypes.containsKey(descriptor)) return null;
@@ -14,23 +14,22 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg.pseudocode;
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.name.FqName;
/**
* @author abreslav
* @author Stepan Koltsov
*/
public interface JetControlFlowDataTraceFactory {
JetControlFlowDataTraceFactory EMPTY = new JetControlFlowDataTraceFactory() {
@NotNull
@Override
public JetPseudocodeTrace createTrace(JetElement element) {
return JetPseudocodeTrace.EMPTY;
}
};
public interface DependencyClassByQualifiedNameResolver {
@Nullable
ClassDescriptor resolveClass(@NotNull FqName qualifiedName);
@Nullable
NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName);
@NotNull
JetPseudocodeTrace createTrace(JetElement element);
}
@@ -0,0 +1,37 @@
/*
* 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.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.name.FqName;
/**
* @author Stepan Koltsov
*/
public class DependencyClassByQualifiedNameResolverDummyImpl implements DependencyClassByQualifiedNameResolver {
@Override
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName) {
return null;
}
@Override
public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) {
return null;
}
}
@@ -20,6 +20,7 @@ import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
import java.util.List;
import java.util.Map;
@@ -58,7 +59,7 @@ public class DescriptorSubstitutor {
});
for (TypeParameterDescriptor descriptor : typeParameters) {
TypeParameterDescriptor substituted = TypeParameterDescriptor.createForFurtherModification(
TypeParameterDescriptorImpl substituted = TypeParameterDescriptorImpl.createForFurtherModification(
newContainingDeclaration,
descriptor.getAnnotations(),
descriptor.isReified(),
@@ -170,7 +170,7 @@ public class ErrorUtils {
function.initialize(
null,
ReceiverDescriptor.NO_RECEIVER,
Collections.<TypeParameterDescriptor>emptyList(), // TODO
Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
Collections.<ValueParameterDescriptor>emptyList(), // TODO
createErrorType("<ERROR FUNCTION RETURN TYPE>"),
Modality.OPEN,
@@ -223,7 +223,7 @@ public class ErrorUtils {
}
private static JetType createErrorTypeWithCustomDebugName(JetScope memberScope, String debugName) {
return new ErrorTypeImpl(new TypeConstructorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, debugName, Collections.<TypeParameterDescriptor>emptyList(), Collections.singleton(JetStandardClasses.getAnyType())), memberScope);
return new ErrorTypeImpl(new TypeConstructorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, debugName, Collections.<TypeParameterDescriptorImpl>emptyList(), Collections.singleton(JetStandardClasses.getAnyType())), memberScope);
}
public static JetType createWrongVarianceErrorType(TypeProjection value) {
@@ -21,6 +21,7 @@ import com.google.common.collect.Multimap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.util.CommonSuppliers;
@@ -95,6 +96,9 @@ public class SubstitutionUtils {
}
private static void fillInSubstitutionContext(List<TypeParameterDescriptor> parameters, List<TypeProjection> contextArguments, Map<TypeConstructor, TypeProjection> parameterValues) {
if (parameters.size() != contextArguments.size()) {
throw new IllegalArgumentException("type parameter count != context arguments");
}
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
TypeParameterDescriptor parameter = parameters.get(i);
TypeProjection value = contextArguments.get(i);
@@ -108,7 +112,7 @@ public class SubstitutionUtils {
}
public static boolean hasUnsubstitutedTypeParameters(JetType type) {
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptorImpl) {
return true;
}
@@ -45,7 +45,7 @@ public class TypeConstructorImpl extends AnnotatedImpl implements TypeConstructo
@NotNull List<AnnotationDescriptor> annotations,
boolean sealed,
@NotNull String debugName,
@NotNull List<TypeParameterDescriptor> parameters,
@NotNull List<? extends TypeParameterDescriptor> parameters,
@NotNull Collection<JetType> supertypes) {
super(annotations);
this.classifierDescriptor = classifierDescriptor;
@@ -22,10 +22,7 @@ import com.google.common.collect.Sets;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
@@ -222,7 +219,7 @@ public class TypeUtils {
private static void processAllTypeParameters(JetType type, Variance howThiTypeIsUsed, Processor<TypeParameterUsage> result) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) {
if (descriptor instanceof TypeParameterDescriptorImpl) {
result.process(new TypeParameterUsage((TypeParameterDescriptor)descriptor, howThiTypeIsUsed));
}
for (TypeProjection projection : type.getArguments()) {
@@ -149,7 +149,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
}
functionDescriptor.initialize(effectiveReceiverType,
NO_RECEIVER,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<TypeParameterDescriptorImpl>emptyList(),
valueParameterDescriptors,
/*unsubstitutedReturnType = */ null,
Modality.FINAL,
@@ -157,13 +157,13 @@ public class JetStandardClasses {
Name.identifier("Tuple" + i));
WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, RedeclarationHandler.THROW_EXCEPTION);
for (int j = 0; j < i; j++) {
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createWithDefaultBound(
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createWithDefaultBound(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
true, Variance.OUT_VARIANCE, Name.identifier("T" + (j + 1)), j);
parameters.add(typeParameterDescriptor);
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC, false, false, Name.identifier("_" + (j + 1)), CallableMemberDescriptor.Kind.DECLARATION);
propertyDescriptor.setType(typeParameterDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(), classDescriptor.getImplicitReceiver(), ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.setType(typeParameterDescriptor.getDefaultType(), Collections.<TypeParameterDescriptorImpl>emptyList(), classDescriptor.getImplicitReceiver(), ReceiverDescriptor.NO_RECEIVER);
PropertyGetterDescriptor getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC, false, true, CallableMemberDescriptor.Kind.DECLARATION);
getterDescriptor.initialize(typeParameterDescriptor.getDefaultType());
propertyDescriptor.initialize(getterDescriptor, null);
@@ -215,7 +215,7 @@ public class JetStandardClasses {
SimpleFunctionDescriptorImpl invokeWithReceiver = new SimpleFunctionDescriptorImpl(receiverFunction, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("invoke"), CallableMemberDescriptor.Kind.DECLARATION);
WritableScope scopeForInvokeWithReceiver = createScopeForInvokeFunction(receiverFunction, invokeWithReceiver);
List<TypeParameterDescriptor> parameters = createTypeParameters(i, receiverFunction);
parameters.add(0, TypeParameterDescriptor.createWithDefaultBound(
parameters.add(0, TypeParameterDescriptorImpl.createWithDefaultBound(
receiverFunction,
Collections.<AnnotationDescriptor>emptyList(),
true, Variance.IN_VARIANCE, Name.identifier("T"), 0));
@@ -238,12 +238,12 @@ public class JetStandardClasses {
private static List<TypeParameterDescriptor> createTypeParameters(int parameterCount, ClassDescriptorImpl function) {
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>();
for (int j = 1; j <= parameterCount; j++) {
parameters.add(TypeParameterDescriptor.createWithDefaultBound(
parameters.add(TypeParameterDescriptorImpl.createWithDefaultBound(
function,
Collections.<AnnotationDescriptor>emptyList(),
true, Variance.IN_VARIANCE, Name.identifier("P" + j), j));
}
parameters.add(TypeParameterDescriptor.createWithDefaultBound(
parameters.add(TypeParameterDescriptorImpl.createWithDefaultBound(
function,
Collections.<AnnotationDescriptor>emptyList(),
true, Variance.OUT_VARIANCE, Name.identifier("R"), parameterCount + 1));
@@ -146,7 +146,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
Object typeNameObject;
if (cd == null || cd instanceof TypeParameterDescriptor) {
if (cd == null || cd instanceof TypeParameterDescriptorImpl) {
typeNameObject = type.getConstructor();
}
else {
@@ -1,16 +1,3 @@
== get_j ==
get() = 20
---------------------
l0:
<START> NEXT:[r(20)] PREV:[]
r(20) NEXT:[<END>] PREV:[<START>]
l1:
<END> NEXT:[<SINK>] PREV:[r(20)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== AnonymousInitializers ==
class AnonymousInitializers() {
val k = 34
@@ -46,16 +33,29 @@ l2:
l1:
<END> NEXT:[<SINK>] PREV:[w($i)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[d(get() = 20), <END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d(get() = 20)]
l3:
<START> NEXT:[r(20)] PREV:[]
r(20) NEXT:[<END>] PREV:[<START>]
l4:
<END> NEXT:[<SINK>] PREV:[r(20)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== get_j ==
get() = 20
---------------------
l3:
<START> NEXT:[r(20)] PREV:[]
r(20) NEXT:[<END>] PREV:[<START>]
l4:
<END> NEXT:[<SINK>] PREV:[r(20)]
error:
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -35,7 +35,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[w(a[10])]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -9,9 +9,9 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[v(var x : Int;)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== assignments ==
fun assignments() : Unit {
@@ -72,7 +72,7 @@ l5:
l1:
<END> NEXT:[<SINK>] PREV:[w(t.x)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
+23 -23
View File
@@ -1,16 +1,3 @@
== anonymous_0 ==
{1}
---------------------
l3:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>]
l4:
<END> NEXT:[<SINK>] PREV:[r(1)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== f ==
fun f(a : Boolean) : Unit {
1
@@ -78,18 +65,31 @@ l6:
l1:
<END> NEXT:[<SINK>] PREV:[r(a || false)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[d({1}), <END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d({1})]
l3:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>]
l4:
<END> NEXT:[<SINK>] PREV:[r(1)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== anonymous_0 ==
{1}
---------------------
l3:
<START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>]
l4:
<END> NEXT:[<SINK>] PREV:[r(1)]
error:
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== foo ==
fun foo(a : Boolean, b : Int) : Unit {}
@@ -104,9 +104,9 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== genfun ==
fun genfun<T>() : Unit {}
@@ -117,9 +117,9 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== flfun ==
fun flfun(f : () -> Any) : Unit {}
@@ -132,7 +132,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -0,0 +1,20 @@
== test ==
fun test() {
throw Exception()
test()
}
---------------------
l0:
<START> NEXT:[r(Exception)] PREV:[]
r(Exception) NEXT:[r(Exception())] PREV:[<START>]
r(Exception()) NEXT:[jmp(error)] PREV:[r(Exception)]
jmp(error) NEXT:[<ERROR>] PREV:[r(Exception())]
- r(test) NEXT:[r(test())] PREV:[]
- r(test()) NEXT:[<END>] PREV:[]
l1:
<END> NEXT:[<SINK>] PREV:[]
error:
<ERROR> NEXT:[<SINK>] PREV:[jmp(error)]
sink:
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
+4
View File
@@ -0,0 +1,4 @@
fun test() {
throw Exception()
test()
}
@@ -7,7 +7,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -15,7 +15,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[]
error:
<ERROR> NEXT:[] PREV:[jmp(error)]
<ERROR> NEXT:[<SINK>] PREV:[jmp(error)]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
+101 -101
View File
@@ -21,9 +21,9 @@ l1:
l3:
<END> NEXT:[<SINK>] PREV:[r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t2 ==
fun t2() {
@@ -65,36 +65,9 @@ l1:
l5:
<END> NEXT:[<SINK>] PREV:[ret l1, r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== anonymous_0 ==
{ () =>
if (2 > 3) {
return@
}
}
---------------------
l3:
<START> NEXT:[r(())] PREV:[]
r(()) NEXT:[r(2)] PREV:[<START>]
r(2) NEXT:[r(3)] PREV:[r(())]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
ret l4 NEXT:[<END>] PREV:[jf(l5)]
- jmp(l6) NEXT:[<END>] PREV:[]
l5:
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4:
l6:
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t3 ==
fun t3() {
@@ -141,9 +114,9 @@ l1:
l8:
<END> NEXT:[<SINK>] PREV:[r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[d({ () => if (2 > 3) { retur..), <END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d({ () => if (2 > 3) { retur..)]
l3:
<START> NEXT:[r(())] PREV:[]
r(()) NEXT:[r(2)] PREV:[<START>]
@@ -160,54 +133,36 @@ l4:
l6:
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== anonymous_1 ==
== anonymous_0 ==
{ () =>
try {
1
if (2 > 3) {
return@
}
} finally {
2
if (2 > 3) {
return@
}
}
}
---------------------
l3:
<START> NEXT:[r(())] PREV:[]
r(()) NEXT:[r(try { 1 if (2 > 3) { retur..)] PREV:[<START>]
r(try {
1
if (2 > 3) {
return@
}
} finally {
2
}) NEXT:[r(1)] PREV:[r(())]
r(1) NEXT:[r(2)] PREV:[r(try { 1 if (2 > 3) { retur..)]
r(2) NEXT:[r(3)] PREV:[r(1)]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l4] PREV:[jf(l5)]
ret l4 NEXT:[<END>] PREV:[r(2)]
- jmp(l6) NEXT:[r(2)] PREV:[]
<START> NEXT:[r(())] PREV:[]
r(()) NEXT:[r(2)] PREV:[<START>]
r(2) NEXT:[r(3)] PREV:[r(())]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
ret l4 NEXT:[<END>] PREV:[jf(l5)]
- jmp(l6) NEXT:[<END>] PREV:[]
l5:
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
l6:
l7:
r(2) NEXT:[<END>] PREV:[read (Unit)]
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4:
l8:
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
l6:
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t4 ==
fun t4() {
@@ -250,9 +205,9 @@ l2:
l1:
<END> NEXT:[<SINK>] PREV:[r({ () => try { 1 if (2 > 3)..)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[d({ () => try { 1 if (2 > 3)..), <END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d({ () => try { 1 if (2 > 3)..)]
l3:
<START> NEXT:[r(())] PREV:[]
r(()) NEXT:[r(try { 1 if (2 > 3) { retur..)] PREV:[<START>]
@@ -282,9 +237,54 @@ l4:
l8:
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== anonymous_1 ==
{ () =>
try {
1
if (2 > 3) {
return@
}
} finally {
2
}
}
---------------------
l3:
<START> NEXT:[r(())] PREV:[]
r(()) NEXT:[r(try { 1 if (2 > 3) { retur..)] PREV:[<START>]
r(try {
1
if (2 > 3) {
return@
}
} finally {
2
}) NEXT:[r(1)] PREV:[r(())]
r(1) NEXT:[r(2)] PREV:[r(try { 1 if (2 > 3) { retur..)]
r(2) NEXT:[r(3)] PREV:[r(1)]
r(3) NEXT:[r(>)] PREV:[r(2)]
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l4] PREV:[jf(l5)]
ret l4 NEXT:[<END>] PREV:[r(2)]
- jmp(l6) NEXT:[r(2)] PREV:[]
l5:
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
l6:
l7:
r(2) NEXT:[<END>] PREV:[read (Unit)]
l4:
l8:
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
error:
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t5 ==
fun t5() {
@@ -346,9 +346,9 @@ l3:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t6 ==
fun t6() {
@@ -410,9 +410,9 @@ l1:
l9:
<END> NEXT:[<SINK>] PREV:[r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t7 ==
fun t7() {
@@ -471,9 +471,9 @@ l1:
l9:
<END> NEXT:[<SINK>] PREV:[r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t8 ==
fun t8(a : Int) {
@@ -542,9 +542,9 @@ l2:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t9 ==
fun t9(a : Int) {
@@ -613,9 +613,9 @@ l1:
l9:
<END> NEXT:[<SINK>] PREV:[r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t10 ==
fun t10(a : Int) {
@@ -681,9 +681,9 @@ l1:
l9:
<END> NEXT:[<SINK>] PREV:[r(2)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t11 ==
fun t11() {
@@ -714,9 +714,9 @@ l1:
l3:
<END> NEXT:[<SINK>] PREV:[ret(*) l1]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t12 ==
fun t12() : Int {
@@ -749,9 +749,9 @@ l1:
l3:
<END> NEXT:[<SINK>] PREV:[ret(*) l1]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t13 ==
fun t13() : Int {
@@ -802,9 +802,9 @@ l1:
l6:
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(doSmth(3))]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t14 ==
fun t14() : Int {
@@ -843,9 +843,9 @@ l4:
l6:
<END> NEXT:[<SINK>] PREV:[ret(*) l1, jmp(l4)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t15 ==
fun t15() : Int {
@@ -898,9 +898,9 @@ l1:
l6:
<END> NEXT:[<SINK>] PREV:[ret(*) l1, ret(*) l1]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t16 ==
fun t16() : Int {
@@ -951,9 +951,9 @@ l1:
l6:
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(doSmth(3))]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== doSmth ==
fun doSmth(i: Int) {
@@ -967,7 +967,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
+4 -4
View File
@@ -29,9 +29,9 @@ l2:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== doSmth ==
fun doSmth(i: Int) {}
@@ -44,7 +44,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
+6 -6
View File
@@ -48,9 +48,9 @@ l5:
l1:
<END> NEXT:[<SINK>] PREV:[r(doSmth(r))]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== t2 ==
fun t2(b: Boolean) {
@@ -92,9 +92,9 @@ l1:
l5:
<END> NEXT:[<SINK>] PREV:[ret l1, ret l1, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== doSmth ==
fun doSmth(s: String) {}
@@ -107,7 +107,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -72,7 +72,7 @@ l13:
l1:
<END> NEXT:[<SINK>] PREV:[r(14)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -25,56 +25,9 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== O ==
object O {
val x : Int
{
$x = 1
}
}
---------------------
l0:
<START> NEXT:[v(val x : Int)] PREV:[]
v(val x : Int) NEXT:[r(1)] PREV:[<START>]
r(1) NEXT:[w($x)] PREV:[v(val x : Int)]
w($x) NEXT:[<END>] PREV:[r(1)]
l1:
<END> NEXT:[<SINK>] PREV:[w($x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== null ==
object {
val x : Int
{
$x = 1
}
fun foo() {
val b : Int = 1
doSmth(b)
}
}
---------------------
l0:
<START> NEXT:[v(val x : Int)] PREV:[]
v(val x : Int) NEXT:[r(1)] PREV:[<START>]
r(1) NEXT:[w($x)] PREV:[v(val x : Int)]
w($x) NEXT:[<END>] PREV:[r(1)]
l1:
<END> NEXT:[<SINK>] PREV:[w($x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== doSmth ==
fun doSmth(i: Int) {}
@@ -87,9 +40,9 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== test1 ==
fun test1() {
@@ -122,9 +75,29 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== O ==
object O {
val x : Int
{
$x = 1
}
}
---------------------
l0:
<START> NEXT:[v(val x : Int)] PREV:[]
v(val x : Int) NEXT:[r(1)] PREV:[<START>]
r(1) NEXT:[w($x)] PREV:[v(val x : Int)]
w($x) NEXT:[<END>] PREV:[r(1)]
l1:
<END> NEXT:[<SINK>] PREV:[w($x)]
error:
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== test2 ==
fun test2() {
@@ -152,25 +125,9 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== inner_bar ==
fun inner_bar() {
y = 10
}
---------------------
l3:
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
w(y) NEXT:[<END>] PREV:[r(10)]
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== test3 ==
fun test3() {
@@ -206,9 +163,9 @@ l2:
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[d(fun inner_bar() { y = 10 }) , <END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d(fun inner_bar() { y = 10 }) ]
l3:
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
@@ -216,12 +173,12 @@ l3:
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== ggg ==
fun ggg() {
== inner_bar ==
fun inner_bar() {
y = 10
}
---------------------
@@ -232,9 +189,9 @@ l3:
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== test4 ==
fun test4() {
@@ -285,9 +242,9 @@ l2:
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[d(fun ggg() { y = 10 }) , <END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d(fun ggg() { y = 10 }) ]
l3:
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
@@ -295,41 +252,25 @@ l3:
l4:
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== foo ==
fun foo() {
x = 3
== ggg ==
fun ggg() {
y = 10
}
---------------------
l3:
<START> NEXT:[r(3)] PREV:[]
r(3) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(3)]
<START> NEXT:[r(10)] PREV:[]
r(10) NEXT:[w(y)] PREV:[<START>]
w(y) NEXT:[<END>] PREV:[r(10)]
l4:
<END> NEXT:[<SINK>] PREV:[w(x)]
<END> NEXT:[<SINK>] PREV:[w(y)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
=====================
== bar ==
fun bar() {
x = 4
}
---------------------
l6:
<START> NEXT:[r(4)] PREV:[]
r(4) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(4)]
l7:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== test5 ==
fun test5() {
@@ -392,9 +333,9 @@ l5:
l1:
<END> NEXT:[<SINK>] PREV:[w(a)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[d(fun foo() { x = 3 }) , d(fun bar() { x = 4 }) , <END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d(fun foo() { x = 3 }) , d(fun bar() { x = 4 }) ]
l3:
<START> NEXT:[r(3)] PREV:[]
r(3) NEXT:[w(x)] PREV:[<START>]
@@ -402,9 +343,9 @@ l3:
l4:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
l6:
<START> NEXT:[r(4)] PREV:[]
r(4) NEXT:[w(x)] PREV:[<START>]
@@ -412,28 +353,39 @@ l6:
l7:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== foo ==
fun foo() {
val b : Int = 1
doSmth(b)
x = 3
}
---------------------
l0:
<START> NEXT:[v(val b : Int = 1)] PREV:[]
v(val b : Int = 1) NEXT:[r(1)] PREV:[<START>]
r(1) NEXT:[w(b)] PREV:[v(val b : Int = 1)]
w(b) NEXT:[r(b)] PREV:[r(1)]
r(b) NEXT:[r(doSmth)] PREV:[w(b)]
r(doSmth) NEXT:[r(doSmth(b))] PREV:[r(b)]
r(doSmth(b)) NEXT:[<END>] PREV:[r(doSmth)]
l1:
<END> NEXT:[<SINK>] PREV:[r(doSmth(b))]
l3:
<START> NEXT:[r(3)] PREV:[]
r(3) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(3)]
l4:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== bar ==
fun bar() {
x = 4
}
---------------------
l6:
<START> NEXT:[r(4)] PREV:[]
r(4) NEXT:[w(x)] PREV:[<START>]
w(x) NEXT:[<END>] PREV:[r(4)]
l7:
<END> NEXT:[<SINK>] PREV:[w(x)]
error:
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -25,9 +25,9 @@ l3:
l1:
<END> NEXT:[<SINK>] PREV:[read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
== dowhile ==
fun dowhile() {
@@ -53,7 +53,7 @@ l3:
l1:
<END> NEXT:[<SINK>] PREV:[ret l1]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -15,7 +15,7 @@ l2:
l1:
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(false || (return false))]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -7,7 +7,7 @@ l0:
l1:
<END> NEXT:[<SINK>] PREV:[r(1)]
error:
<ERROR> NEXT:[] PREV:[]
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
@@ -175,12 +175,12 @@ class B() {
fun testFunctionLiterals() {
val <!UNUSED_VARIABLE!>endsWithVarDeclaration<!> : () -> Boolean = {
<!EXPECTED_TYPE_MISMATCH!>val x = 2<!>
<!EXPECTED_TYPE_MISMATCH!>val <!UNUSED_VARIABLE!>x<!> = 2<!>
}
val <!UNUSED_VARIABLE!>endsWithAssignment<!> = { () : Int ->
var x = 1
<!EXPECTED_TYPE_MISMATCH!>x = 333<!>
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
<!EXPECTED_TYPE_MISMATCH!>x = <!UNUSED_VALUE!>333<!><!>
}
val <!UNUSED_VARIABLE!>endsWithReAssignment<!> = { () : Int ->
@@ -189,19 +189,19 @@ fun testFunctionLiterals() {
}
val <!UNUSED_VARIABLE!>endsWithFunDeclaration<!> : () -> String = {
var x = 1
x = 333
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
x = <!UNUSED_VALUE!>333<!>
<!EXPECTED_TYPE_MISMATCH!>fun meow() : Unit {}<!>
}
val <!UNUSED_VARIABLE!>endsWithObjectDeclaration<!> : () -> Int = {
var x = 1
x = 333
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
x = <!UNUSED_VALUE!>333<!>
<!EXPECTED_TYPE_MISMATCH!>object A {}<!>
}
val <!UNUSED_VARIABLE!>expectedUnitReturnType1<!> = { () : Unit ->
val x = 1
val <!UNUSED_VARIABLE!>x<!> = 1
}
val <!UNUSED_VARIABLE!>expectedUnitReturnType2<!> = { () : Unit ->
@@ -3,8 +3,8 @@ fun demo() {
val a = ""
val asd = 1
val bar = 5
fun map(f : () -> Any?) : Int = 1
fun buzz(f : () -> Any?) : Int = 1
fun map(<!UNUSED_PARAMETER!>f<!> : () -> Any?) : Int = 1
fun buzz(<!UNUSED_PARAMETER!>f<!> : () -> Any?) : Int = 1
val sdf = 1
val foo = 3;
<!UNUSED_EXPRESSION!>"$abc"<!>
@@ -19,4 +19,4 @@ fun demo() {
<!UNUSED_EXPRESSION!>"foo${bar + map {
"foo$sdf${ buzz{}}" }}sdfsdf"<!>
<!UNUSED_EXPRESSION!>"a<!ILLEGAL_ESCAPE_SEQUENCE!>\u<!> <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>0 <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>00 <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>000 \u0000 \u0AaA <!ILLEGAL_ESCAPE_SEQUENCE!>\u<!>0AAz.length( ) + \u0022b"<!>
}
}
@@ -101,7 +101,7 @@ fun t5() {
for (i in 0..2) {
<!VAL_REASSIGNMENT!>i<!> += 1
fun t5() {
<!VAL_REASSIGNMENT!>i<!> += 3
i += 3
}
}
}
@@ -297,8 +297,8 @@ class TestObjectExpression() {
<!VAL_REASSIGNMENT!>a<!> = 231
}
fun inner2() {
<!VAL_REASSIGNMENT!>y<!> = 101
<!VAL_REASSIGNMENT!>a<!> = 231
y = 101
a = 231
}
}
}
@@ -0,0 +1,12 @@
package c
fun test() {
val x = 10
fun inner1() {
fun inner2() {
fun inner3() {
val <!UNUSED_VARIABLE!>y<!> = x
}
}
}
}
@@ -12,8 +12,8 @@ fun main(args: Array<String>) {
<!EXPECTED_TYPE_MISMATCH!>x += 2<!> //no error, but it should be here
}
val <!UNUSED_VARIABLE!>h<!> = {(): String ->
var x = 1
<!EXPECTED_TYPE_MISMATCH!>x = 2<!> //the same
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
<!EXPECTED_TYPE_MISMATCH!>x = <!UNUSED_VALUE!>2<!><!> //the same
}
val array1 = MyArray1()
val <!UNUSED_VARIABLE!>i<!> = { (): String ->
@@ -46,4 +46,4 @@ class MyArray1() {
class MyNumber() {
fun inc(): MyNumber = MyNumber()
}
}
@@ -1,7 +1,7 @@
fun f(<!UNUSED_PARAMETER!>i<!>: Int) {
for (j in 1..100) {
<!UNUSED_FUNCTION_LITERAL!>{
var <!NAME_SHADOWING!>i<!> = 12
var <!NAME_SHADOWING, UNUSED_VARIABLE!>i<!> = 12
}<!>
}
}
}
@@ -1,7 +1,7 @@
fun ff(): Int {
var i = 1
<!UNUSED_FUNCTION_LITERAL!>{
val <!NAME_SHADOWING!>i<!> = 2
val <!NAME_SHADOWING, UNUSED_VARIABLE!>i<!> = 2
}<!>
return i
}
}
@@ -1,5 +1,5 @@
fun f(): Int {
var i = 17
<!UNUSED_FUNCTION_LITERAL!>{ (): Unit -> var <!NAME_SHADOWING!>i<!> = 18 }<!>
<!UNUSED_FUNCTION_LITERAL!>{ (): Unit -> var <!NAME_SHADOWING, UNUSED_VARIABLE!>i<!> = 18 }<!>
return i
}
}
@@ -33,7 +33,6 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.Severity;
@@ -170,8 +169,8 @@ public class JetTestUtils {
private JetTestUtils() {
}
public static AnalyzeExhaust analyzeFile(@NotNull JetFile namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(namespace, flowDataTraceFactory,
public static AnalyzeExhaust analyzeFile(@NotNull JetFile namespace) {
return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(namespace,
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true));
}
@@ -28,9 +28,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.lang.cfg.LoopInfo;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import java.io.File;
@@ -72,37 +73,17 @@ public class JetControlFlowTest extends JetLiteFixture {
JetFile file = loadPsiFile(myName + ".jet");
final Map<JetElement, Pseudocode> data = new LinkedHashMap<JetElement, Pseudocode>();
final JetPseudocodeTrace pseudocodeTrace = new JetPseudocodeTrace() {
@Override
public void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode) {
data.put(element, pseudocode);
AnalyzeExhaust analyzeExhaust = JetTestUtils.analyzeFile(file);
List<JetDeclaration> declarations = file.getDeclarations();
BindingContext bindingContext = analyzeExhaust.getBindingContext();
for (JetDeclaration declaration : declarations) {
Pseudocode pseudocode = PseudocodeUtil.generatePseudocode(declaration, bindingContext);
data.put(declaration, pseudocode);
for (LocalDeclarationInstruction instruction : pseudocode.getLocalDeclarations()) {
Pseudocode localPseudocode = instruction.getBody();
data.put(localPseudocode.getCorrespondingElement(), localPseudocode);
}
@Override
public void close() {
for (Pseudocode pseudocode : data.values()) {
pseudocode.postProcess();
}
}
@Override
public void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
}
@Override
public void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction) {
}
};
JetTestUtils.analyzeFile(file, new JetControlFlowDataTraceFactory() {
@NotNull
@Override
public JetPseudocodeTrace createTrace(JetElement element) {
return pseudocodeTrace;
}
});
}
try {
processCFData(myName, data);
@@ -123,6 +104,7 @@ public class JetControlFlowTest extends JetLiteFixture {
StringBuilder instructionDump = new StringBuilder();
int i = 0;
for (Pseudocode pseudocode : pseudocodes) {
JetElement correspondingElement = pseudocode.getCorrespondingElement();
String label = "";
assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetSecondaryConstructor || correspondingElement instanceof JetPropertyAccessor) :
@@ -146,11 +128,11 @@ public class JetControlFlowTest extends JetLiteFixture {
instructionDump.append(correspondingElement.getText());
instructionDump.append("\n---------------------\n");
dumpInstructions(pseudocode, instructionDump);
dumpInstructions((PseudocodeImpl) pseudocode, instructionDump);
instructionDump.append("=====================\n");
//check edges directions
Collection<Instruction> instructions = pseudocode.getMutableInstructionList();
Collection<Instruction> instructions = ((PseudocodeImpl)pseudocode).getAllInstructions();
for (Instruction instruction : instructions) {
if (!((InstructionImpl)instruction).isDead()) {
for (Instruction nextInstruction : instruction.getNextInstructions()) {
@@ -181,8 +163,8 @@ public class JetControlFlowTest extends JetLiteFixture {
// }
}
public void dfsDump(Pseudocode pseudocode, StringBuilder nodes, StringBuilder edges, Map<Instruction, String> nodeNames) {
dfsDump(nodes, edges, pseudocode.getMutableInstructionList().get(0), nodeNames);
public void dfsDump(PseudocodeImpl pseudocode, StringBuilder nodes, StringBuilder edges, Map<Instruction, String> nodeNames) {
dfsDump(nodes, edges, pseudocode.getAllInstructions().get(0), nodeNames);
}
private void dfsDump(StringBuilder nodes, StringBuilder edges, Instruction instruction, Map<Instruction, String> nodeNames) {
@@ -243,11 +225,11 @@ public class JetControlFlowTest extends JetLiteFixture {
return sb.toString();
}
public void dumpInstructions(Pseudocode pseudocode, @NotNull StringBuilder out) {
List<Instruction> instructions = pseudocode.getMutableInstructionList();
public void dumpInstructions(PseudocodeImpl pseudocode, @NotNull StringBuilder out) {
List<Instruction> instructions = pseudocode.getAllInstructions();
Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions());
List<Pseudocode.PseudocodeLabel> labels = pseudocode.getLabels();
List<Pseudocode> locals = new ArrayList<Pseudocode>();
List<PseudocodeImpl.PseudocodeLabel> labels = pseudocode.getLabels();
List<PseudocodeImpl> locals = new ArrayList<PseudocodeImpl>();
int maxLength = 0;
int maxNextLength = 0;
for (Instruction instruction : instructions) {
@@ -276,9 +258,9 @@ public class JetControlFlowTest extends JetLiteFixture {
Instruction instruction = instructions.get(i);
if (instruction instanceof LocalDeclarationInstruction) {
LocalDeclarationInstruction localDeclarationInstruction = (LocalDeclarationInstruction) instruction;
locals.add(localDeclarationInstruction.getBody());
locals.add((PseudocodeImpl) localDeclarationInstruction.getBody());
}
for (Pseudocode.PseudocodeLabel label: labels) {
for (PseudocodeImpl.PseudocodeLabel label: labels) {
if (label.getTargetInstructionIndex() == i) {
out.append(label.getName()).append(":\n");
}
@@ -288,7 +270,7 @@ public class JetControlFlowTest extends JetLiteFixture {
append(" NEXT:").append(String.format("%1$-" + maxNextLength + "s", formatInstructionList(instruction.getNextInstructions()))).
append(" PREV:").append(formatInstructionList(instruction.getPreviousInstructions())).append("\n");
}
for (Pseudocode local : locals) {
for (PseudocodeImpl local : locals) {
dumpInstructions(local, out);
}
}
@@ -300,7 +282,7 @@ public class JetControlFlowTest extends JetLiteFixture {
public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
int index = count[0];
// instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName);
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getBody().getMutableInstructionList().get(0)), null);
printEdge(out, nodeToName.get(instruction), nodeToName.get(((PseudocodeImpl)instruction.getBody()).getAllInstructions().get(0)), null);
visitInstructionWithNext(instruction);
}
@@ -415,7 +397,7 @@ public class JetControlFlowTest extends JetLiteFixture {
int[] count = new int[1];
Map<Instruction, String> nodeToName = new HashMap<Instruction, String>();
for (Pseudocode pseudocode : pseudocodes) {
dumpNodes(pseudocode.getMutableInstructionList(), out, count, nodeToName, Sets.newHashSet(pseudocode.getInstructions()));
dumpNodes(((PseudocodeImpl)pseudocode).getAllInstructions(), out, count, nodeToName, Sets.newHashSet(pseudocode.getInstructions()));
}
int i = 0;
for (Pseudocode pseudocode : pseudocodes) {
@@ -431,7 +413,7 @@ public class JetControlFlowTest extends JetLiteFixture {
out.println("subgraph cluster_" + i + " {\n" +
"label=\"" + label + "\";\n" +
"color=blue;\n");
dumpEdges(pseudocode.getMutableInstructionList(), out, count, nodeToName);
dumpEdges(((PseudocodeImpl)pseudocode).getAllInstructions(), out, count, nodeToName);
out.println("}");
i++;
}
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -107,8 +106,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
public void test(final @NotNull PsiFile psiFile) {
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
(JetFile) psiFile, JetControlFlowDataTraceFactory.EMPTY,
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true))
(JetFile) psiFile, CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true))
.getBindingContext();
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString();
@@ -29,7 +29,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
@@ -172,9 +171,7 @@ public class JetDiagnosticsTest extends JetLiteFixture {
}
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY,
myEnvironment.getCompilerDependencies())
.getBindingContext();
getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), myEnvironment.getCompilerDependencies()).getBindingContext();
boolean ok = true;
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -87,8 +86,7 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir {
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
psiFile, JetControlFlowDataTraceFactory.EMPTY,
jetCoreEnvironment.getCompilerDependencies())
psiFile, jetCoreEnvironment.getCompilerDependencies())
.getBindingContext();
return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel(Name.identifier("test")));
}
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
@@ -186,8 +185,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) {
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
myFile, JetControlFlowDataTraceFactory.EMPTY,
myEnvironment.getCompilerDependencies());
myFile, myEnvironment.getCompilerDependencies());
analyzeExhaust.throwIfError();
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
GenerationState state = new GenerationState(myEnvironment.getProject(), classBuilderFactory, analyzeExhaust, Collections.singletonList(myFile));
@@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
@@ -37,8 +36,7 @@ public class GenerationUtils {
public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile, @NotNull CompilerSpecialMode compilerSpecialMode) {
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
psiFile, JetControlFlowDataTraceFactory.EMPTY,
CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode, true));
psiFile, CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode, true));
analyzeExhaust.throwIfError();
GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile));
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
@@ -22,7 +22,6 @@ import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -78,8 +77,7 @@ public class DescriptorRendererTest extends JetLiteFixture {
JetFile psiFile = createPsiFile(null, fileName, loadFile(fileName));
AnalyzeExhaust analyzeExhaust =
AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
(JetFile) psiFile, JetControlFlowDataTraceFactory.EMPTY,
myEnvironment.getCompilerDependencies());
(JetFile) psiFile, myEnvironment.getCompilerDependencies());
final BindingContext bindingContext = analyzeExhaust.getBindingContext();
final List<DeclarationDescriptor> descriptors = new ArrayList<DeclarationDescriptor>();
psiFile.acceptChildren(new JetVisitorVoid() {
@@ -27,7 +27,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -154,8 +153,7 @@ public abstract class ExpectedResolveData {
JetStandardLibrary lib = JetStandardLibrary.getInstance();
AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(project, files,
Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY,
jetCoreEnvironment.getCompilerDependencies());
Predicates.<PsiFile>alwaysTrue(), jetCoreEnvironment.getCompilerDependencies());
BindingContext bindingContext = analyzeExhaust.getBindingContext();
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
if (diagnostic.getFactory() instanceof UnresolvedReferenceDiagnosticFactory) {
@@ -20,7 +20,6 @@ import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.di.InjectorForTests;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -66,7 +65,6 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture {
JetDeclaration aClass = declarations.get(0);
assert aClass instanceof JetClass;
AnalyzeExhaust bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(file,
JetControlFlowDataTraceFactory.EMPTY,
myEnvironment.getCompilerDependencies());
DeclarationDescriptor classDescriptor = bindingContext.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, aClass);
WritableScopeImpl scope = new WritableScopeImpl(libraryScope, root, RedeclarationHandler.DO_NOTHING);
@@ -698,7 +698,7 @@ public class JetTypeCheckerTest extends JetLiteFixture {
parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH);
// This call has side-effects on the parameterScope (fills it in)
List<TypeParameterDescriptor> typeParameters
List<TypeParameterDescriptorImpl> typeParameters
= descriptorResolver.resolveTypeParameters(classDescriptor, parameterScope, classElement.getTypeParameters(), JetTestUtils.DUMMY_TRACE);
descriptorResolver.resolveGenericBounds(classElement, parameterScope, typeParameters, JetTestUtils.DUMMY_TRACE);
@@ -110,7 +110,7 @@ public final class JetDescriptorIconProvider {
return ((PropertyDescriptor)descriptor).isVar() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL;
}
if (descriptor instanceof TypeParameterDescriptor) {
if (descriptor instanceof TypeParameterDescriptorImpl) {
return PlatformIcons.CLASS_ICON;
}
@@ -183,7 +183,7 @@ public class JetCompletionContributor extends CompletionContributor {
DeclarationDescriptor descriptor = ((JetLookupObject)object).getDescriptor();
return (descriptor instanceof ClassDescriptor) ||
(descriptor instanceof NamespaceDescriptor) ||
(descriptor instanceof TypeParameterDescriptor);
(descriptor instanceof TypeParameterDescriptorImpl);
}
}
@@ -33,7 +33,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import jet.Tuple2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -74,8 +73,7 @@ public class JetSourceNavigationHelper {
BindingContext bindingContext = AnalyzerFacadeProvider.getAnalyzerFacadeForProject(project).analyzeFiles(
project,
libraryFiles,
Predicates.<PsiFile>alwaysTrue(),
JetControlFlowDataTraceFactory.EMPTY).getBindingContext();
Predicates.<PsiFile>alwaysTrue()).getBindingContext();
D descriptor = bindingContext.get(slice, fqName);
if (descriptor != null) {
return new Tuple2<BindingContext, D>(bindingContext, descriptor);
@@ -28,7 +28,6 @@ import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -94,7 +93,6 @@ public final class AnalyzerFacadeWithCache {
AnalyzeExhaust exhaust = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).analyzeBodiesInFiles(
file.getProject(),
Predicates.<PsiFile>equalTo(file),
JetControlFlowDataTraceFactory.EMPTY,
new DelegatingBindingTrace(analyzeExhaustHeaders.getBindingContext()),
context);
@@ -137,8 +135,7 @@ public final class AnalyzerFacadeWithCache {
AnalyzeExhaust exhaust = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(fileToCache)
.analyzeFiles(fileToCache.getProject(),
headerFiles,
Predicates.<PsiFile>alwaysFalse(),
JetControlFlowDataTraceFactory.EMPTY);
Predicates.<PsiFile>alwaysFalse());
return new Result<AnalyzeExhaust>(exhaust, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
}
@@ -22,7 +22,6 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
@@ -44,8 +43,7 @@ public enum JSAnalyzerFacadeForIDEA implements AnalyzerFacade {
@Override
public AnalyzeExhaust analyzeFiles(@NotNull Project project,
@NotNull Collection<JetFile> files,
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely) {
return AnalyzerFacadeForJS.analyzeFiles(files, filesToAnalyzeCompletely, new IDEAConfig(project), true);
}
@@ -53,7 +51,6 @@ public enum JSAnalyzerFacadeForIDEA implements AnalyzerFacade {
@Override
public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
@NotNull Predicate<PsiFile> filesForBodiesResolve,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull BindingTrace traceContext,
@NotNull BodiesResolveContext bodiesResolveContext) {
return AnalyzerFacadeForJS.analyzeBodiesInFiles(filesForBodiesResolve, new IDEAConfig(project), traceContext, bodiesResolveContext);

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