Multiple declarations contributing to the same namespace are supported
This commit is contained in:
@@ -13,7 +13,7 @@ internal class Example<X, T : Comparable<X>>(protected val x : Foo<X, T>, y : So
|
|||||||
class
|
class
|
||||||
: modifiers "class" SimpleName
|
: modifiers "class" SimpleName
|
||||||
typeParameters?
|
typeParameters?
|
||||||
"wraps"?
|
("wraps" | modifiers)?
|
||||||
valueParameters?
|
valueParameters?
|
||||||
(":" attributes delegationSpecifier{","})?
|
(":" attributes delegationSpecifier{","})?
|
||||||
(classBody? | enumClassBody)
|
(classBody? | enumClassBody)
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ package org.jetbrains.jet.lang;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
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.resolve.ClassDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
|
||||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
|
||||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +63,6 @@ public class JetSemanticServices {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public WritableScope createWritableScope(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner) {
|
public WritableScope createWritableScope(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner) {
|
||||||
return new WritableScope(scope, owner, errorHandler);
|
return new WritableScopeImpl(scope, owner, errorHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
* class
|
* class
|
||||||
* : modifiers "class" SimpleName
|
* : modifiers "class" SimpleName
|
||||||
* typeParameters?
|
* typeParameters?
|
||||||
* "wraps"?
|
* ("wraps" | modifiers)?
|
||||||
* ("(" primaryConstructorParameter{","} ")")?
|
* ("(" primaryConstructorParameter{","} ")")?
|
||||||
* (":" attributes delegationSpecifier{","})?
|
* (":" attributes delegationSpecifier{","})?
|
||||||
* (classBody? | enumClassBody)
|
* (classBody? | enumClassBody)
|
||||||
@@ -384,7 +384,13 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
|
expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
|
||||||
parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
|
parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
|
||||||
|
|
||||||
consumeIf(WRAPS_KEYWORD);
|
if (at(WRAPS_KEYWORD)) {
|
||||||
|
advance(); // WRAPS_KEYWORD
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parseModifierList();
|
||||||
|
}
|
||||||
|
|
||||||
if (at(LPAR)) {
|
if (at(LPAR)) {
|
||||||
parseValueParameterList(false, TokenSet.EMPTY);
|
parseValueParameterList(false, TokenSet.EMPTY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ public class JetScopeAdapter implements JetScope {
|
|||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected final JetScope getWorkerScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JetType getThisType() {
|
public JetType getThisType() {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class SubstitutingScope implements JetScope {
|
|||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
return new LazySubstitutingClassDescriptor((ClassDescriptor) descriptor, substitutor);
|
return new LazySubstitutingClassDescriptor((ClassDescriptor) descriptor, substitutor);
|
||||||
}
|
}
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -99,11 +99,12 @@ public class TopDownAnalyzer {
|
|||||||
Collections.<Attribute>emptyList(), // TODO
|
Collections.<Attribute>emptyList(), // TODO
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
|
namespaceDescriptor.initialize(semanticServices.createWritableScope(JetScope.EMPTY, namespaceDescriptor));
|
||||||
declaringScope.addNamespace(namespaceDescriptor);
|
declaringScope.addNamespace(namespaceDescriptor);
|
||||||
trace.recordDeclarationResolution(namespace, namespaceDescriptor);
|
trace.recordDeclarationResolution(namespace, namespaceDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
WritableScope namespaceScope = semanticServices.createWritableScope(declaringScope, namespaceDescriptor);
|
WritableScope namespaceScope = new WriteThroughScope(declaringScope, (WritableScope) namespaceDescriptor.getMemberScope());
|
||||||
namespaceScopes.put(namespace, namespaceScope);
|
namespaceScopes.put(namespace, namespaceScope);
|
||||||
|
|
||||||
for (JetImportDirective importDirective : importDirectives) {
|
for (JetImportDirective importDirective : importDirectives) {
|
||||||
@@ -264,7 +265,7 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processClassObject(JetClassObject classObject) {
|
private void processClassObject(JetClassObject classObject) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
semanticServices.getErrorHandler().genericError(classObject.getNode(), "Class objects are not supported yet"); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -2,296 +2,32 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
|
|
||||||
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.ErrorHandler;
|
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class WritableScope extends JetScopeAdapter {
|
public interface WritableScope extends JetScope {
|
||||||
@NotNull
|
void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor);
|
||||||
private final ErrorHandler errorHandler;
|
|
||||||
|
|
||||||
@NotNull
|
void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor);
|
||||||
private final DeclarationDescriptor ownerDeclarationDescriptor;
|
|
||||||
|
|
||||||
// FieldNames include "$"
|
void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor);
|
||||||
@Nullable
|
|
||||||
private Map<String, PropertyDescriptor> propertyDescriptorsByFieldNames;
|
void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor);
|
||||||
|
|
||||||
|
void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor);
|
||||||
|
|
||||||
|
void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor);
|
||||||
|
|
||||||
|
void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Map<String, VariableDescriptor> variableDescriptors;
|
NamespaceDescriptor getDeclaredNamespace(@NotNull String name);
|
||||||
@Nullable
|
|
||||||
private Map<String, WritableFunctionGroup> functionGroups;
|
|
||||||
@Nullable
|
|
||||||
private Map<String, ClassifierDescriptor> classifierDescriptors;
|
|
||||||
@Nullable
|
|
||||||
private Map<String, NamespaceDescriptor> namespaceDescriptors;
|
|
||||||
@Nullable
|
|
||||||
private Map<String, List<DeclarationDescriptor>> labelsToDescriptors;
|
|
||||||
@Nullable
|
|
||||||
private JetType thisType;
|
|
||||||
|
|
||||||
@Nullable
|
void addPropertyDescriptorByFieldName(@NotNull String fieldName, @NotNull PropertyDescriptor propertyDescriptor);
|
||||||
private List<JetScope> imports;
|
|
||||||
|
|
||||||
public WritableScope(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull ErrorHandler errorHandler) {
|
void importScope(@NotNull JetScope imported);
|
||||||
super(scope);
|
|
||||||
this.ownerDeclarationDescriptor = owner;
|
|
||||||
this.errorHandler = errorHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
void setThisType(@NotNull JetType thisType);
|
||||||
@Override
|
|
||||||
public DeclarationDescriptor getContainingDeclaration() {
|
|
||||||
return ownerDeclarationDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Map<String, List<DeclarationDescriptor>> getLabelsToDescriptors() {
|
|
||||||
if (labelsToDescriptors == null) {
|
|
||||||
labelsToDescriptors = new HashMap<String, List<DeclarationDescriptor>>();
|
|
||||||
}
|
|
||||||
return labelsToDescriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull String labelName) {
|
|
||||||
Map<String, List<DeclarationDescriptor>> labelsToDescriptors = getLabelsToDescriptors();
|
|
||||||
Collection<DeclarationDescriptor> superResult = super.getDeclarationsByLabel(labelName);
|
|
||||||
List<DeclarationDescriptor> declarationDescriptors = labelsToDescriptors.get(labelName);
|
|
||||||
if (declarationDescriptors == null) {
|
|
||||||
return superResult;
|
|
||||||
}
|
|
||||||
if (superResult.isEmpty()) return declarationDescriptors;
|
|
||||||
List<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>(declarationDescriptors);
|
|
||||||
result.addAll(superResult);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
Map<String, List<DeclarationDescriptor>> labelsToDescriptors = getLabelsToDescriptors();
|
|
||||||
String name = descriptor.getName();
|
|
||||||
assert name != null;
|
|
||||||
List<DeclarationDescriptor> declarationDescriptors = labelsToDescriptors.get(name);
|
|
||||||
if (declarationDescriptors == null) {
|
|
||||||
declarationDescriptors = new ArrayList<DeclarationDescriptor>();
|
|
||||||
labelsToDescriptors.put(name, declarationDescriptors);
|
|
||||||
}
|
|
||||||
declarationDescriptors.add(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void importScope(@NotNull JetScope imported) {
|
|
||||||
getImports().add(0, imported);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private List<JetScope> getImports() {
|
|
||||||
if (imports == null) {
|
|
||||||
imports = new ArrayList<JetScope>();
|
|
||||||
}
|
|
||||||
return imports;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Map<String, VariableDescriptor> getVariableDescriptors() {
|
|
||||||
if (variableDescriptors == null) {
|
|
||||||
variableDescriptors = new HashMap<String, VariableDescriptor>();
|
|
||||||
}
|
|
||||||
return variableDescriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addVariableDescriptor(VariableDescriptor variableDescriptor) {
|
|
||||||
Map<String, VariableDescriptor> propertyDescriptors = getVariableDescriptors();
|
|
||||||
VariableDescriptor existingDescriptor = propertyDescriptors.get(variableDescriptor.getName());
|
|
||||||
if (existingDescriptor != null) {
|
|
||||||
errorHandler.redeclaration(existingDescriptor, variableDescriptor);
|
|
||||||
}
|
|
||||||
// TODO : Should this always happen?
|
|
||||||
propertyDescriptors.put(variableDescriptor.getName(), variableDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VariableDescriptor getVariable(@NotNull String name) {
|
|
||||||
@NotNull
|
|
||||||
Map<String, VariableDescriptor> propertyDescriptors = getVariableDescriptors();
|
|
||||||
VariableDescriptor variableDescriptor = propertyDescriptors.get(name);
|
|
||||||
if (variableDescriptor != null) {
|
|
||||||
return variableDescriptor;
|
|
||||||
}
|
|
||||||
variableDescriptor = super.getVariable(name);
|
|
||||||
if (variableDescriptor != null) {
|
|
||||||
return variableDescriptor;
|
|
||||||
}
|
|
||||||
for (JetScope imported : getImports()) {
|
|
||||||
VariableDescriptor importedDescriptor = imported.getVariable(name);
|
|
||||||
if (importedDescriptor != null) {
|
|
||||||
return importedDescriptor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Map<String, WritableFunctionGroup> getFunctionGroups() {
|
|
||||||
if (functionGroups == null) {
|
|
||||||
functionGroups = new HashMap<String, WritableFunctionGroup>();
|
|
||||||
}
|
|
||||||
return functionGroups;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addFunctionDescriptor(FunctionDescriptor functionDescriptor) {
|
|
||||||
String name = functionDescriptor.getName();
|
|
||||||
Map<String, WritableFunctionGroup> functionGroups = getFunctionGroups();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
WritableFunctionGroup functionGroup = functionGroups.get(name);
|
|
||||||
if (functionGroup == null) {
|
|
||||||
functionGroup = new WritableFunctionGroup(name);
|
|
||||||
functionGroups.put(name, functionGroup);
|
|
||||||
}
|
|
||||||
functionGroup.addFunction(functionDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public FunctionGroup getFunctionGroup(@NotNull String name) {
|
|
||||||
FunctionGroup functionGroup = getFunctionGroups().get(name);
|
|
||||||
if (functionGroup != null && !functionGroup.isEmpty()) {
|
|
||||||
return functionGroup;
|
|
||||||
}
|
|
||||||
// TODO : this logic is questionable
|
|
||||||
functionGroup = super.getFunctionGroup(name);
|
|
||||||
if (!functionGroup.isEmpty()) return functionGroup;
|
|
||||||
for (JetScope imported : getImports()) {
|
|
||||||
FunctionGroup importedDescriptor = imported.getFunctionGroup(name);
|
|
||||||
if (!importedDescriptor.isEmpty()) {
|
|
||||||
return importedDescriptor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return functionGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTypeParameterDescriptor(TypeParameterDescriptor typeParameterDescriptor) {
|
|
||||||
String name = typeParameterDescriptor.getName();
|
|
||||||
Map<String, ClassifierDescriptor> classifierDescriptors = getClassifierDescriptors();
|
|
||||||
ClassifierDescriptor originalDescriptor = classifierDescriptors.get(name);
|
|
||||||
if (originalDescriptor != null) {
|
|
||||||
errorHandler.redeclaration(originalDescriptor, typeParameterDescriptor);
|
|
||||||
}
|
|
||||||
classifierDescriptors.put(name, typeParameterDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Map<String, ClassifierDescriptor> getClassifierDescriptors() {
|
|
||||||
if (classifierDescriptors == null) {
|
|
||||||
classifierDescriptors = new HashMap<String, ClassifierDescriptor>();
|
|
||||||
}
|
|
||||||
return classifierDescriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) {
|
|
||||||
addClassifierAlias(classDescriptor.getName(), classDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addClassifierAlias(String name, ClassifierDescriptor classifierDescriptor) {
|
|
||||||
Map<String, ClassifierDescriptor> classifierDescriptors = getClassifierDescriptors();
|
|
||||||
ClassifierDescriptor originalDescriptor = classifierDescriptors.get(name);
|
|
||||||
if (originalDescriptor != null) {
|
|
||||||
errorHandler.redeclaration(originalDescriptor, classifierDescriptor);
|
|
||||||
}
|
|
||||||
classifierDescriptors.put(name, classifierDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClassifierDescriptor getClassifier(@NotNull String name) {
|
|
||||||
ClassifierDescriptor classifierDescriptor = getClassifierDescriptors().get(name);
|
|
||||||
if (classifierDescriptor != null) return classifierDescriptor;
|
|
||||||
|
|
||||||
classifierDescriptor = super.getClassifier(name);
|
|
||||||
if (classifierDescriptor != null) return classifierDescriptor;
|
|
||||||
for (JetScope imported : getImports()) {
|
|
||||||
ClassifierDescriptor importedClassifier = imported.getClassifier(name);
|
|
||||||
if (importedClassifier != null) {
|
|
||||||
return importedClassifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public JetType getThisType() {
|
|
||||||
if (thisType == null) {
|
|
||||||
return super.getThisType();
|
|
||||||
}
|
|
||||||
return thisType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Map<String, NamespaceDescriptor> getNamespaceDescriptors() {
|
|
||||||
if (namespaceDescriptors == null) {
|
|
||||||
namespaceDescriptors = new HashMap<String, NamespaceDescriptor>();
|
|
||||||
}
|
|
||||||
return namespaceDescriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addNamespace(NamespaceDescriptor namespaceDescriptor) {
|
|
||||||
NamespaceDescriptor oldValue = getNamespaceDescriptors().put(namespaceDescriptor.getName(), namespaceDescriptor);
|
|
||||||
if (oldValue != null) {
|
|
||||||
errorHandler.redeclaration(oldValue, namespaceDescriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NamespaceDescriptor getDeclaredNamespace(@NotNull String name) {
|
|
||||||
NamespaceDescriptor namespaceDescriptor = getNamespaceDescriptors().get(name);
|
|
||||||
if (namespaceDescriptor != null) return namespaceDescriptor;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
|
||||||
NamespaceDescriptor declaredNamespace = getDeclaredNamespace(name);
|
|
||||||
if (declaredNamespace != null) return declaredNamespace;
|
|
||||||
|
|
||||||
NamespaceDescriptor namespace = super.getNamespace(name);
|
|
||||||
if (namespace != null) return namespace;
|
|
||||||
for (JetScope imported : getImports()) {
|
|
||||||
NamespaceDescriptor importedDescriptor = imported.getNamespace(name);
|
|
||||||
if (importedDescriptor != null) {
|
|
||||||
return importedDescriptor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThisType(JetType thisType) {
|
|
||||||
if (this.thisType != null) {
|
|
||||||
throw new UnsupportedOperationException("Receiver redeclared");
|
|
||||||
}
|
|
||||||
this.thisType = thisType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"NullableProblems"})
|
|
||||||
@NotNull
|
|
||||||
private Map<String, PropertyDescriptor> getPropertyDescriptorsByFieldNames() {
|
|
||||||
if (propertyDescriptorsByFieldNames == null) {
|
|
||||||
propertyDescriptorsByFieldNames = new HashMap<String, PropertyDescriptor>();
|
|
||||||
}
|
|
||||||
return propertyDescriptorsByFieldNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPropertyDescriptorByFieldName(@NotNull String fieldName, PropertyDescriptor propertyDescriptor) {
|
|
||||||
getPropertyDescriptorsByFieldNames().put(fieldName, propertyDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName) {
|
|
||||||
PropertyDescriptor descriptor = getPropertyDescriptorsByFieldNames().get(fieldName);
|
|
||||||
if (descriptor != null) return descriptor;
|
|
||||||
return super.getPropertyByFieldReference(fieldName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,296 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class WritableScopeImpl extends WritableScopeWithImports {
|
||||||
|
@NotNull
|
||||||
|
private final ErrorHandler errorHandler;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final DeclarationDescriptor ownerDeclarationDescriptor;
|
||||||
|
|
||||||
|
// FieldNames include "$"
|
||||||
|
@Nullable
|
||||||
|
private Map<String, PropertyDescriptor> propertyDescriptorsByFieldNames;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Map<String, VariableDescriptor> variableDescriptors;
|
||||||
|
@Nullable
|
||||||
|
private Map<String, WritableFunctionGroup> functionGroups;
|
||||||
|
@Nullable
|
||||||
|
private Map<String, ClassifierDescriptor> classifierDescriptors;
|
||||||
|
@Nullable
|
||||||
|
private Map<String, NamespaceDescriptor> namespaceDescriptors;
|
||||||
|
@Nullable
|
||||||
|
private Map<String, List<DeclarationDescriptor>> labelsToDescriptors;
|
||||||
|
@Nullable
|
||||||
|
private JetType thisType;
|
||||||
|
|
||||||
|
public WritableScopeImpl(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull ErrorHandler errorHandler) {
|
||||||
|
super(scope);
|
||||||
|
this.ownerDeclarationDescriptor = owner;
|
||||||
|
this.errorHandler = errorHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public DeclarationDescriptor getContainingDeclaration() {
|
||||||
|
return ownerDeclarationDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Map<String, List<DeclarationDescriptor>> getLabelsToDescriptors() {
|
||||||
|
if (labelsToDescriptors == null) {
|
||||||
|
labelsToDescriptors = new HashMap<String, List<DeclarationDescriptor>>();
|
||||||
|
}
|
||||||
|
return labelsToDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull String labelName) {
|
||||||
|
Map<String, List<DeclarationDescriptor>> labelsToDescriptors = getLabelsToDescriptors();
|
||||||
|
Collection<DeclarationDescriptor> superResult = super.getDeclarationsByLabel(labelName);
|
||||||
|
List<DeclarationDescriptor> declarationDescriptors = labelsToDescriptors.get(labelName);
|
||||||
|
if (declarationDescriptors == null) {
|
||||||
|
return superResult;
|
||||||
|
}
|
||||||
|
if (superResult.isEmpty()) return declarationDescriptors;
|
||||||
|
List<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>(declarationDescriptors);
|
||||||
|
result.addAll(superResult);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
Map<String, List<DeclarationDescriptor>> labelsToDescriptors = getLabelsToDescriptors();
|
||||||
|
String name = descriptor.getName();
|
||||||
|
assert name != null;
|
||||||
|
List<DeclarationDescriptor> declarationDescriptors = labelsToDescriptors.get(name);
|
||||||
|
if (declarationDescriptors == null) {
|
||||||
|
declarationDescriptors = new ArrayList<DeclarationDescriptor>();
|
||||||
|
labelsToDescriptors.put(name, declarationDescriptors);
|
||||||
|
}
|
||||||
|
declarationDescriptors.add(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Map<String, VariableDescriptor> getVariableDescriptors() {
|
||||||
|
if (variableDescriptors == null) {
|
||||||
|
variableDescriptors = new HashMap<String, VariableDescriptor>();
|
||||||
|
}
|
||||||
|
return variableDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) {
|
||||||
|
Map<String, VariableDescriptor> propertyDescriptors = getVariableDescriptors();
|
||||||
|
VariableDescriptor existingDescriptor = propertyDescriptors.get(variableDescriptor.getName());
|
||||||
|
if (existingDescriptor != null) {
|
||||||
|
errorHandler.redeclaration(existingDescriptor, variableDescriptor);
|
||||||
|
}
|
||||||
|
// TODO : Should this always happen?
|
||||||
|
propertyDescriptors.put(variableDescriptor.getName(), variableDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VariableDescriptor getVariable(@NotNull String name) {
|
||||||
|
@NotNull
|
||||||
|
Map<String, VariableDescriptor> propertyDescriptors = getVariableDescriptors();
|
||||||
|
VariableDescriptor variableDescriptor = propertyDescriptors.get(name);
|
||||||
|
if (variableDescriptor != null) {
|
||||||
|
return variableDescriptor;
|
||||||
|
}
|
||||||
|
variableDescriptor = getWorkerScope().getVariable(name);
|
||||||
|
if (variableDescriptor != null) {
|
||||||
|
return variableDescriptor;
|
||||||
|
}
|
||||||
|
// for (JetScope imported : getImports()) {
|
||||||
|
// VariableDescriptor importedDescriptor = imported.getVariable(name);
|
||||||
|
// if (importedDescriptor != null) {
|
||||||
|
// return importedDescriptor;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
return super.getVariable(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Map<String, WritableFunctionGroup> getFunctionGroups() {
|
||||||
|
if (functionGroups == null) {
|
||||||
|
functionGroups = new HashMap<String, WritableFunctionGroup>();
|
||||||
|
}
|
||||||
|
return functionGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
|
String name = functionDescriptor.getName();
|
||||||
|
Map<String, WritableFunctionGroup> functionGroups = getFunctionGroups();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
WritableFunctionGroup functionGroup = functionGroups.get(name);
|
||||||
|
if (functionGroup == null) {
|
||||||
|
functionGroup = new WritableFunctionGroup(name);
|
||||||
|
functionGroups.put(name, functionGroup);
|
||||||
|
}
|
||||||
|
functionGroup.addFunction(functionDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public FunctionGroup getFunctionGroup(@NotNull String name) {
|
||||||
|
FunctionGroup functionGroup = getFunctionGroups().get(name);
|
||||||
|
if (functionGroup != null && !functionGroup.isEmpty()) {
|
||||||
|
return functionGroup;
|
||||||
|
}
|
||||||
|
// TODO : this logic is questionable
|
||||||
|
functionGroup = getWorkerScope().getFunctionGroup(name);
|
||||||
|
if (!functionGroup.isEmpty()) return functionGroup;
|
||||||
|
// for (JetScope imported : getImports()) {
|
||||||
|
// FunctionGroup importedDescriptor = imported.getFunctionGroup(name);
|
||||||
|
// if (!importedDescriptor.isEmpty()) {
|
||||||
|
// return importedDescriptor;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return functionGroup;
|
||||||
|
return super.getFunctionGroup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
|
String name = typeParameterDescriptor.getName();
|
||||||
|
Map<String, ClassifierDescriptor> classifierDescriptors = getClassifierDescriptors();
|
||||||
|
ClassifierDescriptor originalDescriptor = classifierDescriptors.get(name);
|
||||||
|
if (originalDescriptor != null) {
|
||||||
|
errorHandler.redeclaration(originalDescriptor, typeParameterDescriptor);
|
||||||
|
}
|
||||||
|
classifierDescriptors.put(name, typeParameterDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Map<String, ClassifierDescriptor> getClassifierDescriptors() {
|
||||||
|
if (classifierDescriptors == null) {
|
||||||
|
classifierDescriptors = new HashMap<String, ClassifierDescriptor>();
|
||||||
|
}
|
||||||
|
return classifierDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) {
|
||||||
|
addClassifierAlias(classDescriptor.getName(), classDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor) {
|
||||||
|
Map<String, ClassifierDescriptor> classifierDescriptors = getClassifierDescriptors();
|
||||||
|
ClassifierDescriptor originalDescriptor = classifierDescriptors.get(name);
|
||||||
|
if (originalDescriptor != null) {
|
||||||
|
errorHandler.redeclaration(originalDescriptor, classifierDescriptor);
|
||||||
|
}
|
||||||
|
classifierDescriptors.put(name, classifierDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassifierDescriptor getClassifier(@NotNull String name) {
|
||||||
|
ClassifierDescriptor classifierDescriptor = getClassifierDescriptors().get(name);
|
||||||
|
if (classifierDescriptor != null) return classifierDescriptor;
|
||||||
|
|
||||||
|
classifierDescriptor = getWorkerScope().getClassifier(name);
|
||||||
|
if (classifierDescriptor != null) return classifierDescriptor;
|
||||||
|
// for (JetScope imported : getImports()) {
|
||||||
|
// ClassifierDescriptor importedClassifier = imported.getClassifier(name);
|
||||||
|
// if (importedClassifier != null) {
|
||||||
|
// return importedClassifier;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
return super.getClassifier(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JetType getThisType() {
|
||||||
|
if (thisType == null) {
|
||||||
|
return super.getThisType();
|
||||||
|
}
|
||||||
|
return thisType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Map<String, NamespaceDescriptor> getNamespaceDescriptors() {
|
||||||
|
if (namespaceDescriptors == null) {
|
||||||
|
namespaceDescriptors = new HashMap<String, NamespaceDescriptor>();
|
||||||
|
}
|
||||||
|
return namespaceDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||||
|
NamespaceDescriptor oldValue = getNamespaceDescriptors().put(namespaceDescriptor.getName(), namespaceDescriptor);
|
||||||
|
if (oldValue != null) {
|
||||||
|
errorHandler.redeclaration(oldValue, namespaceDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getDeclaredNamespace(@NotNull String name) {
|
||||||
|
NamespaceDescriptor namespaceDescriptor = getNamespaceDescriptors().get(name);
|
||||||
|
if (namespaceDescriptor != null) return namespaceDescriptor;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
|
NamespaceDescriptor declaredNamespace = getDeclaredNamespace(name);
|
||||||
|
if (declaredNamespace != null) return declaredNamespace;
|
||||||
|
|
||||||
|
NamespaceDescriptor namespace = getWorkerScope().getNamespace(name);
|
||||||
|
if (namespace != null) return namespace;
|
||||||
|
// for (JetScope imported : getImports()) {
|
||||||
|
// NamespaceDescriptor importedDescriptor = imported.getNamespace(name);
|
||||||
|
// if (importedDescriptor != null) {
|
||||||
|
// return importedDescriptor;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
return super.getNamespace(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setThisType(@NotNull JetType thisType) {
|
||||||
|
if (this.thisType != null) {
|
||||||
|
throw new UnsupportedOperationException("Receiver redeclared");
|
||||||
|
}
|
||||||
|
this.thisType = thisType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"NullableProblems"})
|
||||||
|
@NotNull
|
||||||
|
private Map<String, PropertyDescriptor> getPropertyDescriptorsByFieldNames() {
|
||||||
|
if (propertyDescriptorsByFieldNames == null) {
|
||||||
|
propertyDescriptorsByFieldNames = new HashMap<String, PropertyDescriptor>();
|
||||||
|
}
|
||||||
|
return propertyDescriptorsByFieldNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPropertyDescriptorByFieldName(@NotNull String fieldName, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||||
|
getPropertyDescriptorsByFieldNames().put(fieldName, propertyDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName) {
|
||||||
|
PropertyDescriptor descriptor = getPropertyDescriptorsByFieldNames().get(fieldName);
|
||||||
|
if (descriptor != null) return descriptor;
|
||||||
|
return super.getPropertyByFieldReference(fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.types.ClassifierDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.FunctionGroup;
|
||||||
|
import org.jetbrains.jet.lang.types.NamespaceDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.VariableDescriptor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class WritableScopeWithImports extends JetScopeAdapter implements WritableScope {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private List<JetScope> imports;
|
||||||
|
|
||||||
|
public WritableScopeWithImports(@NotNull JetScope scope) {
|
||||||
|
super(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected final List<JetScope> getImports() {
|
||||||
|
if (imports == null) {
|
||||||
|
imports = new ArrayList<JetScope>();
|
||||||
|
}
|
||||||
|
return imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void importScope(@NotNull JetScope imported) {
|
||||||
|
getImports().add(0, imported);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VariableDescriptor getVariable(@NotNull String name) {
|
||||||
|
// Meaningful lookup goes here
|
||||||
|
for (JetScope imported : getImports()) {
|
||||||
|
VariableDescriptor importedDescriptor = imported.getVariable(name);
|
||||||
|
if (importedDescriptor != null) {
|
||||||
|
return importedDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public FunctionGroup getFunctionGroup(@NotNull String name) {
|
||||||
|
for (JetScope imported : getImports()) {
|
||||||
|
FunctionGroup importedDescriptor = imported.getFunctionGroup(name);
|
||||||
|
if (!importedDescriptor.isEmpty()) {
|
||||||
|
return importedDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FunctionGroup.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassifierDescriptor getClassifier(@NotNull String name) {
|
||||||
|
for (JetScope imported : getImports()) {
|
||||||
|
ClassifierDescriptor importedClassifier = imported.getClassifier(name);
|
||||||
|
if (importedClassifier != null) {
|
||||||
|
return importedClassifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
|
for (JetScope imported : getImports()) {
|
||||||
|
NamespaceDescriptor importedDescriptor = imported.getNamespace(name);
|
||||||
|
if (importedDescriptor != null) {
|
||||||
|
return importedDescriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class WriteThroughScope extends WritableScopeWithImports {
|
||||||
|
private final WritableScope writableWorker;
|
||||||
|
|
||||||
|
public WriteThroughScope(@NotNull JetScope outerScope, @NotNull WritableScope scope) {
|
||||||
|
super(outerScope);
|
||||||
|
this.writableWorker = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName) {
|
||||||
|
return writableWorker.getPropertyByFieldReference(fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public Collection<DeclarationDescriptor> getDeclarationsByLabel(String labelName) {
|
||||||
|
return writableWorker.getDeclarationsByLabel(labelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public DeclarationDescriptor getContainingDeclaration() {
|
||||||
|
return writableWorker.getContainingDeclaration();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JetType getThisType() {
|
||||||
|
return writableWorker.getThisType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public FunctionGroup getFunctionGroup(@NotNull String name) {
|
||||||
|
FunctionGroup functionGroup = writableWorker.getFunctionGroup(name);
|
||||||
|
if (!functionGroup.isEmpty()) return functionGroup; // TODO : Overloads from different places
|
||||||
|
|
||||||
|
functionGroup = getWorkerScope().getFunctionGroup(name);
|
||||||
|
if (!functionGroup.isEmpty()) return functionGroup; // TODO : Overloads from different places
|
||||||
|
|
||||||
|
return super.getFunctionGroup(name); // Imports
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public VariableDescriptor getVariable(@NotNull String name) {
|
||||||
|
VariableDescriptor variable = writableWorker.getVariable(name);
|
||||||
|
if (variable != null) return variable;
|
||||||
|
|
||||||
|
variable = getWorkerScope().getVariable(name);
|
||||||
|
if (variable != null) return variable;
|
||||||
|
|
||||||
|
return super.getVariable(name); // Imports
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
|
NamespaceDescriptor namespace = writableWorker.getNamespace(name);
|
||||||
|
if (namespace != null) return namespace;
|
||||||
|
|
||||||
|
namespace = getWorkerScope().getNamespace(name);
|
||||||
|
if (namespace != null) return namespace;
|
||||||
|
|
||||||
|
return super.getNamespace(name); // Imports
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public ClassifierDescriptor getClassifier(@NotNull String name) {
|
||||||
|
ClassifierDescriptor classifier = writableWorker.getClassifier(name);
|
||||||
|
if (classifier != null) return classifier;
|
||||||
|
|
||||||
|
classifier = getWorkerScope().getClassifier(name);
|
||||||
|
if (classifier != null) return classifier;
|
||||||
|
|
||||||
|
return super.getClassifier(name); // Imports
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
writableWorker.addLabeledDeclaration(descriptor); // TODO : review
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) {
|
||||||
|
writableWorker.addVariableDescriptor(variableDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
|
writableWorker.addFunctionDescriptor(functionDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
|
writableWorker.addTypeParameterDescriptor(typeParameterDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) {
|
||||||
|
writableWorker.addClassifierDescriptor(classDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor) {
|
||||||
|
writableWorker.addClassifierAlias(name, classifierDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||||
|
writableWorker.addNamespace(namespaceDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public NamespaceDescriptor getDeclaredNamespace(@NotNull String name) {
|
||||||
|
return writableWorker.getDeclaredNamespace(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPropertyDescriptorByFieldName(@NotNull String fieldName, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||||
|
writableWorker.addPropertyDescriptorByFieldName(fieldName, propertyDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void importScope(@NotNull JetScope imported) {
|
||||||
|
super.importScope(imported); //
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setThisType(@NotNull JetType thisType) {
|
||||||
|
writableWorker.setThisType(thisType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -141,10 +141,6 @@ public class ErrorUtils {
|
|||||||
return createErrorType(value + " is not allowed here]", value.getType().getMemberScope());
|
return createErrorType(value + " is not allowed here]", value.getType().getMemberScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isErrorType(JetType type) {
|
|
||||||
return type instanceof ErrorTypeImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ClassifierDescriptor getErrorClass() {
|
public static ClassifierDescriptor getErrorClass() {
|
||||||
return ERROR_CLASS;
|
return ERROR_CLASS;
|
||||||
}
|
}
|
||||||
@@ -153,6 +149,10 @@ public class ErrorUtils {
|
|||||||
return typeConstructor == ERROR_CLASS.getTypeConstructor();
|
return typeConstructor == ERROR_CLASS.getTypeConstructor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isErrorType(JetType type) {
|
||||||
|
return type instanceof ErrorTypeImpl || isError(type.getConstructor());
|
||||||
|
}
|
||||||
|
|
||||||
private static class ErrorTypeImpl implements JetType {
|
private static class ErrorTypeImpl implements JetType {
|
||||||
|
|
||||||
private final TypeConstructor constructor;
|
private final TypeConstructor constructor;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.ErrorHandler;
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
import org.jetbrains.jet.lang.resolve.WritableScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.WritableScopeImpl;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -164,7 +165,7 @@ public class JetStandardClasses {
|
|||||||
/*package*/ static final JetScope STANDARD_CLASSES;
|
/*package*/ static final JetScope STANDARD_CLASSES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
WritableScope writableScope = new WritableScope(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, ErrorHandler.DO_NOTHING);
|
WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, ErrorHandler.DO_NOTHING);
|
||||||
STANDARD_CLASSES = writableScope;
|
STANDARD_CLASSES = writableScope;
|
||||||
writableScope.addClassifierAlias("Unit", getTuple(0));
|
writableScope.addClassifierAlias("Unit", getTuple(0));
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public class NamespaceDescriptor extends DeclarationDescriptorImpl {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public NamespaceType getNamespaceType() {
|
public NamespaceType getNamespaceType() {
|
||||||
if (namespaceType == null) {
|
if (namespaceType == null) {
|
||||||
|
assert memberScope != null : "Member scope not set";
|
||||||
namespaceType = new NamespaceType(getName(), memberScope);
|
namespaceType = new NamespaceType(getName(), memberScope);
|
||||||
}
|
}
|
||||||
return namespaceType;
|
return namespaceType;
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class NamespaceType implements JetType {
|
public class NamespaceType implements JetType {
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@NotNull
|
||||||
private final JetScope memberScope;
|
private final JetScope memberScope;
|
||||||
|
|
||||||
public NamespaceType(String name, JetScope memberScope) {
|
public NamespaceType(@NotNull String name, @NotNull JetScope memberScope) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.memberScope = memberScope;
|
this.memberScope = memberScope;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
namespace foobar
|
||||||
|
|
||||||
|
namespace a {
|
||||||
|
import java.*
|
||||||
|
|
||||||
|
val a : util.List<Int>? = null
|
||||||
|
val a1 : <error>List</error><Int>? = null
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace a {
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
val b : List<Int>? = a
|
||||||
|
val b1 : <error>util</error>.List<Int>? = a
|
||||||
|
}
|
||||||
|
|
||||||
|
val x1 = a.a
|
||||||
|
|
||||||
|
val y1 = a.b
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
fun done<O>(result : O) : Iteratee<Any?, O>
|
||||||
|
|
||||||
|
class Iteratee<in I, out O> {
|
||||||
|
abstract fun process(item : I) : Iteratee<I, O>
|
||||||
|
abstract val isDone : Boolean
|
||||||
|
abstract val result : O
|
||||||
|
abstract fun done() : O
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sum : Iteratee<Int, Int> {
|
||||||
|
override fun process(item : Int) : Iteratee<Int, Int> {
|
||||||
|
return foobar.done<Int>(item);
|
||||||
|
}
|
||||||
|
override val isDone : Boolean
|
||||||
|
override val result : Int
|
||||||
|
override fun done() : Int
|
||||||
|
}
|
||||||
|
|
||||||
|
class Collection<E> : Iterable<E> {
|
||||||
|
fun iterate<O>(iteratee : Iteratee<E, O>) : O {
|
||||||
|
for (x in this) {
|
||||||
|
val it = iteratee.process(x)
|
||||||
|
if (it.isDone) return it.result
|
||||||
|
iteratee = it
|
||||||
|
}
|
||||||
|
return iteratee.done()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
namespace root
|
||||||
|
|
||||||
|
~a~namespace a {
|
||||||
|
import java.*
|
||||||
|
|
||||||
|
~a.a~val a : util.List<Int>? = null
|
||||||
|
|
||||||
|
val y : Any? = `a.b`b
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace a {
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
~a.b~val b : List<Int>? = null
|
||||||
|
|
||||||
|
val x = `a.a`a
|
||||||
|
}
|
||||||
|
|
||||||
|
val x = `a`a.`a.a`a
|
||||||
|
|
||||||
|
val y = `a`a.`a.b`b
|
||||||
@@ -147,4 +147,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
|
|||||||
doTest("/resolve/ConstructorsAndInitializers.jet", true, true);
|
doTest("/resolve/ConstructorsAndInitializers.jet", true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testNamespaces() throws Exception {
|
||||||
|
doTest("/resolve/Namespaces.jet", true, true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user