Merge branch 'master' of github.com:JetBrains/kotlin
This commit is contained in:
+3
@@ -410,6 +410,9 @@
|
|||||||
<inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UtilityClassWithoutPrivateConstructor" 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="ignoreClassesWithOnlyMain" value="false" />
|
||||||
|
<option name="ignorableAnnotations">
|
||||||
|
<value />
|
||||||
|
</option>
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="VolatileLongOrDoubleField" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="VolatileLongOrDoubleField" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
|||||||
+1
-3
@@ -26,8 +26,6 @@
|
|||||||
<RunnerSettings RunnerId="Run" />
|
<RunnerSettings RunnerId="Run" />
|
||||||
<ConfigurationWrapper RunnerId="Debug" />
|
<ConfigurationWrapper RunnerId="Debug" />
|
||||||
<ConfigurationWrapper RunnerId="Run" />
|
<ConfigurationWrapper RunnerId="Run" />
|
||||||
<method>
|
<method />
|
||||||
<option name="AntTarget" enabled="false" antfile="file://$PROJECT_DIR$/js_backend_tests.xml" target="copy_lib" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
||||||
@@ -198,7 +198,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
|
private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
|
||||||
ClassDescriptor function = state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name);
|
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());
|
funDescriptor, function, name.getInternalName(), this, state.getInjector().getJetTypeMapper());
|
||||||
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
||||||
JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
|
JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
|
||||||
|
|||||||
@@ -35,25 +35,6 @@ import java.util.LinkedHashMap;
|
|||||||
* @author alex.tkachman
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public abstract class CodegenContext {
|
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;
|
private final DeclarationDescriptor contextType;
|
||||||
|
|
||||||
@@ -121,31 +102,31 @@ public abstract class CodegenContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CodegenContext intoNamespace(NamespaceDescriptor descriptor) {
|
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) {
|
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) {
|
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) {
|
public CodegenContexts.MethodContext intoFunction(FunctionDescriptor descriptor) {
|
||||||
return new MethodContext(descriptor, getContextKind(), this);
|
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) {
|
if(descriptor == null) {
|
||||||
descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.<AnnotationDescriptor>emptyList(), true)
|
descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.<AnnotationDescriptor>emptyList(), true)
|
||||||
.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PUBLIC);
|
.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) {
|
public CodegenContexts.ClosureContext intoClosure(FunctionDescriptor funDescriptor, ClassDescriptor classDescriptor, String internalClassName, ClosureCodegen closureCodegen, JetTypeMapper typeMapper) {
|
||||||
return new ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
|
return new CodegenContexts.ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrameMap prepareFrame(JetTypeMapper mapper) {
|
public FrameMap prepareFrame(JetTypeMapper mapper) {
|
||||||
@@ -190,7 +171,7 @@ public abstract class CodegenContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getTypeInfoConstantIndex(JetType type) {
|
public int getTypeInfoConstantIndex(JetType type) {
|
||||||
if (parentContext != STATIC) { return parentContext.getTypeInfoConstantIndex(type); }
|
if (parentContext != CodegenContexts.STATIC) { return parentContext.getTypeInfoConstantIndex(type); }
|
||||||
|
|
||||||
if(typeInfoConstants == null) {
|
if(typeInfoConstants == null) {
|
||||||
typeInfoConstants = new LinkedHashMap<JetType, Integer>();
|
typeInfoConstants = new LinkedHashMap<JetType, Integer>();
|
||||||
@@ -242,7 +223,7 @@ public abstract class CodegenContext {
|
|||||||
CallableMemberDescriptor.Kind.DECLARATION
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
JetType receiverType = pd.getReceiverParameter().exists() ? pd.getReceiverParameter().getType() : null;
|
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(
|
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
|
||||||
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
|
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
|
||||||
@@ -280,174 +261,4 @@ public abstract class CodegenContext {
|
|||||||
this.accessors.putAll(accessors);
|
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,
|
invokeDescriptor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
|
||||||
fd.getExpectedThisObject(),
|
fd.getExpectedThisObject(),
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptorImpl>emptyList(),
|
||||||
fd.getValueParameters(),
|
fd.getValueParameters(),
|
||||||
fd.getReturnType(),
|
fd.getReturnType(),
|
||||||
Modality.FINAL,
|
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;
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
||||||
v.invokevirtual("jet/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
v.invokevirtual("jet/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
||||||
v.checkcast(asmType(typeParameterDescriptor.getClassObjectType()));
|
v.checkcast(asmType(typeParameterDescriptor.getClassObjectType()));
|
||||||
@@ -1162,7 +1162,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
|
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
|
||||||
propertyDescriptor = propertyDescriptor.getOriginal();
|
propertyDescriptor = propertyDescriptor.getOriginal();
|
||||||
boolean isInsideClass = ((containingDeclaration == context.getThisDescriptor()) ||
|
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;
|
&& contextKind() != OwnerKind.TRAIT_IMPL;
|
||||||
Method getter;
|
Method getter;
|
||||||
Method setter;
|
Method setter;
|
||||||
@@ -1438,8 +1438,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private StackValue generateReceiver(DeclarationDescriptor provided) {
|
private StackValue generateReceiver(DeclarationDescriptor provided) {
|
||||||
assert context instanceof CodegenContext.ReceiverContext;
|
assert context instanceof CodegenContexts.ReceiverContext;
|
||||||
CodegenContext.ReceiverContext cur = (CodegenContext.ReceiverContext) context;
|
CodegenContexts.ReceiverContext cur = (CodegenContexts.ReceiverContext) context;
|
||||||
if (cur.getReceiverDescriptor() == provided) {
|
if (cur.getReceiverDescriptor() == provided) {
|
||||||
StackValue result = cur.getReceiverExpression(typeMapper);
|
StackValue result = cur.getReceiverExpression(typeMapper);
|
||||||
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, null);
|
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, null);
|
||||||
@@ -1458,7 +1458,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
cur = context;
|
cur = context;
|
||||||
StackValue result = StackValue.local(0, TYPE_OBJECT);
|
StackValue result = StackValue.local(0, TYPE_OBJECT);
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
if(cur instanceof CodegenContext.MethodContext && !(cur instanceof CodegenContext.ConstructorContext))
|
if(cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext))
|
||||||
cur = cur.getParentContext();
|
cur = cur.getParentContext();
|
||||||
|
|
||||||
if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
|
if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
|
||||||
@@ -1474,7 +1474,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
result = cur.getOuterExpression(result);
|
result = cur.getOuterExpression(result);
|
||||||
|
|
||||||
if(cur instanceof CodegenContext.ConstructorContext) {
|
if(cur instanceof CodegenContexts.ConstructorContext) {
|
||||||
cur = cur.getParentContext();
|
cur = cur.getParentContext();
|
||||||
}
|
}
|
||||||
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();
|
JetExpression left = expression.getLeft();
|
||||||
JetType leftType = bindingContext.get(BindingContext.EXPRESSION_TYPE, left);
|
JetType leftType = bindingContext.get(BindingContext.EXPRESSION_TYPE, left);
|
||||||
DeclarationDescriptor descriptor = rightType.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor descriptor = rightType.getConstructor().getDeclarationDescriptor();
|
||||||
if (descriptor instanceof ClassDescriptor || descriptor instanceof TypeParameterDescriptor) {
|
if (descriptor instanceof ClassDescriptor || descriptor instanceof TypeParameterDescriptorImpl) {
|
||||||
StackValue value = genQualified(receiver, left);
|
StackValue value = genQualified(receiver, left);
|
||||||
value.put(JetTypeMapper.boxType(value.type), v);
|
value.put(JetTypeMapper.boxType(value.type), v);
|
||||||
assert leftType != null;
|
assert leftType != null;
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class FunctionCodegen {
|
|||||||
JvmMethodSignature jvmMethod, boolean needJetAnnotations,
|
JvmMethodSignature jvmMethod, boolean needJetAnnotations,
|
||||||
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
|
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
|
||||||
|
|
||||||
CodegenContext.MethodContext funContext = owner.intoFunction(functionDescriptor);
|
CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor);
|
||||||
|
|
||||||
final JetExpression bodyExpression = f.getBodyExpression();
|
final JetExpression bodyExpression = f.getBodyExpression();
|
||||||
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
|
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
|
||||||
@@ -78,7 +78,7 @@ public class FunctionCodegen {
|
|||||||
private void generatedMethod(JetExpression bodyExpressions,
|
private void generatedMethod(JetExpression bodyExpressions,
|
||||||
JvmMethodSignature jvmSignature,
|
JvmMethodSignature jvmSignature,
|
||||||
boolean needJetAnnotations, @Nullable String propertyTypeSignature,
|
boolean needJetAnnotations, @Nullable String propertyTypeSignature,
|
||||||
CodegenContext.MethodContext context,
|
CodegenContexts.MethodContext context,
|
||||||
FunctionDescriptor functionDescriptor,
|
FunctionDescriptor functionDescriptor,
|
||||||
JetDeclarationWithBody fun
|
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();
|
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
|
||||||
|
|
||||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
|
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
|
||||||
|
|
||||||
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
|
CodegenContexts.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
|
||||||
|
|
||||||
JvmMethodSignature constructorMethod;
|
JvmMethodSignature constructorMethod;
|
||||||
CallableMethod callableMethod;
|
CallableMethod callableMethod;
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ public class JetTypeMapper {
|
|||||||
return asmType;
|
return asmType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor instanceof TypeParameterDescriptor) {
|
if (descriptor instanceof TypeParameterDescriptorImpl) {
|
||||||
|
|
||||||
Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
@@ -722,7 +722,7 @@ public class JetTypeMapper {
|
|||||||
signatureVisitor.writeInterfaceBoundEnd();
|
signatureVisitor.writeInterfaceBoundEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptorImpl) {
|
||||||
signatureVisitor.writeInterfaceBound();
|
signatureVisitor.writeInterfaceBound();
|
||||||
mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
|
mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
|
||||||
signatureVisitor.writeInterfaceBoundEnd();
|
signatureVisitor.writeInterfaceBoundEnd();
|
||||||
@@ -966,7 +966,7 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
public boolean isGenericsArray(JetType type) {
|
public boolean isGenericsArray(JetType type) {
|
||||||
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||||
if(declarationDescriptor instanceof TypeParameterDescriptor)
|
if(declarationDescriptor instanceof TypeParameterDescriptorImpl)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(standardLibrary.getArray().equals(declarationDescriptor))
|
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.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
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.JvmAbi;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@@ -57,7 +56,7 @@ public class NamespaceCodegen {
|
|||||||
|
|
||||||
public void generate(JetFile file) {
|
public void generate(JetFile file) {
|
||||||
NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, 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 FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state);
|
||||||
final PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, state);
|
final PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, state);
|
||||||
@@ -100,7 +99,7 @@ public class NamespaceCodegen {
|
|||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
FrameMap frameMap = new FrameMap();
|
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()) {
|
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
|
|||||||
@@ -106,9 +106,9 @@ public class ObjectOrClosureCodegen {
|
|||||||
FunctionDescriptor fd = (FunctionDescriptor) d;
|
FunctionDescriptor fd = (FunctionDescriptor) d;
|
||||||
|
|
||||||
// we generate method
|
// 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)
|
if(fcontext.getReceiverDescriptor() != fd)
|
||||||
return null;
|
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.AnalyzerWithCompilerReport;
|
||||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
|
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
|
||||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
|
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.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
@@ -246,7 +245,6 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
public AnalyzeExhaust invoke() {
|
public AnalyzeExhaust invoke() {
|
||||||
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||||
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely,
|
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely,
|
||||||
JetControlFlowDataTraceFactory.EMPTY,
|
|
||||||
configuration.getEnvironment().getCompilerDependencies());
|
configuration.getEnvironment().getCompilerDependencies());
|
||||||
}
|
}
|
||||||
}, environment.getSourceFiles()
|
}, environment.getSourceFiles()
|
||||||
|
|||||||
+32
-10
@@ -17,16 +17,42 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.di;
|
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 com.intellij.openapi.project.Project;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
|
||||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
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.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.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;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
/* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */
|
/* 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 TopDownAnalysisParameters topDownAnalysisParameters;
|
||||||
private final ObservableBindingTrace observableBindingTrace;
|
private final ObservableBindingTrace observableBindingTrace;
|
||||||
private final ModuleDescriptor moduleDescriptor;
|
private final ModuleDescriptor moduleDescriptor;
|
||||||
private final JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory;
|
|
||||||
private final CompilerDependencies compilerDependencies;
|
private final CompilerDependencies compilerDependencies;
|
||||||
private CompilerSpecialMode compilerSpecialMode;
|
private CompilerSpecialMode compilerSpecialMode;
|
||||||
private JavaBridgeConfiguration javaBridgeConfiguration;
|
private JavaBridgeConfiguration javaBridgeConfiguration;
|
||||||
@@ -69,7 +94,6 @@ public class InjectorForTopDownAnalyzerForJvm {
|
|||||||
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
|
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
|
||||||
@NotNull ObservableBindingTrace observableBindingTrace,
|
@NotNull ObservableBindingTrace observableBindingTrace,
|
||||||
@NotNull ModuleDescriptor moduleDescriptor,
|
@NotNull ModuleDescriptor moduleDescriptor,
|
||||||
JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory,
|
|
||||||
@NotNull CompilerDependencies compilerDependencies
|
@NotNull CompilerDependencies compilerDependencies
|
||||||
) {
|
) {
|
||||||
this.topDownAnalyzer = new TopDownAnalyzer();
|
this.topDownAnalyzer = new TopDownAnalyzer();
|
||||||
@@ -82,7 +106,6 @@ public class InjectorForTopDownAnalyzerForJvm {
|
|||||||
this.topDownAnalysisParameters = topDownAnalysisParameters;
|
this.topDownAnalysisParameters = topDownAnalysisParameters;
|
||||||
this.observableBindingTrace = observableBindingTrace;
|
this.observableBindingTrace = observableBindingTrace;
|
||||||
this.moduleDescriptor = moduleDescriptor;
|
this.moduleDescriptor = moduleDescriptor;
|
||||||
this.jetControlFlowDataTraceFactory = jetControlFlowDataTraceFactory;
|
|
||||||
this.compilerDependencies = compilerDependencies;
|
this.compilerDependencies = compilerDependencies;
|
||||||
this.compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
|
this.compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
|
||||||
this.javaBridgeConfiguration = new JavaBridgeConfiguration();
|
this.javaBridgeConfiguration = new JavaBridgeConfiguration();
|
||||||
@@ -126,7 +149,6 @@ public class InjectorForTopDownAnalyzerForJvm {
|
|||||||
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||||
this.bodyResolver.setTrace(observableBindingTrace);
|
this.bodyResolver.setTrace(observableBindingTrace);
|
||||||
|
|
||||||
this.controlFlowAnalyzer.setFlowDataTraceFactory(jetControlFlowDataTraceFactory);
|
|
||||||
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||||
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
|
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
|
||||||
|
|
||||||
|
|||||||
+11
-24
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzerFacade;
|
import org.jetbrains.jet.analyzer.AnalyzerFacade;
|
||||||
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
|
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.descriptors.ModuleDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
@@ -50,9 +49,8 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public AnalyzeExhaust analyzeFiles(@NotNull Project project,
|
public AnalyzeExhaust analyzeFiles(@NotNull Project project,
|
||||||
@NotNull Collection<JetFile> files,
|
@NotNull Collection<JetFile> files,
|
||||||
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
|
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely) {
|
||||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
return analyzeFilesWithJavaIntegration(project, files, filesToAnalyzeCompletely,
|
||||||
return analyzeFilesWithJavaIntegration(project, files, filesToAnalyzeCompletely, flowDataTraceFactory,
|
|
||||||
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR), true);
|
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,22 +58,19 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
|
|||||||
@Override
|
@Override
|
||||||
public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
|
public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
|
||||||
@NotNull Predicate<PsiFile> filesForBodiesResolve,
|
@NotNull Predicate<PsiFile> filesForBodiesResolve,
|
||||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
|
|
||||||
@NotNull BindingTrace headersTraceContext,
|
@NotNull BindingTrace headersTraceContext,
|
||||||
@NotNull BodiesResolveContext bodiesResolveContext
|
@NotNull BodiesResolveContext bodiesResolveContext
|
||||||
) {
|
) {
|
||||||
return analyzeBodiesInFilesWithJavaIntegration(
|
return analyzeBodiesInFilesWithJavaIntegration(
|
||||||
project, filesForBodiesResolve, flowDataTraceFactory,
|
project, filesForBodiesResolve, compilerDependenciesForProduction(CompilerSpecialMode.REGULAR),
|
||||||
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR),
|
|
||||||
headersTraceContext, bodiesResolveContext);
|
headersTraceContext, bodiesResolveContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AnalyzeExhaust analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
public static AnalyzeExhaust analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
||||||
JetFile file, JetControlFlowDataTraceFactory flowDataTraceFactory,
|
JetFile file, @NotNull CompilerDependencies compilerDependencies) {
|
||||||
@NotNull CompilerDependencies compilerDependencies) {
|
|
||||||
AnalyzingUtils.checkForSyntacticErrors(file);
|
AnalyzingUtils.checkForSyntacticErrors(file);
|
||||||
|
|
||||||
AnalyzeExhaust analyzeExhaust = analyzeOneFileWithJavaIntegration(file, flowDataTraceFactory, compilerDependencies);
|
AnalyzeExhaust analyzeExhaust = analyzeOneFileWithJavaIntegration(file, compilerDependencies);
|
||||||
|
|
||||||
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
|
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
|
||||||
|
|
||||||
@@ -83,24 +78,20 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static AnalyzeExhaust analyzeOneFileWithJavaIntegration(
|
public static AnalyzeExhaust analyzeOneFileWithJavaIntegration(
|
||||||
JetFile file, JetControlFlowDataTraceFactory flowDataTraceFactory,
|
JetFile file, @NotNull CompilerDependencies compilerDependencies) {
|
||||||
@NotNull CompilerDependencies compilerDependencies) {
|
|
||||||
return analyzeFilesWithJavaIntegration(file.getProject(), Collections.singleton(file),
|
return analyzeFilesWithJavaIntegration(file.getProject(), Collections.singleton(file),
|
||||||
Predicates.<PsiFile>alwaysTrue(), flowDataTraceFactory, compilerDependencies);
|
Predicates.<PsiFile>alwaysTrue(), compilerDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
|
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
|
||||||
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
|
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
|
||||||
JetControlFlowDataTraceFactory flowDataTraceFactory,
|
|
||||||
@NotNull CompilerDependencies compilerDependencies) {
|
@NotNull CompilerDependencies compilerDependencies) {
|
||||||
return analyzeFilesWithJavaIntegration(
|
return analyzeFilesWithJavaIntegration(
|
||||||
project, files, filesToAnalyzeCompletely,
|
project, files, filesToAnalyzeCompletely, compilerDependencies, false);
|
||||||
flowDataTraceFactory, compilerDependencies, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
|
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
|
||||||
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
|
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
|
||||||
JetControlFlowDataTraceFactory flowDataTraceFactory,
|
|
||||||
@NotNull CompilerDependencies compilerDependencies,
|
@NotNull CompilerDependencies compilerDependencies,
|
||||||
boolean storeContextForBodiesResolve) {
|
boolean storeContextForBodiesResolve) {
|
||||||
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
||||||
@@ -112,8 +103,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
|
|||||||
|
|
||||||
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
|
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
|
||||||
project, topDownAnalysisParameters,
|
project, topDownAnalysisParameters,
|
||||||
new ObservableBindingTrace(bindingTraceContext), owner, flowDataTraceFactory,
|
new ObservableBindingTrace(bindingTraceContext), owner, compilerDependencies);
|
||||||
compilerDependencies);
|
|
||||||
try {
|
try {
|
||||||
injector.getTopDownAnalyzer().analyzeFiles(files);
|
injector.getTopDownAnalyzer().analyzeFiles(files);
|
||||||
BodiesResolveContext bodiesResolveContext = storeContextForBodiesResolve ?
|
BodiesResolveContext bodiesResolveContext = storeContextForBodiesResolve ?
|
||||||
@@ -127,7 +117,6 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
|
|||||||
|
|
||||||
public static AnalyzeExhaust analyzeBodiesInFilesWithJavaIntegration(
|
public static AnalyzeExhaust analyzeBodiesInFilesWithJavaIntegration(
|
||||||
Project project, Predicate<PsiFile> filesToAnalyzeCompletely,
|
Project project, Predicate<PsiFile> filesToAnalyzeCompletely,
|
||||||
JetControlFlowDataTraceFactory flowDataTraceFactory,
|
|
||||||
@NotNull CompilerDependencies compilerDependencies,
|
@NotNull CompilerDependencies compilerDependencies,
|
||||||
@NotNull BindingTrace traceContext,
|
@NotNull BindingTrace traceContext,
|
||||||
@NotNull BodiesResolveContext bodiesResolveContext) {
|
@NotNull BodiesResolveContext bodiesResolveContext) {
|
||||||
@@ -140,8 +129,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
|
|||||||
|
|
||||||
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
|
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
|
||||||
project, topDownAnalysisParameters,
|
project, topDownAnalysisParameters,
|
||||||
new ObservableBindingTrace(traceContext), owner, flowDataTraceFactory,
|
new ObservableBindingTrace(traceContext), owner, compilerDependencies);
|
||||||
compilerDependencies);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
injector.getTopDownAnalyzer().doProcessForBodies(bodiesResolveContext);
|
injector.getTopDownAnalyzer().doProcessForBodies(bodiesResolveContext);
|
||||||
@@ -157,7 +145,6 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
|
|||||||
|
|
||||||
Project project = files.iterator().next().getProject();
|
Project project = files.iterator().next().getProject();
|
||||||
|
|
||||||
return analyzeFilesWithJavaIntegration(project, files, Predicates.<PsiFile>alwaysFalse(),
|
return analyzeFilesWithJavaIntegration(project, files, Predicates.<PsiFile>alwaysFalse(), compilerDependencies);
|
||||||
JetControlFlowDataTraceFactory.EMPTY, compilerDependencies);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-9
@@ -49,7 +49,7 @@ import java.util.*;
|
|||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class JavaDescriptorResolver {
|
public class JavaDescriptorResolver implements DependencyClassByQualifiedNameResolver {
|
||||||
|
|
||||||
public static final Name JAVA_ROOT = Name.special("<java_root>");
|
public static final Name JAVA_ROOT = Name.special("<java_root>");
|
||||||
|
|
||||||
@@ -107,14 +107,14 @@ public class JavaDescriptorResolver {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final TypeParameterDescriptorOrigin origin;
|
private final TypeParameterDescriptorOrigin origin;
|
||||||
@NotNull
|
@NotNull
|
||||||
final TypeParameterDescriptor descriptor;
|
final TypeParameterDescriptorImpl descriptor;
|
||||||
final PsiTypeParameter psiTypeParameter;
|
final PsiTypeParameter psiTypeParameter;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<JetType> upperBoundsForKotlin;
|
private final List<JetType> upperBoundsForKotlin;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<JetType> lowerBoundsForKotlin;
|
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.origin = TypeParameterDescriptorOrigin.JAVA;
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.psiTypeParameter = psiTypeParameter;
|
this.psiTypeParameter = psiTypeParameter;
|
||||||
@@ -122,7 +122,7 @@ public class JavaDescriptorResolver {
|
|||||||
this.lowerBoundsForKotlin = null;
|
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) {
|
List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
|
||||||
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
|
this.origin = TypeParameterDescriptorOrigin.KOTLIN;
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
@@ -307,6 +307,11 @@ public class JavaDescriptorResolver {
|
|||||||
return clazz;
|
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) {
|
private ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule, @NotNull List<Runnable> tasks) {
|
||||||
if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
|
if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
|
||||||
// TODO: only if -$$TImpl class is created by Kotlin
|
// TODO: only if -$$TImpl class is created by Kotlin
|
||||||
@@ -603,10 +608,10 @@ public class JavaDescriptorResolver {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final TypeVariableResolver typeVariableResolver;
|
private final TypeVariableResolver typeVariableResolver;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final TypeParameterDescriptor typeParameterDescriptor;
|
private final TypeParameterDescriptorImpl typeParameterDescriptor;
|
||||||
|
|
||||||
protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner,
|
protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner,
|
||||||
String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptor typeParameterDescriptor)
|
String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptorImpl typeParameterDescriptor)
|
||||||
{
|
{
|
||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
@@ -682,7 +687,7 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
|
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
|
||||||
TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification(
|
TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
|
Collections.<AnnotationDescriptor>emptyList(), // TODO: wrong
|
||||||
reified,
|
reified,
|
||||||
@@ -757,7 +762,7 @@ public class JavaDescriptorResolver {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
|
private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
|
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
Collections.<AnnotationDescriptor>emptyList(), // TODO
|
||||||
false,
|
false,
|
||||||
@@ -769,7 +774,7 @@ public class JavaDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) {
|
private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = typeParameter.descriptor;
|
TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor;
|
||||||
if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
|
if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
|
||||||
List<?> upperBounds = typeParameter.upperBoundsForKotlin;
|
List<?> upperBounds = typeParameter.upperBoundsForKotlin;
|
||||||
if (upperBounds.size() == 0){
|
if (upperBounds.size() == 0){
|
||||||
@@ -947,6 +952,11 @@ public class JavaDescriptorResolver {
|
|||||||
return scopeData.namespaceDescriptor;
|
return scopeData.namespaceDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) {
|
||||||
|
return resolveNamespace(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||||
|
}
|
||||||
|
|
||||||
private NamespaceDescriptorParent resolveParentNamespace(FqName fqName) {
|
private NamespaceDescriptorParent resolveParentNamespace(FqName fqName) {
|
||||||
if (fqName.isRoot()) {
|
if (fqName.isRoot()) {
|
||||||
return FAKE_ROOT_MODULE;
|
return FAKE_ROOT_MODULE;
|
||||||
|
|||||||
-1
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.java;
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
|
|||||||
+1
-6
@@ -17,12 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.java;
|
package org.jetbrains.jet.lang.resolve.java;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import com.google.common.base.Predicate;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
|
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
|
||||||
@@ -35,13 +34,11 @@ public interface AnalyzerFacade {
|
|||||||
@NotNull
|
@NotNull
|
||||||
AnalyzeExhaust analyzeFiles(@NotNull Project project,
|
AnalyzeExhaust analyzeFiles(@NotNull Project project,
|
||||||
@NotNull Collection<JetFile> files,
|
@NotNull Collection<JetFile> files,
|
||||||
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
|
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely);
|
||||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory);
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
|
AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
|
||||||
@NotNull Predicate<PsiFile> filesForBodiesResolve,
|
@NotNull Predicate<PsiFile> filesForBodiesResolve,
|
||||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
|
|
||||||
@NotNull BindingTrace traceContext,
|
@NotNull BindingTrace traceContext,
|
||||||
@NotNull BodiesResolveContext bodiesResolveContext);
|
@NotNull BodiesResolveContext bodiesResolveContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,36 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.di;
|
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 com.intellij.openapi.project.Project;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
|
||||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
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.CallResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
|
|
||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
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;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
/* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */
|
/* 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 TopDownAnalysisParameters topDownAnalysisParameters;
|
||||||
private final ObservableBindingTrace observableBindingTrace;
|
private final ObservableBindingTrace observableBindingTrace;
|
||||||
private final ModuleDescriptor moduleDescriptor;
|
private final ModuleDescriptor moduleDescriptor;
|
||||||
private final JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory;
|
|
||||||
private final ModuleConfiguration moduleConfiguration;
|
private final ModuleConfiguration moduleConfiguration;
|
||||||
private DeclarationResolver declarationResolver;
|
private DeclarationResolver declarationResolver;
|
||||||
private AnnotationResolver annotationResolver;
|
private AnnotationResolver annotationResolver;
|
||||||
@@ -63,7 +82,6 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
|
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
|
||||||
@NotNull ObservableBindingTrace observableBindingTrace,
|
@NotNull ObservableBindingTrace observableBindingTrace,
|
||||||
@NotNull ModuleDescriptor moduleDescriptor,
|
@NotNull ModuleDescriptor moduleDescriptor,
|
||||||
JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory,
|
|
||||||
@NotNull ModuleConfiguration moduleConfiguration
|
@NotNull ModuleConfiguration moduleConfiguration
|
||||||
) {
|
) {
|
||||||
this.topDownAnalyzer = new TopDownAnalyzer();
|
this.topDownAnalyzer = new TopDownAnalyzer();
|
||||||
@@ -76,7 +94,6 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
this.topDownAnalysisParameters = topDownAnalysisParameters;
|
this.topDownAnalysisParameters = topDownAnalysisParameters;
|
||||||
this.observableBindingTrace = observableBindingTrace;
|
this.observableBindingTrace = observableBindingTrace;
|
||||||
this.moduleDescriptor = moduleDescriptor;
|
this.moduleDescriptor = moduleDescriptor;
|
||||||
this.jetControlFlowDataTraceFactory = jetControlFlowDataTraceFactory;
|
|
||||||
this.moduleConfiguration = moduleConfiguration;
|
this.moduleConfiguration = moduleConfiguration;
|
||||||
this.declarationResolver = new DeclarationResolver();
|
this.declarationResolver = new DeclarationResolver();
|
||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
@@ -114,7 +131,6 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||||
this.bodyResolver.setTrace(observableBindingTrace);
|
this.bodyResolver.setTrace(observableBindingTrace);
|
||||||
|
|
||||||
this.controlFlowAnalyzer.setFlowDataTraceFactory(jetControlFlowDataTraceFactory);
|
|
||||||
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
|
||||||
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
|
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -64,7 +65,7 @@ public interface JetControlFlowBuilder {
|
|||||||
// Subroutines
|
// Subroutines
|
||||||
void enterSubroutine(@NotNull JetDeclaration subroutine);
|
void enterSubroutine(@NotNull JetDeclaration subroutine);
|
||||||
|
|
||||||
void exitSubroutine(@NotNull JetDeclaration subroutine);
|
Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
JetElement getCurrentSubroutine();
|
JetElement getCurrentSubroutine();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -157,9 +158,9 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
|
public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
|
||||||
assert builder != null;
|
assert builder != null;
|
||||||
builder.exitSubroutine(subroutine);
|
return builder.exitSubroutine(subroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@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 com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
@@ -45,12 +49,21 @@ public class JetControlFlowProcessor {
|
|||||||
private final JetControlFlowBuilder builder;
|
private final JetControlFlowBuilder builder;
|
||||||
private final BindingTrace trace;
|
private final BindingTrace trace;
|
||||||
|
|
||||||
public JetControlFlowProcessor(BindingTrace trace, JetControlFlowBuilder builder) {
|
public JetControlFlowProcessor(BindingTrace trace) {
|
||||||
this.builder = builder;
|
this.builder = new JetControlFlowInstructionsGenerator();
|
||||||
this.trace = trace;
|
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);
|
builder.enterSubroutine(subroutine);
|
||||||
if (subroutine instanceof JetDeclarationWithBody) {
|
if (subroutine instanceof JetDeclarationWithBody) {
|
||||||
JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine;
|
JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine;
|
||||||
@@ -67,7 +80,7 @@ public class JetControlFlowProcessor {
|
|||||||
else {
|
else {
|
||||||
subroutine.accept(new CFPVisitor(false));
|
subroutine.accept(new CFPVisitor(false));
|
||||||
}
|
}
|
||||||
builder.exitSubroutine(subroutine);
|
return builder.exitSubroutine(subroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processLocalDeclaration(@NotNull JetDeclaration subroutine) {
|
private void processLocalDeclaration(@NotNull JetDeclaration subroutine) {
|
||||||
|
|||||||
+107
-424
@@ -17,15 +17,16 @@
|
|||||||
package org.jetbrains.jet.lang.cfg;
|
package org.jetbrains.jet.lang.cfg;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.util.Pair;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
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.BindingContextUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
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.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.plugin.JetMainDetector;
|
import org.jetbrains.jet.plugin.JetMainDetector;
|
||||||
|
|
||||||
import java.util.*;
|
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.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
|
||||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
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 {
|
public class JetFlowInformationProvider {
|
||||||
|
|
||||||
private final Map<JetElement, Pseudocode> pseudocodeMap;
|
private final JetDeclaration subroutine;
|
||||||
|
private final Pseudocode pseudocode;
|
||||||
|
private final PseudocodeVariablesData pseudocodeVariablesData;
|
||||||
private BindingTrace trace;
|
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;
|
this.trace = trace;
|
||||||
final JetPseudocodeTrace pseudocodeTrace = flowDataTraceFactory.createTrace(declaration);
|
pseudocode = new JetControlFlowProcessor(trace).generatePseudocode(declaration);
|
||||||
pseudocodeMap = new HashMap<JetElement, Pseudocode>();
|
pseudocodeVariablesData = new PseudocodeVariablesData(pseudocode, trace.getBindingContext());
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull final Collection<JetElement> returnedExpressions) {
|
private void collectReturnExpressions(@NotNull final Collection<JetElement> returnedExpressions) {
|
||||||
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
|
||||||
assert pseudocode != null;
|
|
||||||
|
|
||||||
final Set<Instruction> instructions = Sets.newHashSet(pseudocode.getInstructions());
|
final Set<Instruction> instructions = Sets.newHashSet(pseudocode.getInstructions());
|
||||||
SubroutineExitInstruction exitInstruction = pseudocode.getExitInstruction();
|
SubroutineExitInstruction exitInstruction = pseudocode.getExitInstruction();
|
||||||
for (Instruction previousInstruction : exitInstruction.getPreviousInstructions()) {
|
for (Instruction previousInstruction : exitInstruction.getPreviousInstructions()) {
|
||||||
@@ -149,14 +121,15 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkDefiniteReturn(@NotNull final JetDeclarationWithBody function, final @NotNull JetType expectedReturnType) {
|
public void checkDefiniteReturn(final @NotNull JetType expectedReturnType) {
|
||||||
assert function instanceof JetDeclaration;
|
assert subroutine instanceof JetDeclarationWithBody;
|
||||||
|
JetDeclarationWithBody function = (JetDeclarationWithBody) subroutine;
|
||||||
|
|
||||||
JetExpression bodyExpression = function.getBodyExpression();
|
JetExpression bodyExpression = function.getBodyExpression();
|
||||||
if (bodyExpression == null) return;
|
if (bodyExpression == null) return;
|
||||||
|
|
||||||
List<JetElement> returnedExpressions = Lists.newArrayList();
|
List<JetElement> returnedExpressions = Lists.newArrayList();
|
||||||
collectReturnExpressions(function.asElement(), returnedExpressions);
|
collectReturnExpressions(returnedExpressions);
|
||||||
|
|
||||||
boolean nothingReturned = returnedExpressions.isEmpty();
|
boolean nothingReturned = returnedExpressions.isEmpty();
|
||||||
|
|
||||||
@@ -167,7 +140,7 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
final boolean blockBody = function.hasBlockBody();
|
final boolean blockBody = function.hasBlockBody();
|
||||||
|
|
||||||
final Set<JetElement> rootUnreachableElements = collectUnreachableCode(function.asElement());
|
final Set<JetElement> rootUnreachableElements = collectUnreachableCode();
|
||||||
for (JetElement element : rootUnreachableElements) {
|
for (JetElement element : rootUnreachableElements) {
|
||||||
trace.report(UNREACHABLE_CODE.on(element));
|
trace.report(UNREACHABLE_CODE.on(element));
|
||||||
}
|
}
|
||||||
@@ -195,10 +168,7 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<JetElement> collectUnreachableCode(@NotNull JetElement subroutine) {
|
private Set<JetElement> collectUnreachableCode() {
|
||||||
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
|
||||||
assert pseudocode != null;
|
|
||||||
|
|
||||||
Collection<JetElement> unreachableElements = Lists.newArrayList();
|
Collection<JetElement> unreachableElements = Lists.newArrayList();
|
||||||
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
|
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
|
||||||
if (deadInstruction instanceof JetElementInstruction &&
|
if (deadInstruction instanceof JetElementInstruction &&
|
||||||
@@ -213,73 +183,61 @@ public class JetFlowInformationProvider {
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Uninitialized variables analysis
|
// Uninitialized variables analysis
|
||||||
|
|
||||||
public void markUninitializedVariables(@NotNull JetElement subroutine, final boolean processLocalDeclaration) {
|
public void markUninitializedVariables(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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final Collection<VariableDescriptor> varWithUninitializedErrorGenerated = Sets.newHashSet();
|
final Collection<VariableDescriptor> varWithUninitializedErrorGenerated = Sets.newHashSet();
|
||||||
final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet();
|
final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet();
|
||||||
final boolean processClassOrObject = subroutine instanceof JetClassOrObject;
|
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
|
@Override
|
||||||
public void execute(@NotNull Instruction instruction, @Nullable Map<VariableDescriptor, VariableInitializers> enterData, @Nullable Map<VariableDescriptor, VariableInitializers> exitData) {
|
public void execute(@NotNull Instruction instruction,
|
||||||
assert enterData != null && exitData != null;
|
@Nullable Map<VariableDescriptor, VariableInitState> in,
|
||||||
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, true);
|
@Nullable Map<VariableDescriptor, PseudocodeVariablesData.VariableInitState> out) {
|
||||||
|
assert in != null && out != null;
|
||||||
|
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, true, trace.getBindingContext());
|
||||||
if (variableDescriptor == null) return;
|
if (variableDescriptor == null) return;
|
||||||
|
if (!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction)) return;
|
||||||
|
VariableInitState outInitState = out.get(variableDescriptor);
|
||||||
if (instruction instanceof ReadValueInstruction) {
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
||||||
boolean error = checkBackingField(variableDescriptor, element);
|
boolean error = checkBackingField(variableDescriptor, element);
|
||||||
if (!error && declaredVariables.contains(variableDescriptor)) {
|
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();
|
||||||
JetElement element = ((WriteValueInstruction) instruction).getlValue();
|
boolean error = checkBackingField(variableDescriptor, element);
|
||||||
boolean error = checkBackingField(variableDescriptor, element);
|
if (!(element instanceof JetExpression)) return;
|
||||||
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
|
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);
|
error = checkValReassignment(variableDescriptor, (JetExpression) element, inInitState, varWithValReassignErrorGenerated);
|
||||||
}
|
}
|
||||||
if (!error && processClassOrObject) {
|
if (!error && processClassOrObject) {
|
||||||
error = checkAssignmentBeforeDeclaration(variableDescriptor, (JetExpression) element, enterData.get(variableDescriptor), exitData.get(variableDescriptor));
|
error = checkAssignmentBeforeDeclaration(variableDescriptor, (JetExpression) element, inInitState, outInitState);
|
||||||
}
|
}
|
||||||
if (!error && processClassOrObject) {
|
if (!error && processClassOrObject) {
|
||||||
checkInitializationUsingBackingField(variableDescriptor, (JetExpression) element, enterData.get(variableDescriptor), exitData.get(variableDescriptor));
|
checkInitializationUsingBackingField(variableDescriptor, (JetExpression) element, inInitState, outInitState);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
recordInitializedVariables(declaredVariables, traverser.getResultInfo());
|
Pseudocode pseudocode = pseudocodeVariablesData.getPseudocode();
|
||||||
analyzeLocalDeclarations(pseudocode, processLocalDeclaration);
|
recordInitializedVariables(pseudocode, initializers);
|
||||||
|
for (LocalDeclarationInstruction instruction : pseudocode.getLocalDeclarations()) {
|
||||||
|
recordInitializedVariables(instruction.getBody(), initializers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkIsInitialized(@NotNull VariableDescriptor variableDescriptor,
|
private void checkIsInitialized(@NotNull VariableDescriptor variableDescriptor,
|
||||||
@NotNull JetElement element,
|
@NotNull JetElement element,
|
||||||
@NotNull VariableInitializers variableInitializers,
|
@NotNull PseudocodeVariablesData.VariableInitState variableInitState,
|
||||||
@NotNull Collection<VariableDescriptor> varWithUninitializedErrorGenerated) {
|
@NotNull Collection<VariableDescriptor> varWithUninitializedErrorGenerated) {
|
||||||
if (!(element instanceof JetSimpleNameExpression)) return;
|
if (!(element instanceof JetSimpleNameExpression)) return;
|
||||||
|
|
||||||
boolean isInitialized = variableInitializers.isInitialized();
|
boolean isInitialized = variableInitState.isInitialized;
|
||||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||||
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) {
|
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) {
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
@@ -288,7 +246,8 @@ public class JetFlowInformationProvider {
|
|||||||
if (!isInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
|
if (!isInitialized && !varWithUninitializedErrorGenerated.contains(variableDescriptor)) {
|
||||||
varWithUninitializedErrorGenerated.add(variableDescriptor);
|
varWithUninitializedErrorGenerated.add(variableDescriptor);
|
||||||
if (variableDescriptor instanceof ValueParameterDescriptor) {
|
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 {
|
else {
|
||||||
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
|
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
|
||||||
@@ -298,15 +257,11 @@ public class JetFlowInformationProvider {
|
|||||||
|
|
||||||
private boolean checkValReassignment(@NotNull VariableDescriptor variableDescriptor,
|
private boolean checkValReassignment(@NotNull VariableDescriptor variableDescriptor,
|
||||||
@NotNull JetExpression expression,
|
@NotNull JetExpression expression,
|
||||||
@NotNull VariableInitializers enterInitializers,
|
@NotNull VariableInitState enterInitState,
|
||||||
@NotNull Collection<VariableDescriptor> varWithValReassignErrorGenerated) {
|
@NotNull Collection<VariableDescriptor> varWithValReassignErrorGenerated) {
|
||||||
boolean isInitializedNotHere = enterInitializers.isInitialized();
|
boolean isInitializedNotHere = enterInitState.isInitialized;
|
||||||
Set<JetElement> possibleLocalInitializers = enterInitializers.getPossibleLocalInitializers();
|
if (expression.getParent() instanceof JetProperty && ((JetProperty)expression).getInitializer() != null) {
|
||||||
if (possibleLocalInitializers.size() == 1) {
|
isInitializedNotHere = false;
|
||||||
JetElement initializer = possibleLocalInitializers.iterator().next();
|
|
||||||
if (initializer instanceof JetProperty && initializer == expression.getParent()) {
|
|
||||||
isInitializedNotHere = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
boolean hasBackingField = true;
|
boolean hasBackingField = true;
|
||||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||||
@@ -349,16 +304,16 @@ public class JetFlowInformationProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkAssignmentBeforeDeclaration(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitializers enterInitializers, @NotNull VariableInitializers exitInitializers) {
|
private boolean checkAssignmentBeforeDeclaration(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitState enterInitState, @NotNull VariableInitState exitInitState) {
|
||||||
if (!enterInitializers.isDeclared() && !exitInitializers.isDeclared() && !enterInitializers.isInitialized() && exitInitializers.isInitialized()) {
|
if (!enterInitState.isDeclared && !exitInitState.isDeclared && !enterInitState.isInitialized && exitInitState.isInitialized) {
|
||||||
trace.report(Errors.INITIALIZATION_BEFORE_DECLARATION.on(expression, variableDescriptor));
|
trace.report(Errors.INITIALIZATION_BEFORE_DECLARATION.on(expression, variableDescriptor));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkInitializationUsingBackingField(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitializers enterInitializers, @NotNull VariableInitializers exitInitializers) {
|
private boolean checkInitializationUsingBackingField(@NotNull VariableDescriptor variableDescriptor, @NotNull JetExpression expression, @NotNull VariableInitState enterInitState, @NotNull VariableInitState exitInitState) {
|
||||||
if (variableDescriptor instanceof PropertyDescriptor && !enterInitializers.isInitialized() && exitInitializers.isInitialized()) {
|
if (variableDescriptor instanceof PropertyDescriptor && !enterInitState.isInitialized && exitInitState.isInitialized) {
|
||||||
if (!variableDescriptor.isVar()) return false;
|
if (!variableDescriptor.isVar()) return false;
|
||||||
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) return false;
|
if (!trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor)) return false;
|
||||||
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
|
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
|
||||||
@@ -397,7 +352,9 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
|
PsiElement property = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), variableDescriptor);
|
||||||
boolean insideSelfAccessors = PsiTreeUtil.isAncestor(property, element, false);
|
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) {
|
if (((PropertyDescriptor) variableDescriptor).getModality() == Modality.ABSTRACT) {
|
||||||
trace.report(NO_BACKING_FIELD_ABSTRACT_PROPERTY.on(element));
|
trace.report(NO_BACKING_FIELD_ABSTRACT_PROPERTY.on(element));
|
||||||
}
|
}
|
||||||
@@ -436,173 +393,44 @@ public class JetFlowInformationProvider {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordInitializedVariables(Collection<VariableDescriptor> declaredVariables, Map<VariableDescriptor, VariableInitializers> resultInfo) {
|
private void recordInitializedVariables(@NotNull Pseudocode pseudocode, @NotNull Map<Instruction, Edges<Map<VariableDescriptor,PseudocodeVariablesData.VariableInitState>>> initializersMap) {
|
||||||
for (Map.Entry<VariableDescriptor, VariableInitializers> entry : resultInfo.entrySet()) {
|
Edges<Map<VariableDescriptor, VariableInitState>> initializers = initializersMap.get(pseudocode.getExitInstruction());
|
||||||
VariableDescriptor variable = entry.getKey();
|
Set<VariableDescriptor> usedVariables = pseudocodeVariablesData.getUsedVariables(pseudocode);
|
||||||
if (variable instanceof PropertyDescriptor && declaredVariables.contains(variable)) {
|
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode);
|
||||||
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);
|
|
||||||
|
|
||||||
for (VariableDescriptor variable : usedVariables) {
|
for (VariableDescriptor variable : usedVariables) {
|
||||||
if (declaredVariables.contains(variable)) {
|
if (variable instanceof PropertyDescriptor && declaredVariables.contains(variable)) {
|
||||||
initialMapForStartInstruction.put(variable, isNotInitializedForDeclaredVariable);
|
PseudocodeVariablesData.VariableInitState variableInitState = initializers.in.get(variable);
|
||||||
}
|
if (variableInitState == null) return;
|
||||||
else {
|
trace.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) variable, variableInitState.isInitialized);
|
||||||
initialMapForStartInstruction.put(variable, isInitializedForExternalVariable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
// "Unused variable" & "unused value" analyses
|
||||||
|
|
||||||
public void markUnusedVariables(@NotNull JetElement subroutine) {
|
public void markUnusedVariables() {
|
||||||
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> variableStatusData = pseudocodeVariablesData.getVariableUseStatusData();
|
||||||
assert pseudocode != null;
|
InstructionDataAnalyzeStrategy<Map<VariableDescriptor, VariableUseState>> variableStatusAnalyzeStrategy =
|
||||||
JetControlFlowGraphTraverser<Map<VariableDescriptor, VariableStatus>> traverser = JetControlFlowGraphTraverser.create(pseudocode, true, false);
|
new InstructionDataAnalyzeStrategy<Map<VariableDescriptor, PseudocodeVariablesData.VariableUseState>>() {
|
||||||
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>>() {
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<Map<VariableDescriptor, VariableStatus>, Map<VariableDescriptor, VariableStatus>> execute(@NotNull Instruction instruction, @NotNull Collection<Map<VariableDescriptor, VariableStatus>> incomingEdgesData) {
|
public void execute(@NotNull Instruction instruction,
|
||||||
Map<VariableDescriptor, VariableStatus> enterResult = Maps.newHashMap();
|
@Nullable Map<VariableDescriptor, PseudocodeVariablesData.VariableUseState> in,
|
||||||
for (Map<VariableDescriptor, VariableStatus> edgeData : incomingEdgesData) {
|
@Nullable Map<VariableDescriptor, VariableUseState> out) {
|
||||||
for (Map.Entry<VariableDescriptor, VariableStatus> entry : edgeData.entrySet()) {
|
|
||||||
VariableDescriptor variableDescriptor = entry.getKey();
|
assert in != null && out != null;
|
||||||
VariableStatus variableStatus = entry.getValue();
|
Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(instruction.getOwner());
|
||||||
enterResult.put(variableDescriptor, variableStatus.merge(enterResult.get(variableDescriptor)));
|
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(instruction, false,
|
||||||
}
|
trace.getBindingContext());
|
||||||
}
|
|
||||||
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);
|
|
||||||
if (variableDescriptor == null || !declaredVariables.contains(variableDescriptor) ||
|
if (variableDescriptor == null || !declaredVariables.contains(variableDescriptor) ||
|
||||||
!DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return;
|
!DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return;
|
||||||
VariableStatus variableStatus = enterData.get(variableDescriptor);
|
PseudocodeVariablesData.VariableUseState variableUseState = in.get(variableDescriptor);
|
||||||
if (instruction instanceof WriteValueInstruction) {
|
if (instruction instanceof WriteValueInstruction) {
|
||||||
if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor)) return;
|
if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor)) return;
|
||||||
JetElement element = ((WriteValueInstruction) instruction).getElement();
|
JetElement element = ((WriteValueInstruction) instruction).getElement();
|
||||||
if (variableStatus != VariableStatus.READ) {
|
if (variableUseState != LAST_READ) {
|
||||||
if (element instanceof JetBinaryExpression && ((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
|
if (element instanceof JetBinaryExpression &&
|
||||||
|
((JetBinaryExpression) element).getOperationToken() == JetTokens.EQ) {
|
||||||
JetExpression right = ((JetBinaryExpression) element).getRight();
|
JetExpression right = ((JetBinaryExpression) element).getRight();
|
||||||
if (right != null) {
|
if (right != null) {
|
||||||
trace.report(Errors.UNUSED_VALUE.on(right, right, variableDescriptor));
|
trace.report(Errors.UNUSED_VALUE.on(right, right, variableDescriptor));
|
||||||
@@ -621,7 +449,7 @@ public class JetFlowInformationProvider {
|
|||||||
if (element instanceof JetNamedDeclaration) {
|
if (element instanceof JetNamedDeclaration) {
|
||||||
PsiElement nameIdentifier = ((JetNamedDeclaration) element).getNameIdentifier();
|
PsiElement nameIdentifier = ((JetNamedDeclaration) element).getNameIdentifier();
|
||||||
if (nameIdentifier == null) return;
|
if (nameIdentifier == null) return;
|
||||||
if (variableStatus == null || variableStatus == VariableStatus.UNUSED) {
|
if (!VariableUseState.isUsed(variableUseState)) {
|
||||||
if (element instanceof JetProperty) {
|
if (element instanceof JetProperty) {
|
||||||
trace.report(Errors.UNUSED_VARIABLE.on((JetProperty) element, variableDescriptor));
|
trace.report(Errors.UNUSED_VARIABLE.on((JetProperty) element, variableDescriptor));
|
||||||
}
|
}
|
||||||
@@ -629,8 +457,9 @@ public class JetFlowInformationProvider {
|
|||||||
PsiElement psiElement = element.getParent().getParent();
|
PsiElement psiElement = element.getParent().getParent();
|
||||||
if (psiElement instanceof JetFunction) {
|
if (psiElement instanceof JetFunction) {
|
||||||
boolean isMain = (psiElement instanceof JetNamedFunction) && JetMainDetector.isMain((JetNamedFunction) psiElement);
|
boolean isMain = (psiElement instanceof JetNamedFunction) && JetMainDetector.isMain((JetNamedFunction) psiElement);
|
||||||
|
if (psiElement instanceof JetFunctionLiteral) return;
|
||||||
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement);
|
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement);
|
||||||
assert descriptor instanceof FunctionDescriptor;
|
assert descriptor instanceof FunctionDescriptor : psiElement.getText();
|
||||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||||
if (!isMain && !functionDescriptor.getModality().isOverridable() && functionDescriptor.getOverriddenDescriptors().isEmpty()) {
|
if (!isMain && !functionDescriptor.getModality().isOverridable() && functionDescriptor.getOverriddenDescriptors().isEmpty()) {
|
||||||
trace.report(Errors.UNUSED_PARAMETER.on((JetParameter) element, variableDescriptor));
|
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));
|
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();
|
JetExpression initializer = ((JetProperty) element).getInitializer();
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
trace.report(Errors.VARIABLE_WITH_REDUNDANT_INITIALIZER.on(initializer, variableDescriptor));
|
trace.report(Errors.VARIABLE_WITH_REDUNDANT_INITIALIZER.on(initializer, variableDescriptor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
PseudocodeTraverser.traverse(pseudocode, false, true, variableStatusData, variableStatusAnalyzeStrategy);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// "Unused literals" in block
|
// "Unused literals" in block
|
||||||
|
|
||||||
public void markUnusedLiteralsInBlock(@NotNull JetElement subroutine) {
|
public void markUnusedLiteralsInBlock() {
|
||||||
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
|
||||||
assert pseudocode != null;
|
assert pseudocode != null;
|
||||||
JetControlFlowGraphTraverser<Void> traverser = JetControlFlowGraphTraverser.create(pseudocode, true, true);
|
PseudocodeTraverser.traverse(
|
||||||
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
|
pseudocode, true, new InstructionAnalyzeStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(@NotNull Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) {
|
public void execute(@NotNull Instruction instruction) {
|
||||||
if (!(instruction instanceof ReadValueInstruction)) return;
|
if (!(instruction instanceof ReadValueInstruction)) return;
|
||||||
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
JetElement element =
|
||||||
|
((ReadValueInstruction) instruction).getElement();
|
||||||
if (!(element instanceof JetFunctionLiteralExpression
|
if (!(element instanceof JetFunctionLiteralExpression
|
||||||
|| element instanceof JetConstantExpression
|
|| element instanceof JetConstantExpression
|
||||||
|| element instanceof JetStringTemplateExpression
|
|| element instanceof JetStringTemplateExpression
|
||||||
@@ -694,7 +505,8 @@ public class JetFlowInformationProvider {
|
|||||||
if (parent instanceof JetBlockExpression) {
|
if (parent instanceof JetBlockExpression) {
|
||||||
if (!JetPsiUtil.isImplicitlyUsed(element)) {
|
if (!JetPsiUtil.isImplicitlyUsed(element)) {
|
||||||
if (element instanceof JetFunctionLiteralExpression) {
|
if (element instanceof JetFunctionLiteralExpression) {
|
||||||
trace.report(Errors.UNUSED_FUNCTION_LITERAL.on((JetFunctionLiteralExpression) element));
|
trace.report(Errors.UNUSED_FUNCTION_LITERAL
|
||||||
|
.on((JetFunctionLiteralExpression) element));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trace.report(Errors.UNUSED_EXPRESSION.on(element));
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-17
@@ -35,12 +35,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
|
|
||||||
private final Stack<BlockInfo> allBlocks = new Stack<BlockInfo>();
|
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) {
|
private void pushBuilder(JetElement scopingElement, JetElement subroutine) {
|
||||||
JetControlFlowInstructionsGeneratorWorker worker = new JetControlFlowInstructionsGeneratorWorker(scopingElement, subroutine);
|
JetControlFlowInstructionsGeneratorWorker worker = new JetControlFlowInstructionsGeneratorWorker(scopingElement, subroutine);
|
||||||
builders.push(worker);
|
builders.push(worker);
|
||||||
@@ -49,7 +43,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
|
|
||||||
private JetControlFlowInstructionsGeneratorWorker popBuilder(@NotNull JetElement element) {
|
private JetControlFlowInstructionsGeneratorWorker popBuilder(@NotNull JetElement element) {
|
||||||
JetControlFlowInstructionsGeneratorWorker worker = builders.pop();
|
JetControlFlowInstructionsGeneratorWorker worker = builders.pop();
|
||||||
trace.recordControlFlowData(element, worker.getPseudocode());
|
|
||||||
if (!builders.isEmpty()) {
|
if (!builders.isEmpty()) {
|
||||||
builder = builders.peek();
|
builder = builders.peek();
|
||||||
}
|
}
|
||||||
@@ -72,7 +65,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
|
public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
|
||||||
super.exitSubroutine(subroutine);
|
super.exitSubroutine(subroutine);
|
||||||
JetControlFlowInstructionsGeneratorWorker worker = popBuilder(subroutine);
|
JetControlFlowInstructionsGeneratorWorker worker = popBuilder(subroutine);
|
||||||
if (!builders.empty()) {
|
if (!builders.empty()) {
|
||||||
@@ -80,32 +73,29 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
LocalDeclarationInstruction instruction = new LocalDeclarationInstruction(subroutine, worker.getPseudocode());
|
LocalDeclarationInstruction instruction = new LocalDeclarationInstruction(subroutine, worker.getPseudocode());
|
||||||
builder.add(instruction);
|
builder.add(instruction);
|
||||||
}
|
}
|
||||||
|
return worker.getPseudocode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JetControlFlowInstructionsGeneratorWorker implements JetControlFlowBuilder {
|
private class JetControlFlowInstructionsGeneratorWorker implements JetControlFlowBuilder {
|
||||||
|
|
||||||
private final Pseudocode pseudocode;
|
private final PseudocodeImpl pseudocode;
|
||||||
private final Label error;
|
private final Label error;
|
||||||
private final Label sink;
|
private final Label sink;
|
||||||
private final JetElement returnSubroutine;
|
private final JetElement returnSubroutine;
|
||||||
|
|
||||||
private JetControlFlowInstructionsGeneratorWorker(@NotNull JetElement scopingElement, @NotNull 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.error = pseudocode.createLabel("error");
|
||||||
this.sink = pseudocode.createLabel("sink");
|
this.sink = pseudocode.createLabel("sink");
|
||||||
this.returnSubroutine = returnSubroutine;
|
this.returnSubroutine = returnSubroutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pseudocode getPseudocode() {
|
public PseudocodeImpl getPseudocode() {
|
||||||
return pseudocode;
|
return pseudocode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(@NotNull Instruction instruction) {
|
private void add(@NotNull Instruction instruction) {
|
||||||
pseudocode.addInstruction(instruction);
|
pseudocode.addInstruction(instruction);
|
||||||
if (instruction instanceof JetElementInstruction) {
|
|
||||||
JetElementInstruction elementInstruction = (JetElementInstruction) instruction;
|
|
||||||
trace.recordRepresentativeInstruction(elementInstruction.getElement(), instruction);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -127,7 +117,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
loopInfo.push(blockInfo);
|
loopInfo.push(blockInfo);
|
||||||
elementToBlockInfo.put(expression, blockInfo);
|
elementToBlockInfo.put(expression, blockInfo);
|
||||||
allBlocks.push(blockInfo);
|
allBlocks.push(blockInfo);
|
||||||
trace.recordLoopInfo(expression, blockInfo);
|
pseudocode.recordLoopInfo(expression, blockInfo);
|
||||||
return blockInfo;
|
return blockInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +192,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
|
public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
|
||||||
bindLabel(getExitPoint(subroutine));
|
bindLabel(getExitPoint(subroutine));
|
||||||
pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>"));
|
pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>"));
|
||||||
bindLabel(error);
|
bindLabel(error);
|
||||||
@@ -211,6 +201,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
pseudocode.addSinkInstruction(new SubroutineSinkInstruction(subroutine, "<SINK>"));
|
pseudocode.addSinkInstruction(new SubroutineSinkInstruction(subroutine, "<SINK>"));
|
||||||
elementToBlockInfo.remove(subroutine);
|
elementToBlockInfo.remove(subroutine);
|
||||||
allBlocks.pop();
|
allBlocks.pop();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
|
||||||
}
|
|
||||||
+7
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -40,6 +41,12 @@ public class LocalDeclarationInstruction extends InstructionWithNext {
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetDeclaration getElement() {
|
||||||
|
return (JetDeclaration) super.getElement();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<Instruction> getNextInstructions() {
|
public Collection<Instruction> getNextInstructions() {
|
||||||
|
|||||||
@@ -16,343 +16,37 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.cfg.Label;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class Pseudocode {
|
public interface Pseudocode {
|
||||||
|
@NotNull
|
||||||
public class PseudocodeLabel implements Label {
|
JetElement getCorrespondingElement();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<Instruction> getInstructions() {
|
Set<LocalDeclarationInstruction> getLocalDeclarations();
|
||||||
return instructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated //for tests only
|
|
||||||
@NotNull
|
|
||||||
public List<Instruction> getMutableInstructionList() {
|
|
||||||
return mutableInstructionList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<Instruction> getDeadInstructions() {
|
List<Instruction> getInstructions();
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public SubroutineExitInstruction getExitInstruction() {
|
List<Instruction> getReversedInstructions();
|
||||||
return exitInstruction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public SubroutineSinkInstruction getSinkInstruction() {
|
List<Instruction> getDeadInstructions();
|
||||||
return sinkInstruction;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public SubroutineEnterInstruction getEnterInstruction() {
|
SubroutineExitInstruction getExitInstruction();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Set<Instruction> prepareAllowedDeadInstructions() {
|
SubroutineSinkInstruction getSinkInstruction();
|
||||||
Set<Instruction> allowedDeadStartInstructions = Sets.newHashSet();
|
|
||||||
for (PseudocodeLabel allowedDeadLabel : allowedDeadLabels) {
|
|
||||||
Instruction allowedDeadInstruction = getJumpTarget(allowedDeadLabel);
|
|
||||||
if (((InstructionImpl)allowedDeadInstruction).isDead()) {
|
|
||||||
allowedDeadStartInstructions.add(allowedDeadInstruction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allowedDeadStartInstructions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Set<Instruction> prepareStopAllowedDeadInstructions() {
|
SubroutineEnterInstruction getEnterInstruction();
|
||||||
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,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-4
@@ -46,10 +46,8 @@ public class SubroutineExitInstruction extends InstructionImpl {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<Instruction> getNextInstructions() {
|
public Collection<Instruction> getNextInstructions() {
|
||||||
if (sinkInstruction != null) {
|
assert sinkInstruction != null;
|
||||||
return Collections.<Instruction>singleton(sinkInstruction);
|
return Collections.<Instruction>singleton(sinkInstruction);
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final ClassDescriptorImpl initialize(boolean sealed,
|
public final ClassDescriptorImpl initialize(boolean sealed,
|
||||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||||
@NotNull Collection<JetType> supertypes,
|
@NotNull Collection<JetType> supertypes,
|
||||||
@NotNull JetScope memberDeclarations,
|
@NotNull JetScope memberDeclarations,
|
||||||
@NotNull Set<ConstructorDescriptor> constructors,
|
@NotNull Set<ConstructorDescriptor> constructors,
|
||||||
@@ -57,7 +57,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final ClassDescriptorImpl initialize(boolean sealed,
|
public final ClassDescriptorImpl initialize(boolean sealed,
|
||||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||||
@NotNull Collection<JetType> supertypes,
|
@NotNull Collection<JetType> supertypes,
|
||||||
@NotNull JetScope memberDeclarations,
|
@NotNull JetScope memberDeclarations,
|
||||||
@NotNull Set<ConstructorDescriptor> constructors,
|
@NotNull Set<ConstructorDescriptor> constructors,
|
||||||
|
|||||||
+2
-2
@@ -77,12 +77,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
|
|||||||
protected FunctionDescriptorImpl initialize(
|
protected FunctionDescriptorImpl initialize(
|
||||||
@Nullable JetType receiverType,
|
@Nullable JetType receiverType,
|
||||||
@NotNull ReceiverDescriptor expectedThisObject,
|
@NotNull ReceiverDescriptor expectedThisObject,
|
||||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||||
@Nullable JetType unsubstitutedReturnType,
|
@Nullable JetType unsubstitutedReturnType,
|
||||||
@Nullable Modality modality,
|
@Nullable Modality modality,
|
||||||
@NotNull Visibility visibility) {
|
@NotNull Visibility visibility) {
|
||||||
this.typeParameters = typeParameters;
|
this.typeParameters = Lists.newArrayList(typeParameters);
|
||||||
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
|
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
|
||||||
this.unsubstitutedReturnType = unsubstitutedReturnType;
|
this.unsubstitutedReturnType = unsubstitutedReturnType;
|
||||||
this.modality = modality;
|
this.modality = modality;
|
||||||
|
|||||||
+1
-1
@@ -126,7 +126,7 @@ public class FunctionDescriptorUtil {
|
|||||||
assert JetStandardClasses.isFunctionType(functionType);
|
assert JetStandardClasses.isFunctionType(functionType);
|
||||||
functionDescriptor.initialize(JetStandardClasses.getReceiverType(functionType),
|
functionDescriptor.initialize(JetStandardClasses.getReceiverType(functionType),
|
||||||
expectedThisObject,
|
expectedThisObject,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptorImpl>emptyList(),
|
||||||
JetStandardClasses.getValueParameters(functionDescriptor, functionType),
|
JetStandardClasses.getValueParameters(functionDescriptor, functionType),
|
||||||
JetStandardClasses.getReturnTypeFromFunctionType(functionType),
|
JetStandardClasses.getReturnTypeFromFunctionType(functionType),
|
||||||
modality,
|
modality,
|
||||||
|
|||||||
@@ -112,17 +112,17 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
setType(outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
|
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
|
ReceiverDescriptor receiver = receiverType == null
|
||||||
? NO_RECEIVER
|
? NO_RECEIVER
|
||||||
: new ExtensionReceiver(this, receiverType);
|
: new ExtensionReceiver(this, receiverType);
|
||||||
setType(outType, typeParameters, expectedThisObject, receiver);
|
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);
|
setOutType(outType);
|
||||||
|
|
||||||
this.typeParameters = typeParameters;
|
this.typeParameters = Lists.newArrayList(typeParameters);
|
||||||
|
|
||||||
this.receiver = receiver;
|
this.receiver = receiver;
|
||||||
this.expectedThisObject = expectedThisObject;
|
this.expectedThisObject = expectedThisObject;
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
|
|||||||
public SimpleFunctionDescriptorImpl initialize(
|
public SimpleFunctionDescriptorImpl initialize(
|
||||||
@Nullable JetType receiverType,
|
@Nullable JetType receiverType,
|
||||||
@NotNull ReceiverDescriptor expectedThisObject,
|
@NotNull ReceiverDescriptor expectedThisObject,
|
||||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
@NotNull List<? extends TypeParameterDescriptor> typeParameters,
|
||||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||||
@Nullable JetType unsubstitutedReturnType,
|
@Nullable JetType unsubstitutedReturnType,
|
||||||
@Nullable Modality modality,
|
@Nullable Modality modality,
|
||||||
|
|||||||
+15
-221
@@ -16,251 +16,45 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.LazyScopeAdapter;
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
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;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class TypeParameterDescriptor extends DeclarationDescriptorImpl implements ClassifierDescriptor {
|
public interface TypeParameterDescriptor extends ClassifierDescriptor {
|
||||||
public static TypeParameterDescriptor createWithDefaultBound(
|
boolean isReified();
|
||||||
@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 static TypeParameterDescriptor createForFurtherModification(
|
Variance getVariance();
|
||||||
@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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<JetType> getUpperBounds() {
|
Set<JetType> getUpperBounds();
|
||||||
checkInitialized();
|
|
||||||
return upperBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType getUpperBoundsAsType() {
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<JetType> getLowerBounds() {
|
Set<JetType> getLowerBounds();
|
||||||
//checkInitialized();
|
|
||||||
return Collections.singleton(JetStandardClasses.getNothingType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetType getLowerBoundsAsType() {
|
JetType getLowerBoundsAsType();
|
||||||
checkInitialized();
|
|
||||||
return JetStandardClasses.getNothingType();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public TypeConstructor getTypeConstructor() {
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@Deprecated // Use the static method TypeParameterDescriptor.substitute()
|
@Deprecated // Use the static method TypeParameterDescriptor.substitute()
|
||||||
public TypeParameterDescriptor substitute(TypeSubstitutor substitutor) {
|
TypeParameterDescriptor substitute(TypeSubstitutor substitutor);
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
int getIndex();
|
||||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
|
||||||
checkInitialized();
|
|
||||||
return visitor.visitTypeParameterDescriptor(this, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
TypeParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+275
@@ -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;
|
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.PsiElement;
|
||||||
import com.intellij.psi.PsiElementVisitor;
|
import com.intellij.psi.PsiElementVisitor;
|
||||||
import com.intellij.psi.PsiErrorElement;
|
import com.intellij.psi.PsiErrorElement;
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
|
||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
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.PropertyAccessorDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
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 {
|
public class ControlFlowAnalyzer {
|
||||||
private TopDownAnalysisParameters topDownAnalysisParameters;
|
private TopDownAnalysisParameters topDownAnalysisParameters;
|
||||||
private BindingTrace trace;
|
private BindingTrace trace;
|
||||||
private JetControlFlowDataTraceFactory flowDataTraceFactory;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
|
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
|
||||||
@@ -49,11 +47,6 @@ public class ControlFlowAnalyzer {
|
|||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
|
||||||
public void setFlowDataTraceFactory(JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
|
||||||
this.flowDataTraceFactory = flowDataTraceFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
|
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
|
||||||
for (JetClass aClass : bodiesResolveContext.getClasses().keySet()) {
|
for (JetClass aClass : bodiesResolveContext.getClasses().keySet()) {
|
||||||
if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue;
|
if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue;
|
||||||
@@ -86,8 +79,8 @@ public class ControlFlowAnalyzer {
|
|||||||
|
|
||||||
private void checkClassOrObject(JetClassOrObject klass) {
|
private void checkClassOrObject(JetClassOrObject klass) {
|
||||||
// A pseudocode of class initialization corresponds to a class
|
// A pseudocode of class initialization corresponds to a class
|
||||||
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, (JetExpression) klass, flowDataTraceFactory, trace);
|
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, trace);
|
||||||
flowInformationProvider.markUninitializedVariables((JetElement) klass, topDownAnalysisParameters.isDeclaredLocally());
|
flowInformationProvider.markUninitializedVariables(topDownAnalysisParameters.isDeclaredLocally());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) {
|
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) {
|
||||||
@@ -105,16 +98,16 @@ public class ControlFlowAnalyzer {
|
|||||||
|
|
||||||
JetExpression bodyExpression = function.getBodyExpression();
|
JetExpression bodyExpression = function.getBodyExpression();
|
||||||
if (bodyExpression == null) return;
|
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')
|
// Property accessor is checked through initialization of a class check (at 'checkClassOrObject')
|
||||||
boolean isPropertyAccessor = function instanceof JetPropertyAccessor;
|
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();
|
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (JetTypeParameter typeParameter : classElement.getTypeParameters()) {
|
for (JetTypeParameter typeParameter : classElement.getTypeParameters()) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
|
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
descriptor,
|
descriptor,
|
||||||
annotationResolver.createAnnotationStubs(typeParameter.getModifierList(), trace),
|
annotationResolver.createAnnotationStubs(typeParameter.getModifierList(), trace),
|
||||||
!typeParameter.hasModifier(JetTokens.ERASED_KEYWORD),
|
!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");
|
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function descriptor header scope");
|
||||||
innerScope.addLabeledDeclaration(functionDescriptor);
|
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);
|
innerScope.changeLockLevel(WritableScope.LockLevel.BOTH);
|
||||||
resolveGenericBounds(function, innerScope, typeParameterDescriptors, trace);
|
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) {
|
public List<TypeParameterDescriptorImpl> resolveTypeParameters(DeclarationDescriptor containingDescriptor, WritableScope extensibleScope, List<JetTypeParameter> typeParameters, BindingTrace trace) {
|
||||||
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>();
|
List<TypeParameterDescriptorImpl> result = new ArrayList<TypeParameterDescriptorImpl>();
|
||||||
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
|
||||||
JetTypeParameter typeParameter = typeParameters.get(i);
|
JetTypeParameter typeParameter = typeParameters.get(i);
|
||||||
result.add(resolveTypeParameter(containingDescriptor, extensibleScope, typeParameter, i, trace));
|
result.add(resolveTypeParameter(containingDescriptor, extensibleScope, typeParameter, i, trace));
|
||||||
@@ -316,12 +316,12 @@ public class DescriptorResolver {
|
|||||||
return result;
|
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();
|
// JetTypeReference extendsBound = typeParameter.getExtendsBound();
|
||||||
// JetType bound = extendsBound == null
|
// JetType bound = extendsBound == null
|
||||||
// ? JetStandardClasses.getDefaultBound()
|
// ? JetStandardClasses.getDefaultBound()
|
||||||
// : typeResolver.resolveType(extensibleScope, extendsBound);
|
// : typeResolver.resolveType(extensibleScope, extendsBound);
|
||||||
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
|
TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
containingDescriptor,
|
containingDescriptor,
|
||||||
annotationResolver.createAnnotationStubs(typeParameter.getModifierList(), trace),
|
annotationResolver.createAnnotationStubs(typeParameter.getModifierList(), trace),
|
||||||
!typeParameter.hasModifier(JetTokens.ERASED_KEYWORD),
|
!typeParameter.hasModifier(JetTokens.ERASED_KEYWORD),
|
||||||
@@ -346,14 +346,15 @@ public class DescriptorResolver {
|
|||||||
isClassObjectConstraint = classObjectConstraint;
|
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<UpperBoundCheckerTask> deferredUpperBoundCheckerTasks = Lists.newArrayList();
|
||||||
|
|
||||||
List<JetTypeParameter> typeParameters = declaration.getTypeParameters();
|
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++) {
|
for (int i = 0; i < typeParameters.size(); i++) {
|
||||||
JetTypeParameter jetTypeParameter = typeParameters.get(i);
|
JetTypeParameter jetTypeParameter = typeParameters.get(i);
|
||||||
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
|
TypeParameterDescriptorImpl typeParameterDescriptor = parameters.get(i);
|
||||||
|
|
||||||
parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
|
parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
|
||||||
|
|
||||||
@@ -373,7 +374,7 @@ public class DescriptorResolver {
|
|||||||
if (referencedName == null) {
|
if (referencedName == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TypeParameterDescriptor typeParameterDescriptor = parameterByName.get(referencedName);
|
TypeParameterDescriptorImpl typeParameterDescriptor = parameterByName.get(referencedName);
|
||||||
JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
|
JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
|
||||||
JetType bound = null;
|
JetType bound = null;
|
||||||
if (boundTypeReference != null) {
|
if (boundTypeReference != null) {
|
||||||
@@ -405,7 +406,7 @@ public class DescriptorResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TypeParameterDescriptor parameter : parameters) {
|
for (TypeParameterDescriptorImpl parameter : parameters) {
|
||||||
parameter.addDefaultUpperBound();
|
parameter.addDefaultUpperBound();
|
||||||
|
|
||||||
parameter.setInitialized();
|
parameter.setInitialized();
|
||||||
@@ -551,7 +552,7 @@ public class DescriptorResolver {
|
|||||||
return variableDescriptor;
|
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) {
|
@NotNull ReceiverDescriptor receiver, BindingTrace trace) {
|
||||||
WritableScopeImpl result = new WritableScopeImpl(outerScope, outerScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace)).setDebugName("Property declaration inner scope");
|
WritableScopeImpl result = new WritableScopeImpl(outerScope, outerScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace)).setDebugName("Property declaration inner scope");
|
||||||
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
|
||||||
@@ -583,7 +584,7 @@ public class DescriptorResolver {
|
|||||||
CallableMemberDescriptor.Kind.DECLARATION
|
CallableMemberDescriptor.Kind.DECLARATION
|
||||||
);
|
);
|
||||||
|
|
||||||
List<TypeParameterDescriptor> typeParameterDescriptors;
|
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
|
||||||
JetScope scopeWithTypeParameters;
|
JetScope scopeWithTypeParameters;
|
||||||
JetType receiverType = null;
|
JetType receiverType = null;
|
||||||
|
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ public class DescriptorUtils {
|
|||||||
ClassDescriptor clazz = (ClassDescriptor) classifier;
|
ClassDescriptor clazz = (ClassDescriptor) classifier;
|
||||||
return clazz.getKind() == ClassKind.OBJECT || clazz.getKind() == ClassKind.ENUM_ENTRY;
|
return clazz.getKind() == ClassKind.OBJECT || clazz.getKind() == ClassKind.ENUM_ENTRY;
|
||||||
}
|
}
|
||||||
else if (classifier instanceof TypeParameterDescriptor) {
|
else if (classifier instanceof TypeParameterDescriptorImpl) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ public class OverridingUtil {
|
|||||||
if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
|
if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
else if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
else if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptorImpl) {
|
||||||
return ((TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor()).getUpperBoundsAsType();
|
return ((TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor()).getUpperBoundsAsType();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import com.intellij.psi.PsiFile;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic;
|
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic;
|
||||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
@@ -188,7 +187,7 @@ public class TopDownAnalyzer {
|
|||||||
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(Predicates.<PsiFile>alwaysFalse(), true, false);
|
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(Predicates.<PsiFile>alwaysFalse(), true, false);
|
||||||
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
|
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
|
||||||
project, topDownAnalysisParameters, new ObservableBindingTrace(trace),
|
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);
|
injector.getTopDownAnalyzer().doProcessStandardLibraryNamespace(outerScope, standardLibraryNamespace, files);
|
||||||
}
|
}
|
||||||
@@ -220,7 +219,7 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
|
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
|
||||||
project, topDownAnalysisParameters, new ObservableBindingTrace(trace), moduleDescriptor,
|
project, topDownAnalysisParameters, new ObservableBindingTrace(trace), moduleDescriptor,
|
||||||
JetControlFlowDataTraceFactory.EMPTY, ModuleConfiguration.EMPTY);
|
ModuleConfiguration.EMPTY);
|
||||||
|
|
||||||
injector.getTopDownAnalyzer().doProcess(outerScope, new NamespaceLikeBuilder() {
|
injector.getTopDownAnalyzer().doProcess(outerScope, new NamespaceLikeBuilder() {
|
||||||
|
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ public class TypeHierarchyResolver {
|
|||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
MutableClassDescriptor descriptor = entry.getValue();
|
MutableClassDescriptor descriptor = entry.getValue();
|
||||||
descriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(),
|
descriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(),
|
||||||
descriptor.getTypeConstructor().getParameters(), trace);
|
(List) descriptor.getTypeConstructor().getParameters(), trace);
|
||||||
descriptorResolver.resolveSupertypes(jetClass, descriptor, trace);
|
descriptorResolver.resolveSupertypes(jetClass, descriptor, trace);
|
||||||
}
|
}
|
||||||
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
|
||||||
@@ -528,7 +528,7 @@ public class TypeHierarchyResolver {
|
|||||||
if (projections.size() > 1) {
|
if (projections.size() > 1) {
|
||||||
TypeConstructor typeConstructor = entry.getKey();
|
TypeConstructor typeConstructor = entry.getKey();
|
||||||
DeclarationDescriptor declarationDescriptor = typeConstructor.getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = typeConstructor.getDeclarationDescriptor();
|
||||||
assert declarationDescriptor instanceof TypeParameterDescriptor : declarationDescriptor;
|
assert declarationDescriptor instanceof TypeParameterDescriptorImpl : declarationDescriptor;
|
||||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor;
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor;
|
||||||
|
|
||||||
// Immediate arguments of supertypes cannot be projected
|
// Immediate arguments of supertypes cannot be projected
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class TypeResolver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classifierDescriptor instanceof TypeParameterDescriptor) {
|
if (classifierDescriptor instanceof TypeParameterDescriptorImpl) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
|
||||||
|
|
||||||
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, typeParameterDescriptor);
|
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, typeParameterDescriptor);
|
||||||
|
|||||||
+3
-2
@@ -21,6 +21,7 @@ import com.google.common.collect.Sets;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
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.*;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
||||||
@@ -88,7 +89,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private TypeValue getTypeValueFor(@NotNull JetType type) {
|
private TypeValue getTypeValueFor(@NotNull JetType type) {
|
||||||
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
if (declarationDescriptor instanceof TypeParameterDescriptorImpl) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor;
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor;
|
||||||
// Checking that this is not a T?, but exactly T
|
// Checking that this is not a T?, but exactly T
|
||||||
if (typeParameterDescriptor.getDefaultType().isNullable() == type.isNullable()) {
|
if (typeParameterDescriptor.getDefaultType().isNullable() == type.isNullable()) {
|
||||||
@@ -488,7 +489,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem {
|
|||||||
@Override
|
@Override
|
||||||
public TypeProjection get(TypeConstructor key) {
|
public TypeProjection get(TypeConstructor key) {
|
||||||
DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor();
|
||||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
if (declarationDescriptor instanceof TypeParameterDescriptorImpl) {
|
||||||
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
|
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
|
||||||
|
|
||||||
if (!unknownTypes.containsKey(descriptor)) return null;
|
if (!unknownTypes.containsKey(descriptor)) return null;
|
||||||
|
|||||||
+12
-13
@@ -14,23 +14,22 @@
|
|||||||
* limitations under the License.
|
* 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.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 {
|
public interface DependencyClassByQualifiedNameResolver {
|
||||||
JetControlFlowDataTraceFactory EMPTY = new JetControlFlowDataTraceFactory() {
|
|
||||||
@NotNull
|
@Nullable
|
||||||
@Override
|
ClassDescriptor resolveClass(@NotNull FqName qualifiedName);
|
||||||
public JetPseudocodeTrace createTrace(JetElement element) {
|
@Nullable
|
||||||
return JetPseudocodeTrace.EMPTY;
|
NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
JetPseudocodeTrace createTrace(JetElement element);
|
|
||||||
}
|
}
|
||||||
+37
@@ -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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -58,7 +59,7 @@ public class DescriptorSubstitutor {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (TypeParameterDescriptor descriptor : typeParameters) {
|
for (TypeParameterDescriptor descriptor : typeParameters) {
|
||||||
TypeParameterDescriptor substituted = TypeParameterDescriptor.createForFurtherModification(
|
TypeParameterDescriptorImpl substituted = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
newContainingDeclaration,
|
newContainingDeclaration,
|
||||||
descriptor.getAnnotations(),
|
descriptor.getAnnotations(),
|
||||||
descriptor.isReified(),
|
descriptor.isReified(),
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class ErrorUtils {
|
|||||||
function.initialize(
|
function.initialize(
|
||||||
null,
|
null,
|
||||||
ReceiverDescriptor.NO_RECEIVER,
|
ReceiverDescriptor.NO_RECEIVER,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(), // TODO
|
Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
|
||||||
Collections.<ValueParameterDescriptor>emptyList(), // TODO
|
Collections.<ValueParameterDescriptor>emptyList(), // TODO
|
||||||
createErrorType("<ERROR FUNCTION RETURN TYPE>"),
|
createErrorType("<ERROR FUNCTION RETURN TYPE>"),
|
||||||
Modality.OPEN,
|
Modality.OPEN,
|
||||||
@@ -223,7 +223,7 @@ public class ErrorUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static JetType createErrorTypeWithCustomDebugName(JetScope memberScope, String debugName) {
|
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) {
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
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.lang.types.lang.JetStandardClasses;
|
||||||
import org.jetbrains.jet.util.CommonSuppliers;
|
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) {
|
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++) {
|
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
||||||
TypeParameterDescriptor parameter = parameters.get(i);
|
TypeParameterDescriptor parameter = parameters.get(i);
|
||||||
TypeProjection value = contextArguments.get(i);
|
TypeProjection value = contextArguments.get(i);
|
||||||
@@ -108,7 +112,7 @@ public class SubstitutionUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasUnsubstitutedTypeParameters(JetType type) {
|
public static boolean hasUnsubstitutedTypeParameters(JetType type) {
|
||||||
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
|
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptorImpl) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class TypeConstructorImpl extends AnnotatedImpl implements TypeConstructo
|
|||||||
@NotNull List<AnnotationDescriptor> annotations,
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
boolean sealed,
|
boolean sealed,
|
||||||
@NotNull String debugName,
|
@NotNull String debugName,
|
||||||
@NotNull List<TypeParameterDescriptor> parameters,
|
@NotNull List<? extends TypeParameterDescriptor> parameters,
|
||||||
@NotNull Collection<JetType> supertypes) {
|
@NotNull Collection<JetType> supertypes) {
|
||||||
super(annotations);
|
super(annotations);
|
||||||
this.classifierDescriptor = classifierDescriptor;
|
this.classifierDescriptor = classifierDescriptor;
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import com.google.common.collect.Sets;
|
|||||||
import com.intellij.util.Processor;
|
import com.intellij.util.Processor;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
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.annotations.AnnotationDescriptor;
|
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.ConstraintResolutionListener;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
|
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) {
|
private static void processAllTypeParameters(JetType type, Variance howThiTypeIsUsed, Processor<TypeParameterUsage> result) {
|
||||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||||
if (descriptor instanceof TypeParameterDescriptor) {
|
if (descriptor instanceof TypeParameterDescriptorImpl) {
|
||||||
result.process(new TypeParameterUsage((TypeParameterDescriptor)descriptor, howThiTypeIsUsed));
|
result.process(new TypeParameterUsage((TypeParameterDescriptor)descriptor, howThiTypeIsUsed));
|
||||||
}
|
}
|
||||||
for (TypeProjection projection : type.getArguments()) {
|
for (TypeProjection projection : type.getArguments()) {
|
||||||
|
|||||||
+1
-1
@@ -149,7 +149,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
functionDescriptor.initialize(effectiveReceiverType,
|
functionDescriptor.initialize(effectiveReceiverType,
|
||||||
NO_RECEIVER,
|
NO_RECEIVER,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptorImpl>emptyList(),
|
||||||
valueParameterDescriptors,
|
valueParameterDescriptors,
|
||||||
/*unsubstitutedReturnType = */ null,
|
/*unsubstitutedReturnType = */ null,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
|
|||||||
@@ -157,13 +157,13 @@ public class JetStandardClasses {
|
|||||||
Name.identifier("Tuple" + i));
|
Name.identifier("Tuple" + i));
|
||||||
WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, RedeclarationHandler.THROW_EXCEPTION);
|
WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, RedeclarationHandler.THROW_EXCEPTION);
|
||||||
for (int j = 0; j < i; j++) {
|
for (int j = 0; j < i; j++) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createWithDefaultBound(
|
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
true, Variance.OUT_VARIANCE, Name.identifier("T" + (j + 1)), j);
|
true, Variance.OUT_VARIANCE, Name.identifier("T" + (j + 1)), j);
|
||||||
parameters.add(typeParameterDescriptor);
|
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 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);
|
PropertyGetterDescriptor getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC, false, true, CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
getterDescriptor.initialize(typeParameterDescriptor.getDefaultType());
|
getterDescriptor.initialize(typeParameterDescriptor.getDefaultType());
|
||||||
propertyDescriptor.initialize(getterDescriptor, null);
|
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);
|
SimpleFunctionDescriptorImpl invokeWithReceiver = new SimpleFunctionDescriptorImpl(receiverFunction, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("invoke"), CallableMemberDescriptor.Kind.DECLARATION);
|
||||||
WritableScope scopeForInvokeWithReceiver = createScopeForInvokeFunction(receiverFunction, invokeWithReceiver);
|
WritableScope scopeForInvokeWithReceiver = createScopeForInvokeFunction(receiverFunction, invokeWithReceiver);
|
||||||
List<TypeParameterDescriptor> parameters = createTypeParameters(i, receiverFunction);
|
List<TypeParameterDescriptor> parameters = createTypeParameters(i, receiverFunction);
|
||||||
parameters.add(0, TypeParameterDescriptor.createWithDefaultBound(
|
parameters.add(0, TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||||
receiverFunction,
|
receiverFunction,
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
true, Variance.IN_VARIANCE, Name.identifier("T"), 0));
|
true, Variance.IN_VARIANCE, Name.identifier("T"), 0));
|
||||||
@@ -238,12 +238,12 @@ public class JetStandardClasses {
|
|||||||
private static List<TypeParameterDescriptor> createTypeParameters(int parameterCount, ClassDescriptorImpl function) {
|
private static List<TypeParameterDescriptor> createTypeParameters(int parameterCount, ClassDescriptorImpl function) {
|
||||||
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>();
|
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>();
|
||||||
for (int j = 1; j <= parameterCount; j++) {
|
for (int j = 1; j <= parameterCount; j++) {
|
||||||
parameters.add(TypeParameterDescriptor.createWithDefaultBound(
|
parameters.add(TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||||
function,
|
function,
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
true, Variance.IN_VARIANCE, Name.identifier("P" + j), j));
|
true, Variance.IN_VARIANCE, Name.identifier("P" + j), j));
|
||||||
}
|
}
|
||||||
parameters.add(TypeParameterDescriptor.createWithDefaultBound(
|
parameters.add(TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||||
function,
|
function,
|
||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
true, Variance.OUT_VARIANCE, Name.identifier("R"), parameterCount + 1));
|
true, Variance.OUT_VARIANCE, Name.identifier("R"), parameterCount + 1));
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
|
|||||||
|
|
||||||
Object typeNameObject;
|
Object typeNameObject;
|
||||||
|
|
||||||
if (cd == null || cd instanceof TypeParameterDescriptor) {
|
if (cd == null || cd instanceof TypeParameterDescriptorImpl) {
|
||||||
typeNameObject = type.getConstructor();
|
typeNameObject = type.getConstructor();
|
||||||
}
|
}
|
||||||
else {
|
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 ==
|
== AnonymousInitializers ==
|
||||||
class AnonymousInitializers() {
|
class AnonymousInitializers() {
|
||||||
val k = 34
|
val k = 34
|
||||||
@@ -46,16 +33,29 @@ l2:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w($i)]
|
<END> NEXT:[<SINK>] PREV:[w($i)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[d(get() = 20), <END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d(get() = 20)]
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(20)] PREV:[]
|
<START> NEXT:[r(20)] PREV:[]
|
||||||
r(20) NEXT:[<END>] PREV:[<START>]
|
r(20) NEXT:[<END>] PREV:[<START>]
|
||||||
l4:
|
l4:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(20)]
|
<END> NEXT:[<SINK>] PREV:[r(20)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(a[10])]
|
<END> NEXT:[<SINK>] PREV:[w(a[10])]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[v(var x : Int;)]
|
<END> NEXT:[<SINK>] PREV:[v(var x : Int;)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== assignments ==
|
== assignments ==
|
||||||
fun assignments() : Unit {
|
fun assignments() : Unit {
|
||||||
@@ -72,7 +72,7 @@ l5:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(t.x)]
|
<END> NEXT:[<SINK>] PREV:[w(t.x)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -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 ==
|
== f ==
|
||||||
fun f(a : Boolean) : Unit {
|
fun f(a : Boolean) : Unit {
|
||||||
1
|
1
|
||||||
@@ -78,18 +65,31 @@ l6:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(a || false)]
|
<END> NEXT:[<SINK>] PREV:[r(a || false)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[d({1}), <END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d({1})]
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(1)] PREV:[]
|
<START> NEXT:[r(1)] PREV:[]
|
||||||
r(1) NEXT:[<END>] PREV:[<START>]
|
r(1) NEXT:[<END>] PREV:[<START>]
|
||||||
l4:
|
l4:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(1)]
|
<END> NEXT:[<SINK>] PREV:[r(1)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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 ==
|
== foo ==
|
||||||
fun foo(a : Boolean, b : Int) : Unit {}
|
fun foo(a : Boolean, b : Int) : Unit {}
|
||||||
@@ -104,9 +104,9 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== genfun ==
|
== genfun ==
|
||||||
fun genfun<T>() : Unit {}
|
fun genfun<T>() : Unit {}
|
||||||
@@ -117,9 +117,9 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== flfun ==
|
== flfun ==
|
||||||
fun flfun(f : () -> Any) : Unit {}
|
fun flfun(f : () -> Any) : Unit {}
|
||||||
@@ -132,7 +132,7 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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>]
|
||||||
|
=====================
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun test() {
|
||||||
|
throw Exception()
|
||||||
|
test()
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[]
|
<END> NEXT:[<SINK>] PREV:[]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[jmp(error)]
|
<ERROR> NEXT:[<SINK>] PREV:[jmp(error)]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ l1:
|
|||||||
l3:
|
l3:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(2)]
|
<END> NEXT:[<SINK>] PREV:[r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t2 ==
|
== t2 ==
|
||||||
fun t2() {
|
fun t2() {
|
||||||
@@ -65,36 +65,9 @@ l1:
|
|||||||
l5:
|
l5:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret l1, r(2)]
|
<END> NEXT:[<SINK>] PREV:[ret l1, r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <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>]
|
|
||||||
=====================
|
=====================
|
||||||
== t3 ==
|
== t3 ==
|
||||||
fun t3() {
|
fun t3() {
|
||||||
@@ -141,9 +114,9 @@ l1:
|
|||||||
l8:
|
l8:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(2)]
|
<END> NEXT:[<SINK>] PREV:[r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[d({ () => if (2 > 3) { retur..), <END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d({ () => if (2 > 3) { retur..)]
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(())] PREV:[]
|
<START> NEXT:[r(())] PREV:[]
|
||||||
r(()) NEXT:[r(2)] PREV:[<START>]
|
r(()) NEXT:[r(2)] PREV:[<START>]
|
||||||
@@ -160,54 +133,36 @@ l4:
|
|||||||
l6:
|
l6:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== anonymous_1 ==
|
== anonymous_0 ==
|
||||||
{ () =>
|
{ () =>
|
||||||
try {
|
if (2 > 3) {
|
||||||
1
|
return@
|
||||||
if (2 > 3) {
|
}
|
||||||
return@
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
2
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
---------------------
|
---------------------
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(())] PREV:[]
|
<START> NEXT:[r(())] PREV:[]
|
||||||
r(()) NEXT:[r(try { 1 if (2 > 3) { retur..)] PREV:[<START>]
|
r(()) NEXT:[r(2)] PREV:[<START>]
|
||||||
r(try {
|
r(2) NEXT:[r(3)] PREV:[r(())]
|
||||||
1
|
r(3) NEXT:[r(>)] PREV:[r(2)]
|
||||||
if (2 > 3) {
|
r(>) NEXT:[r(2 > 3)] PREV:[r(3)]
|
||||||
return@
|
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
|
||||||
}
|
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
|
||||||
} finally {
|
ret l4 NEXT:[<END>] PREV:[jf(l5)]
|
||||||
2
|
- jmp(l6) NEXT:[<END>] PREV:[]
|
||||||
}) 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:
|
l5:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
|
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
|
||||||
l6:
|
|
||||||
l7:
|
|
||||||
r(2) NEXT:[<END>] PREV:[read (Unit)]
|
|
||||||
l4:
|
l4:
|
||||||
l8:
|
l6:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
|
<END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t4 ==
|
== t4 ==
|
||||||
fun t4() {
|
fun t4() {
|
||||||
@@ -250,9 +205,9 @@ l2:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[r({ () => try { 1 if (2 > 3)..)]
|
<END> NEXT:[<SINK>] PREV:[r({ () => try { 1 if (2 > 3)..)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[d({ () => try { 1 if (2 > 3)..), <END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d({ () => try { 1 if (2 > 3)..)]
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(())] PREV:[]
|
<START> NEXT:[r(())] PREV:[]
|
||||||
r(()) NEXT:[r(try { 1 if (2 > 3) { retur..)] PREV:[<START>]
|
r(()) NEXT:[r(try { 1 if (2 > 3) { retur..)] PREV:[<START>]
|
||||||
@@ -282,9 +237,54 @@ l4:
|
|||||||
l8:
|
l8:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
|
<END> NEXT:[<SINK>] PREV:[ret l4, r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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 ==
|
== t5 ==
|
||||||
fun t5() {
|
fun t5() {
|
||||||
@@ -346,9 +346,9 @@ l3:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t6 ==
|
== t6 ==
|
||||||
fun t6() {
|
fun t6() {
|
||||||
@@ -410,9 +410,9 @@ l1:
|
|||||||
l9:
|
l9:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(2)]
|
<END> NEXT:[<SINK>] PREV:[r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t7 ==
|
== t7 ==
|
||||||
fun t7() {
|
fun t7() {
|
||||||
@@ -471,9 +471,9 @@ l1:
|
|||||||
l9:
|
l9:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(2)]
|
<END> NEXT:[<SINK>] PREV:[r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t8 ==
|
== t8 ==
|
||||||
fun t8(a : Int) {
|
fun t8(a : Int) {
|
||||||
@@ -542,9 +542,9 @@ l2:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t9 ==
|
== t9 ==
|
||||||
fun t9(a : Int) {
|
fun t9(a : Int) {
|
||||||
@@ -613,9 +613,9 @@ l1:
|
|||||||
l9:
|
l9:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(2)]
|
<END> NEXT:[<SINK>] PREV:[r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t10 ==
|
== t10 ==
|
||||||
fun t10(a : Int) {
|
fun t10(a : Int) {
|
||||||
@@ -681,9 +681,9 @@ l1:
|
|||||||
l9:
|
l9:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(2)]
|
<END> NEXT:[<SINK>] PREV:[r(2)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t11 ==
|
== t11 ==
|
||||||
fun t11() {
|
fun t11() {
|
||||||
@@ -714,9 +714,9 @@ l1:
|
|||||||
l3:
|
l3:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*) l1]
|
<END> NEXT:[<SINK>] PREV:[ret(*) l1]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t12 ==
|
== t12 ==
|
||||||
fun t12() : Int {
|
fun t12() : Int {
|
||||||
@@ -749,9 +749,9 @@ l1:
|
|||||||
l3:
|
l3:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*) l1]
|
<END> NEXT:[<SINK>] PREV:[ret(*) l1]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t13 ==
|
== t13 ==
|
||||||
fun t13() : Int {
|
fun t13() : Int {
|
||||||
@@ -802,9 +802,9 @@ l1:
|
|||||||
l6:
|
l6:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(doSmth(3))]
|
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(doSmth(3))]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t14 ==
|
== t14 ==
|
||||||
fun t14() : Int {
|
fun t14() : Int {
|
||||||
@@ -843,9 +843,9 @@ l4:
|
|||||||
l6:
|
l6:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*) l1, jmp(l4)]
|
<END> NEXT:[<SINK>] PREV:[ret(*) l1, jmp(l4)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t15 ==
|
== t15 ==
|
||||||
fun t15() : Int {
|
fun t15() : Int {
|
||||||
@@ -898,9 +898,9 @@ l1:
|
|||||||
l6:
|
l6:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*) l1, ret(*) l1]
|
<END> NEXT:[<SINK>] PREV:[ret(*) l1, ret(*) l1]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t16 ==
|
== t16 ==
|
||||||
fun t16() : Int {
|
fun t16() : Int {
|
||||||
@@ -951,9 +951,9 @@ l1:
|
|||||||
l6:
|
l6:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(doSmth(3))]
|
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(doSmth(3))]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== doSmth ==
|
== doSmth ==
|
||||||
fun doSmth(i: Int) {
|
fun doSmth(i: Int) {
|
||||||
@@ -967,7 +967,7 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ l2:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== doSmth ==
|
== doSmth ==
|
||||||
fun doSmth(i: Int) {}
|
fun doSmth(i: Int) {}
|
||||||
@@ -44,7 +44,7 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ l5:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(doSmth(r))]
|
<END> NEXT:[<SINK>] PREV:[r(doSmth(r))]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== t2 ==
|
== t2 ==
|
||||||
fun t2(b: Boolean) {
|
fun t2(b: Boolean) {
|
||||||
@@ -92,9 +92,9 @@ l1:
|
|||||||
l5:
|
l5:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret l1, ret l1, read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[ret l1, ret l1, read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== doSmth ==
|
== doSmth ==
|
||||||
fun doSmth(s: String) {}
|
fun doSmth(s: String) {}
|
||||||
@@ -107,7 +107,7 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ l13:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(14)]
|
<END> NEXT:[<SINK>] PREV:[r(14)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -25,56 +25,9 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(a)]
|
<END> NEXT:[<SINK>] PREV:[w(a)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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:[] 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>]
|
|
||||||
=====================
|
=====================
|
||||||
== doSmth ==
|
== doSmth ==
|
||||||
fun doSmth(i: Int) {}
|
fun doSmth(i: Int) {}
|
||||||
@@ -87,9 +40,9 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== test1 ==
|
== test1 ==
|
||||||
fun test1() {
|
fun test1() {
|
||||||
@@ -122,9 +75,29 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(a)]
|
<END> NEXT:[<SINK>] PREV:[w(a)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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 ==
|
== test2 ==
|
||||||
fun test2() {
|
fun test2() {
|
||||||
@@ -152,25 +125,9 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(a)]
|
<END> NEXT:[<SINK>] PREV:[w(a)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <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>]
|
|
||||||
=====================
|
=====================
|
||||||
== test3 ==
|
== test3 ==
|
||||||
fun test3() {
|
fun test3() {
|
||||||
@@ -206,9 +163,9 @@ l2:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(a)]
|
<END> NEXT:[<SINK>] PREV:[w(a)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[d(fun inner_bar() { y = 10 }) , <END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d(fun inner_bar() { y = 10 }) ]
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(10)] PREV:[]
|
<START> NEXT:[r(10)] PREV:[]
|
||||||
r(10) NEXT:[w(y)] PREV:[<START>]
|
r(10) NEXT:[w(y)] PREV:[<START>]
|
||||||
@@ -216,12 +173,12 @@ l3:
|
|||||||
l4:
|
l4:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(y)]
|
<END> NEXT:[<SINK>] PREV:[w(y)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== ggg ==
|
== inner_bar ==
|
||||||
fun ggg() {
|
fun inner_bar() {
|
||||||
y = 10
|
y = 10
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
@@ -232,9 +189,9 @@ l3:
|
|||||||
l4:
|
l4:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(y)]
|
<END> NEXT:[<SINK>] PREV:[w(y)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== test4 ==
|
== test4 ==
|
||||||
fun test4() {
|
fun test4() {
|
||||||
@@ -285,9 +242,9 @@ l2:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(a)]
|
<END> NEXT:[<SINK>] PREV:[w(a)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[d(fun ggg() { y = 10 }) , <END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>, d(fun ggg() { y = 10 }) ]
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(10)] PREV:[]
|
<START> NEXT:[r(10)] PREV:[]
|
||||||
r(10) NEXT:[w(y)] PREV:[<START>]
|
r(10) NEXT:[w(y)] PREV:[<START>]
|
||||||
@@ -295,41 +252,25 @@ l3:
|
|||||||
l4:
|
l4:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(y)]
|
<END> NEXT:[<SINK>] PREV:[w(y)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== foo ==
|
== ggg ==
|
||||||
fun foo() {
|
fun ggg() {
|
||||||
x = 3
|
y = 10
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
l3:
|
l3:
|
||||||
<START> NEXT:[r(3)] PREV:[]
|
<START> NEXT:[r(10)] PREV:[]
|
||||||
r(3) NEXT:[w(x)] PREV:[<START>]
|
r(10) NEXT:[w(y)] PREV:[<START>]
|
||||||
w(x) NEXT:[<END>] PREV:[r(3)]
|
w(y) NEXT:[<END>] PREV:[r(10)]
|
||||||
l4:
|
l4:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(x)]
|
<END> NEXT:[<SINK>] PREV:[w(y)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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:[] PREV:[]
|
|
||||||
sink:
|
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
|
||||||
=====================
|
=====================
|
||||||
== test5 ==
|
== test5 ==
|
||||||
fun test5() {
|
fun test5() {
|
||||||
@@ -392,9 +333,9 @@ l5:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(a)]
|
<END> NEXT:[<SINK>] PREV:[w(a)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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:
|
l3:
|
||||||
<START> NEXT:[r(3)] PREV:[]
|
<START> NEXT:[r(3)] PREV:[]
|
||||||
r(3) NEXT:[w(x)] PREV:[<START>]
|
r(3) NEXT:[w(x)] PREV:[<START>]
|
||||||
@@ -402,9 +343,9 @@ l3:
|
|||||||
l4:
|
l4:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(x)]
|
<END> NEXT:[<SINK>] PREV:[w(x)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
l6:
|
l6:
|
||||||
<START> NEXT:[r(4)] PREV:[]
|
<START> NEXT:[r(4)] PREV:[]
|
||||||
r(4) NEXT:[w(x)] PREV:[<START>]
|
r(4) NEXT:[w(x)] PREV:[<START>]
|
||||||
@@ -412,28 +353,39 @@ l6:
|
|||||||
l7:
|
l7:
|
||||||
<END> NEXT:[<SINK>] PREV:[w(x)]
|
<END> NEXT:[<SINK>] PREV:[w(x)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== foo ==
|
== foo ==
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val b : Int = 1
|
x = 3
|
||||||
doSmth(b)
|
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
l0:
|
l3:
|
||||||
<START> NEXT:[v(val b : Int = 1)] PREV:[]
|
<START> NEXT:[r(3)] PREV:[]
|
||||||
v(val b : Int = 1) NEXT:[r(1)] PREV:[<START>]
|
r(3) NEXT:[w(x)] PREV:[<START>]
|
||||||
r(1) NEXT:[w(b)] PREV:[v(val b : Int = 1)]
|
w(x) NEXT:[<END>] PREV:[r(3)]
|
||||||
w(b) NEXT:[r(b)] PREV:[r(1)]
|
l4:
|
||||||
r(b) NEXT:[r(doSmth)] PREV:[w(b)]
|
<END> NEXT:[<SINK>] PREV:[w(x)]
|
||||||
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))]
|
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
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:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
== dowhile ==
|
== dowhile ==
|
||||||
fun dowhile() {
|
fun dowhile() {
|
||||||
@@ -53,7 +53,7 @@ l3:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret l1]
|
<END> NEXT:[<SINK>] PREV:[ret l1]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ l2:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(false || (return false))]
|
<END> NEXT:[<SINK>] PREV:[ret(*) l1, r(false || (return false))]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ l0:
|
|||||||
l1:
|
l1:
|
||||||
<END> NEXT:[<SINK>] PREV:[r(1)]
|
<END> NEXT:[<SINK>] PREV:[r(1)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[<SINK>] PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> NEXT:[] PREV:[<END>]
|
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -175,12 +175,12 @@ class B() {
|
|||||||
|
|
||||||
fun testFunctionLiterals() {
|
fun testFunctionLiterals() {
|
||||||
val <!UNUSED_VARIABLE!>endsWithVarDeclaration<!> : () -> Boolean = {
|
val <!UNUSED_VARIABLE!>endsWithVarDeclaration<!> : () -> Boolean = {
|
||||||
<!EXPECTED_TYPE_MISMATCH!>val x = 2<!>
|
<!EXPECTED_TYPE_MISMATCH!>val <!UNUSED_VARIABLE!>x<!> = 2<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val <!UNUSED_VARIABLE!>endsWithAssignment<!> = { () : Int ->
|
val <!UNUSED_VARIABLE!>endsWithAssignment<!> = { () : Int ->
|
||||||
var x = 1
|
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
|
||||||
<!EXPECTED_TYPE_MISMATCH!>x = 333<!>
|
<!EXPECTED_TYPE_MISMATCH!>x = <!UNUSED_VALUE!>333<!><!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val <!UNUSED_VARIABLE!>endsWithReAssignment<!> = { () : Int ->
|
val <!UNUSED_VARIABLE!>endsWithReAssignment<!> = { () : Int ->
|
||||||
@@ -189,19 +189,19 @@ fun testFunctionLiterals() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val <!UNUSED_VARIABLE!>endsWithFunDeclaration<!> : () -> String = {
|
val <!UNUSED_VARIABLE!>endsWithFunDeclaration<!> : () -> String = {
|
||||||
var x = 1
|
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
|
||||||
x = 333
|
x = <!UNUSED_VALUE!>333<!>
|
||||||
<!EXPECTED_TYPE_MISMATCH!>fun meow() : Unit {}<!>
|
<!EXPECTED_TYPE_MISMATCH!>fun meow() : Unit {}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val <!UNUSED_VARIABLE!>endsWithObjectDeclaration<!> : () -> Int = {
|
val <!UNUSED_VARIABLE!>endsWithObjectDeclaration<!> : () -> Int = {
|
||||||
var x = 1
|
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
|
||||||
x = 333
|
x = <!UNUSED_VALUE!>333<!>
|
||||||
<!EXPECTED_TYPE_MISMATCH!>object A {}<!>
|
<!EXPECTED_TYPE_MISMATCH!>object A {}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val <!UNUSED_VARIABLE!>expectedUnitReturnType1<!> = { () : Unit ->
|
val <!UNUSED_VARIABLE!>expectedUnitReturnType1<!> = { () : Unit ->
|
||||||
val x = 1
|
val <!UNUSED_VARIABLE!>x<!> = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val <!UNUSED_VARIABLE!>expectedUnitReturnType2<!> = { () : Unit ->
|
val <!UNUSED_VARIABLE!>expectedUnitReturnType2<!> = { () : Unit ->
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ fun demo() {
|
|||||||
val a = ""
|
val a = ""
|
||||||
val asd = 1
|
val asd = 1
|
||||||
val bar = 5
|
val bar = 5
|
||||||
fun map(f : () -> Any?) : Int = 1
|
fun map(<!UNUSED_PARAMETER!>f<!> : () -> Any?) : Int = 1
|
||||||
fun buzz(f : () -> Any?) : Int = 1
|
fun buzz(<!UNUSED_PARAMETER!>f<!> : () -> Any?) : Int = 1
|
||||||
val sdf = 1
|
val sdf = 1
|
||||||
val foo = 3;
|
val foo = 3;
|
||||||
<!UNUSED_EXPRESSION!>"$abc"<!>
|
<!UNUSED_EXPRESSION!>"$abc"<!>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ fun t5() {
|
|||||||
for (i in 0..2) {
|
for (i in 0..2) {
|
||||||
<!VAL_REASSIGNMENT!>i<!> += 1
|
<!VAL_REASSIGNMENT!>i<!> += 1
|
||||||
fun t5() {
|
fun t5() {
|
||||||
<!VAL_REASSIGNMENT!>i<!> += 3
|
i += 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,8 +297,8 @@ class TestObjectExpression() {
|
|||||||
<!VAL_REASSIGNMENT!>a<!> = 231
|
<!VAL_REASSIGNMENT!>a<!> = 231
|
||||||
}
|
}
|
||||||
fun inner2() {
|
fun inner2() {
|
||||||
<!VAL_REASSIGNMENT!>y<!> = 101
|
y = 101
|
||||||
<!VAL_REASSIGNMENT!>a<!> = 231
|
a = 231
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -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
|
<!EXPECTED_TYPE_MISMATCH!>x += 2<!> //no error, but it should be here
|
||||||
}
|
}
|
||||||
val <!UNUSED_VARIABLE!>h<!> = {(): String ->
|
val <!UNUSED_VARIABLE!>h<!> = {(): String ->
|
||||||
var x = 1
|
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = 1
|
||||||
<!EXPECTED_TYPE_MISMATCH!>x = 2<!> //the same
|
<!EXPECTED_TYPE_MISMATCH!>x = <!UNUSED_VALUE!>2<!><!> //the same
|
||||||
}
|
}
|
||||||
val array1 = MyArray1()
|
val array1 = MyArray1()
|
||||||
val <!UNUSED_VARIABLE!>i<!> = { (): String ->
|
val <!UNUSED_VARIABLE!>i<!> = { (): String ->
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
fun f(<!UNUSED_PARAMETER!>i<!>: Int) {
|
fun f(<!UNUSED_PARAMETER!>i<!>: Int) {
|
||||||
for (j in 1..100) {
|
for (j in 1..100) {
|
||||||
<!UNUSED_FUNCTION_LITERAL!>{
|
<!UNUSED_FUNCTION_LITERAL!>{
|
||||||
var <!NAME_SHADOWING!>i<!> = 12
|
var <!NAME_SHADOWING, UNUSED_VARIABLE!>i<!> = 12
|
||||||
}<!>
|
}<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
fun ff(): Int {
|
fun ff(): Int {
|
||||||
var i = 1
|
var i = 1
|
||||||
<!UNUSED_FUNCTION_LITERAL!>{
|
<!UNUSED_FUNCTION_LITERAL!>{
|
||||||
val <!NAME_SHADOWING!>i<!> = 2
|
val <!NAME_SHADOWING, UNUSED_VARIABLE!>i<!> = 2
|
||||||
}<!>
|
}<!>
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fun f(): Int {
|
fun f(): Int {
|
||||||
var i = 17
|
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
|
return i
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,6 @@ import org.jetbrains.annotations.NonNls;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
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.UnresolvedReferenceDiagnosticFactory;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Severity;
|
import org.jetbrains.jet.lang.diagnostics.Severity;
|
||||||
@@ -170,8 +169,8 @@ public class JetTestUtils {
|
|||||||
private JetTestUtils() {
|
private JetTestUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AnalyzeExhaust analyzeFile(@NotNull JetFile namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
public static AnalyzeExhaust analyzeFile(@NotNull JetFile namespace) {
|
||||||
return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(namespace, flowDataTraceFactory,
|
return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(namespace,
|
||||||
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true));
|
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.JetLiteFixture;
|
import org.jetbrains.jet.JetLiteFixture;
|
||||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
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.cfg.pseudocode.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -72,37 +73,17 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
JetFile file = loadPsiFile(myName + ".jet");
|
JetFile file = loadPsiFile(myName + ".jet");
|
||||||
|
|
||||||
final Map<JetElement, Pseudocode> data = new LinkedHashMap<JetElement, Pseudocode>();
|
final Map<JetElement, Pseudocode> data = new LinkedHashMap<JetElement, Pseudocode>();
|
||||||
final JetPseudocodeTrace pseudocodeTrace = new JetPseudocodeTrace() {
|
AnalyzeExhaust analyzeExhaust = JetTestUtils.analyzeFile(file);
|
||||||
|
List<JetDeclaration> declarations = file.getDeclarations();
|
||||||
@Override
|
BindingContext bindingContext = analyzeExhaust.getBindingContext();
|
||||||
public void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode) {
|
for (JetDeclaration declaration : declarations) {
|
||||||
data.put(element, pseudocode);
|
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 {
|
try {
|
||||||
processCFData(myName, data);
|
processCFData(myName, data);
|
||||||
@@ -123,6 +104,7 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
StringBuilder instructionDump = new StringBuilder();
|
StringBuilder instructionDump = new StringBuilder();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Pseudocode pseudocode : pseudocodes) {
|
for (Pseudocode pseudocode : pseudocodes) {
|
||||||
|
|
||||||
JetElement correspondingElement = pseudocode.getCorrespondingElement();
|
JetElement correspondingElement = pseudocode.getCorrespondingElement();
|
||||||
String label = "";
|
String label = "";
|
||||||
assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetSecondaryConstructor || correspondingElement instanceof JetPropertyAccessor) :
|
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(correspondingElement.getText());
|
||||||
instructionDump.append("\n---------------------\n");
|
instructionDump.append("\n---------------------\n");
|
||||||
dumpInstructions(pseudocode, instructionDump);
|
dumpInstructions((PseudocodeImpl) pseudocode, instructionDump);
|
||||||
instructionDump.append("=====================\n");
|
instructionDump.append("=====================\n");
|
||||||
|
|
||||||
//check edges directions
|
//check edges directions
|
||||||
Collection<Instruction> instructions = pseudocode.getMutableInstructionList();
|
Collection<Instruction> instructions = ((PseudocodeImpl)pseudocode).getAllInstructions();
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
if (!((InstructionImpl)instruction).isDead()) {
|
if (!((InstructionImpl)instruction).isDead()) {
|
||||||
for (Instruction nextInstruction : instruction.getNextInstructions()) {
|
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) {
|
public void dfsDump(PseudocodeImpl pseudocode, StringBuilder nodes, StringBuilder edges, Map<Instruction, String> nodeNames) {
|
||||||
dfsDump(nodes, edges, pseudocode.getMutableInstructionList().get(0), nodeNames);
|
dfsDump(nodes, edges, pseudocode.getAllInstructions().get(0), nodeNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dfsDump(StringBuilder nodes, StringBuilder edges, Instruction instruction, Map<Instruction, String> 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();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dumpInstructions(Pseudocode pseudocode, @NotNull StringBuilder out) {
|
public void dumpInstructions(PseudocodeImpl pseudocode, @NotNull StringBuilder out) {
|
||||||
List<Instruction> instructions = pseudocode.getMutableInstructionList();
|
List<Instruction> instructions = pseudocode.getAllInstructions();
|
||||||
Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions());
|
Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions());
|
||||||
List<Pseudocode.PseudocodeLabel> labels = pseudocode.getLabels();
|
List<PseudocodeImpl.PseudocodeLabel> labels = pseudocode.getLabels();
|
||||||
List<Pseudocode> locals = new ArrayList<Pseudocode>();
|
List<PseudocodeImpl> locals = new ArrayList<PseudocodeImpl>();
|
||||||
int maxLength = 0;
|
int maxLength = 0;
|
||||||
int maxNextLength = 0;
|
int maxNextLength = 0;
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
@@ -276,9 +258,9 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
Instruction instruction = instructions.get(i);
|
Instruction instruction = instructions.get(i);
|
||||||
if (instruction instanceof LocalDeclarationInstruction) {
|
if (instruction instanceof LocalDeclarationInstruction) {
|
||||||
LocalDeclarationInstruction localDeclarationInstruction = (LocalDeclarationInstruction) instruction;
|
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) {
|
if (label.getTargetInstructionIndex() == i) {
|
||||||
out.append(label.getName()).append(":\n");
|
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(" NEXT:").append(String.format("%1$-" + maxNextLength + "s", formatInstructionList(instruction.getNextInstructions()))).
|
||||||
append(" PREV:").append(formatInstructionList(instruction.getPreviousInstructions())).append("\n");
|
append(" PREV:").append(formatInstructionList(instruction.getPreviousInstructions())).append("\n");
|
||||||
}
|
}
|
||||||
for (Pseudocode local : locals) {
|
for (PseudocodeImpl local : locals) {
|
||||||
dumpInstructions(local, out);
|
dumpInstructions(local, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,7 +282,7 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
|
public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
|
||||||
int index = count[0];
|
int index = count[0];
|
||||||
// instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName);
|
// 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);
|
visitInstructionWithNext(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +397,7 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
int[] count = new int[1];
|
int[] count = new int[1];
|
||||||
Map<Instruction, String> nodeToName = new HashMap<Instruction, String>();
|
Map<Instruction, String> nodeToName = new HashMap<Instruction, String>();
|
||||||
for (Pseudocode pseudocode : pseudocodes) {
|
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;
|
int i = 0;
|
||||||
for (Pseudocode pseudocode : pseudocodes) {
|
for (Pseudocode pseudocode : pseudocodes) {
|
||||||
@@ -431,7 +413,7 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
out.println("subgraph cluster_" + i + " {\n" +
|
out.println("subgraph cluster_" + i + " {\n" +
|
||||||
"label=\"" + label + "\";\n" +
|
"label=\"" + label + "\";\n" +
|
||||||
"color=blue;\n");
|
"color=blue;\n");
|
||||||
dumpEdges(pseudocode.getMutableInstructionList(), out, count, nodeToName);
|
dumpEdges(((PseudocodeImpl)pseudocode).getAllInstructions(), out, count, nodeToName);
|
||||||
out.println("}");
|
out.println("}");
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiFile;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||||
import org.jetbrains.jet.JetLiteFixture;
|
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.diagnostics.Diagnostic;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
@@ -107,8 +106,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
|
|||||||
|
|
||||||
public void test(final @NotNull PsiFile psiFile) {
|
public void test(final @NotNull PsiFile psiFile) {
|
||||||
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
|
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
|
||||||
(JetFile) psiFile, JetControlFlowDataTraceFactory.EMPTY,
|
(JetFile) psiFile, CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true))
|
||||||
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true))
|
|
||||||
.getBindingContext();
|
.getBindingContext();
|
||||||
|
|
||||||
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString();
|
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.JetLiteFixture;
|
||||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
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.diagnostics.DiagnosticUtils;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
@@ -172,9 +171,7 @@ public class JetDiagnosticsTest extends JetLiteFixture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||||
getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY,
|
getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), myEnvironment.getCompilerDependencies()).getBindingContext();
|
||||||
myEnvironment.getCompilerDependencies())
|
|
||||||
.getBindingContext();
|
|
||||||
|
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
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.descriptors.NamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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);
|
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
|
||||||
|
|
||||||
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
||||||
psiFile, JetControlFlowDataTraceFactory.EMPTY,
|
psiFile, jetCoreEnvironment.getCompilerDependencies())
|
||||||
jetCoreEnvironment.getCompilerDependencies())
|
|
||||||
.getBindingContext();
|
.getBindingContext();
|
||||||
return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel(Name.identifier("test")));
|
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.JetTestUtils;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
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.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
@@ -186,8 +185,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
|
|||||||
|
|
||||||
private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) {
|
private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) {
|
||||||
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
||||||
myFile, JetControlFlowDataTraceFactory.EMPTY,
|
myFile, myEnvironment.getCompilerDependencies());
|
||||||
myEnvironment.getCompilerDependencies());
|
|
||||||
analyzeExhaust.throwIfError();
|
analyzeExhaust.throwIfError();
|
||||||
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
|
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
|
||||||
GenerationState state = new GenerationState(myEnvironment.getProject(), classBuilderFactory, analyzeExhaust, Collections.singletonList(myFile));
|
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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
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.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||||
@@ -37,8 +36,7 @@ public class GenerationUtils {
|
|||||||
|
|
||||||
public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile, @NotNull CompilerSpecialMode compilerSpecialMode) {
|
public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile, @NotNull CompilerSpecialMode compilerSpecialMode) {
|
||||||
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
||||||
psiFile, JetControlFlowDataTraceFactory.EMPTY,
|
psiFile, CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode, true));
|
||||||
CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode, true));
|
|
||||||
analyzeExhaust.throwIfError();
|
analyzeExhaust.throwIfError();
|
||||||
GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile));
|
GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile));
|
||||||
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
|
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.jetbrains.jet.JetLiteFixture;
|
|||||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
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.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
@@ -78,8 +77,7 @@ public class DescriptorRendererTest extends JetLiteFixture {
|
|||||||
JetFile psiFile = createPsiFile(null, fileName, loadFile(fileName));
|
JetFile psiFile = createPsiFile(null, fileName, loadFile(fileName));
|
||||||
AnalyzeExhaust analyzeExhaust =
|
AnalyzeExhaust analyzeExhaust =
|
||||||
AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
|
AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
|
||||||
(JetFile) psiFile, JetControlFlowDataTraceFactory.EMPTY,
|
(JetFile) psiFile, myEnvironment.getCompilerDependencies());
|
||||||
myEnvironment.getCompilerDependencies());
|
|
||||||
final BindingContext bindingContext = analyzeExhaust.getBindingContext();
|
final BindingContext bindingContext = analyzeExhaust.getBindingContext();
|
||||||
final List<DeclarationDescriptor> descriptors = new ArrayList<DeclarationDescriptor>();
|
final List<DeclarationDescriptor> descriptors = new ArrayList<DeclarationDescriptor>();
|
||||||
psiFile.acceptChildren(new JetVisitorVoid() {
|
psiFile.acceptChildren(new JetVisitorVoid() {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
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.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
@@ -154,8 +153,7 @@ public abstract class ExpectedResolveData {
|
|||||||
JetStandardLibrary lib = JetStandardLibrary.getInstance();
|
JetStandardLibrary lib = JetStandardLibrary.getInstance();
|
||||||
|
|
||||||
AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(project, files,
|
AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(project, files,
|
||||||
Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY,
|
Predicates.<PsiFile>alwaysTrue(), jetCoreEnvironment.getCompilerDependencies());
|
||||||
jetCoreEnvironment.getCompilerDependencies());
|
|
||||||
BindingContext bindingContext = analyzeExhaust.getBindingContext();
|
BindingContext bindingContext = analyzeExhaust.getBindingContext();
|
||||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
||||||
if (diagnostic.getFactory() instanceof UnresolvedReferenceDiagnosticFactory) {
|
if (diagnostic.getFactory() instanceof UnresolvedReferenceDiagnosticFactory) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import org.jetbrains.jet.JetLiteFixture;
|
|||||||
import org.jetbrains.jet.JetTestUtils;
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.di.InjectorForTests;
|
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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
@@ -66,7 +65,6 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture {
|
|||||||
JetDeclaration aClass = declarations.get(0);
|
JetDeclaration aClass = declarations.get(0);
|
||||||
assert aClass instanceof JetClass;
|
assert aClass instanceof JetClass;
|
||||||
AnalyzeExhaust bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(file,
|
AnalyzeExhaust bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(file,
|
||||||
JetControlFlowDataTraceFactory.EMPTY,
|
|
||||||
myEnvironment.getCompilerDependencies());
|
myEnvironment.getCompilerDependencies());
|
||||||
DeclarationDescriptor classDescriptor = bindingContext.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, aClass);
|
DeclarationDescriptor classDescriptor = bindingContext.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, aClass);
|
||||||
WritableScopeImpl scope = new WritableScopeImpl(libraryScope, root, RedeclarationHandler.DO_NOTHING);
|
WritableScopeImpl scope = new WritableScopeImpl(libraryScope, root, RedeclarationHandler.DO_NOTHING);
|
||||||
|
|||||||
@@ -698,7 +698,7 @@ public class JetTypeCheckerTest extends JetLiteFixture {
|
|||||||
parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH);
|
parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH);
|
||||||
|
|
||||||
// This call has side-effects on the parameterScope (fills it in)
|
// 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.resolveTypeParameters(classDescriptor, parameterScope, classElement.getTypeParameters(), JetTestUtils.DUMMY_TRACE);
|
||||||
descriptorResolver.resolveGenericBounds(classElement, parameterScope, typeParameters, 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;
|
return ((PropertyDescriptor)descriptor).isVar() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor instanceof TypeParameterDescriptor) {
|
if (descriptor instanceof TypeParameterDescriptorImpl) {
|
||||||
return PlatformIcons.CLASS_ICON;
|
return PlatformIcons.CLASS_ICON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ public class JetCompletionContributor extends CompletionContributor {
|
|||||||
DeclarationDescriptor descriptor = ((JetLookupObject)object).getDescriptor();
|
DeclarationDescriptor descriptor = ((JetLookupObject)object).getDescriptor();
|
||||||
return (descriptor instanceof ClassDescriptor) ||
|
return (descriptor instanceof ClassDescriptor) ||
|
||||||
(descriptor instanceof NamespaceDescriptor) ||
|
(descriptor instanceof NamespaceDescriptor) ||
|
||||||
(descriptor instanceof TypeParameterDescriptor);
|
(descriptor instanceof TypeParameterDescriptorImpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import com.intellij.psi.util.PsiTreeUtil;
|
|||||||
import jet.Tuple2;
|
import jet.Tuple2;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
@@ -74,8 +73,7 @@ public class JetSourceNavigationHelper {
|
|||||||
BindingContext bindingContext = AnalyzerFacadeProvider.getAnalyzerFacadeForProject(project).analyzeFiles(
|
BindingContext bindingContext = AnalyzerFacadeProvider.getAnalyzerFacadeForProject(project).analyzeFiles(
|
||||||
project,
|
project,
|
||||||
libraryFiles,
|
libraryFiles,
|
||||||
Predicates.<PsiFile>alwaysTrue(),
|
Predicates.<PsiFile>alwaysTrue()).getBindingContext();
|
||||||
JetControlFlowDataTraceFactory.EMPTY).getBindingContext();
|
|
||||||
D descriptor = bindingContext.get(slice, fqName);
|
D descriptor = bindingContext.get(slice, fqName);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
return new Tuple2<BindingContext, D>(bindingContext, descriptor);
|
return new Tuple2<BindingContext, D>(bindingContext, descriptor);
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import com.intellij.psi.util.PsiModificationTracker;
|
|||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
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.DiagnosticUtils;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
@@ -94,7 +93,6 @@ public final class AnalyzerFacadeWithCache {
|
|||||||
AnalyzeExhaust exhaust = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).analyzeBodiesInFiles(
|
AnalyzeExhaust exhaust = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(file).analyzeBodiesInFiles(
|
||||||
file.getProject(),
|
file.getProject(),
|
||||||
Predicates.<PsiFile>equalTo(file),
|
Predicates.<PsiFile>equalTo(file),
|
||||||
JetControlFlowDataTraceFactory.EMPTY,
|
|
||||||
new DelegatingBindingTrace(analyzeExhaustHeaders.getBindingContext()),
|
new DelegatingBindingTrace(analyzeExhaustHeaders.getBindingContext()),
|
||||||
context);
|
context);
|
||||||
|
|
||||||
@@ -137,8 +135,7 @@ public final class AnalyzerFacadeWithCache {
|
|||||||
AnalyzeExhaust exhaust = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(fileToCache)
|
AnalyzeExhaust exhaust = AnalyzerFacadeProvider.getAnalyzerFacadeForFile(fileToCache)
|
||||||
.analyzeFiles(fileToCache.getProject(),
|
.analyzeFiles(fileToCache.getProject(),
|
||||||
headerFiles,
|
headerFiles,
|
||||||
Predicates.<PsiFile>alwaysFalse(),
|
Predicates.<PsiFile>alwaysFalse());
|
||||||
JetControlFlowDataTraceFactory.EMPTY);
|
|
||||||
|
|
||||||
return new Result<AnalyzeExhaust>(exhaust, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||||
import org.jetbrains.jet.analyzer.AnalyzerFacade;
|
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.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
|
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
|
||||||
@@ -44,8 +43,7 @@ public enum JSAnalyzerFacadeForIDEA implements AnalyzerFacade {
|
|||||||
@Override
|
@Override
|
||||||
public AnalyzeExhaust analyzeFiles(@NotNull Project project,
|
public AnalyzeExhaust analyzeFiles(@NotNull Project project,
|
||||||
@NotNull Collection<JetFile> files,
|
@NotNull Collection<JetFile> files,
|
||||||
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
|
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely) {
|
||||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
|
||||||
return AnalyzerFacadeForJS.analyzeFiles(files, filesToAnalyzeCompletely, new IDEAConfig(project), true);
|
return AnalyzerFacadeForJS.analyzeFiles(files, filesToAnalyzeCompletely, new IDEAConfig(project), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +51,6 @@ public enum JSAnalyzerFacadeForIDEA implements AnalyzerFacade {
|
|||||||
@Override
|
@Override
|
||||||
public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
|
public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
|
||||||
@NotNull Predicate<PsiFile> filesForBodiesResolve,
|
@NotNull Predicate<PsiFile> filesForBodiesResolve,
|
||||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
|
|
||||||
@NotNull BindingTrace traceContext,
|
@NotNull BindingTrace traceContext,
|
||||||
@NotNull BodiesResolveContext bodiesResolveContext) {
|
@NotNull BodiesResolveContext bodiesResolveContext) {
|
||||||
return AnalyzerFacadeForJS.analyzeBodiesInFiles(filesForBodiesResolve, new IDEAConfig(project), traceContext, 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
Reference in New Issue
Block a user