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
|
||||
: modifiers "class" SimpleName
|
||||
typeParameters?
|
||||
"wraps"?
|
||||
("wraps" | modifiers)?
|
||||
valueParameters?
|
||||
(":" attributes delegationSpecifier{","})?
|
||||
(classBody? | enumClassBody)
|
||||
|
||||
@@ -3,10 +3,7 @@ package org.jetbrains.jet.lang;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver;
|
||||
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.resolve.*;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
/**
|
||||
@@ -66,6 +63,6 @@ public class JetSemanticServices {
|
||||
|
||||
@NotNull
|
||||
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
|
||||
* : modifiers "class" SimpleName
|
||||
* typeParameters?
|
||||
* "wraps"?
|
||||
* ("wraps" | modifiers)?
|
||||
* ("(" primaryConstructorParameter{","} ")")?
|
||||
* (":" attributes delegationSpecifier{","})?
|
||||
* (classBody? | enumClassBody)
|
||||
@@ -384,7 +384,13 @@ public class JetParsing extends AbstractJetParsing {
|
||||
expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
|
||||
parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
|
||||
|
||||
consumeIf(WRAPS_KEYWORD);
|
||||
if (at(WRAPS_KEYWORD)) {
|
||||
advance(); // WRAPS_KEYWORD
|
||||
}
|
||||
else {
|
||||
parseModifierList();
|
||||
}
|
||||
|
||||
if (at(LPAR)) {
|
||||
parseValueParameterList(false, TokenSet.EMPTY);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@ public class JetScopeAdapter implements JetScope {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected final JetScope getWorkerScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getThisType() {
|
||||
|
||||
@@ -38,7 +38,7 @@ public class SubstitutingScope implements JetScope {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return new LazySubstitutingClassDescriptor((ClassDescriptor) descriptor, substitutor);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -99,11 +99,12 @@ public class TopDownAnalyzer {
|
||||
Collections.<Attribute>emptyList(), // TODO
|
||||
name
|
||||
);
|
||||
namespaceDescriptor.initialize(semanticServices.createWritableScope(JetScope.EMPTY, namespaceDescriptor));
|
||||
declaringScope.addNamespace(namespaceDescriptor);
|
||||
trace.recordDeclarationResolution(namespace, namespaceDescriptor);
|
||||
}
|
||||
|
||||
WritableScope namespaceScope = semanticServices.createWritableScope(declaringScope, namespaceDescriptor);
|
||||
WritableScope namespaceScope = new WriteThroughScope(declaringScope, (WritableScope) namespaceDescriptor.getMemberScope());
|
||||
namespaceScopes.put(namespace, namespaceScope);
|
||||
|
||||
for (JetImportDirective importDirective : importDirectives) {
|
||||
@@ -264,7 +265,7 @@ public class TopDownAnalyzer {
|
||||
}
|
||||
|
||||
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.Nullable;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class WritableScope extends JetScopeAdapter {
|
||||
@NotNull
|
||||
private final ErrorHandler errorHandler;
|
||||
public interface WritableScope extends JetScope {
|
||||
void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor);
|
||||
|
||||
@NotNull
|
||||
private final DeclarationDescriptor ownerDeclarationDescriptor;
|
||||
void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor);
|
||||
|
||||
// FieldNames include "$"
|
||||
@Nullable
|
||||
private Map<String, PropertyDescriptor> propertyDescriptorsByFieldNames;
|
||||
void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor);
|
||||
|
||||
void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor);
|
||||
|
||||
void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor);
|
||||
|
||||
void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor);
|
||||
|
||||
void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor);
|
||||
|
||||
@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;
|
||||
NamespaceDescriptor getDeclaredNamespace(@NotNull String name);
|
||||
|
||||
@Nullable
|
||||
private List<JetScope> imports;
|
||||
void addPropertyDescriptorByFieldName(@NotNull String fieldName, @NotNull PropertyDescriptor propertyDescriptor);
|
||||
|
||||
public WritableScope(@NotNull JetScope scope, @NotNull DeclarationDescriptor owner, @NotNull ErrorHandler errorHandler) {
|
||||
super(scope);
|
||||
this.ownerDeclarationDescriptor = owner;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
void importScope(@NotNull JetScope imported);
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
void setThisType(@NotNull JetType thisType);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
public static boolean isErrorType(JetType type) {
|
||||
return type instanceof ErrorTypeImpl;
|
||||
}
|
||||
|
||||
public static ClassifierDescriptor getErrorClass() {
|
||||
return ERROR_CLASS;
|
||||
}
|
||||
@@ -153,6 +149,10 @@ public class ErrorUtils {
|
||||
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 final TypeConstructor constructor;
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ErrorHandler;
|
||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.WritableScope;
|
||||
import org.jetbrains.jet.lang.resolve.WritableScopeImpl;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -164,7 +165,7 @@ public class JetStandardClasses {
|
||||
/*package*/ static final JetScope STANDARD_CLASSES;
|
||||
|
||||
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;
|
||||
writableScope.addClassifierAlias("Unit", getTuple(0));
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ public class NamespaceDescriptor extends DeclarationDescriptorImpl {
|
||||
@NotNull
|
||||
public NamespaceType getNamespaceType() {
|
||||
if (namespaceType == null) {
|
||||
assert memberScope != null : "Member scope not set";
|
||||
namespaceType = new NamespaceType(getName(), memberScope);
|
||||
}
|
||||
return namespaceType;
|
||||
|
||||
@@ -13,9 +13,10 @@ import java.util.List;
|
||||
*/
|
||||
public class NamespaceType implements JetType {
|
||||
private final String name;
|
||||
@NotNull
|
||||
private final JetScope memberScope;
|
||||
|
||||
public NamespaceType(String name, JetScope memberScope) {
|
||||
public NamespaceType(@NotNull String name, @NotNull JetScope memberScope) {
|
||||
this.name = name;
|
||||
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);
|
||||
}
|
||||
|
||||
public void testNamespaces() throws Exception {
|
||||
doTest("/resolve/Namespaces.jet", true, true);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user