forked from qt-creator/qt-creator
Added symbols for property declarations.
This commit is contained in:
@@ -2391,6 +2391,9 @@ public:
|
||||
unsigned rparen_token;
|
||||
DeclarationAST *simple_declaration;
|
||||
|
||||
public: // annotations
|
||||
List<ObjCPropertyDeclaration *> *symbols;
|
||||
|
||||
public:
|
||||
virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return this; }
|
||||
|
||||
|
@@ -130,6 +130,7 @@ class ObjCForwardClassDeclaration;
|
||||
class ObjCProtocol;
|
||||
class ObjCForwardProtocolDeclaration;
|
||||
class ObjCMethod;
|
||||
class ObjCPropertyDeclaration;
|
||||
|
||||
} // end of namespace CPlusPlus
|
||||
|
||||
|
@@ -682,21 +682,6 @@ bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
enum PropertyAttributes {
|
||||
None = 0,
|
||||
Assign = 1 << 0,
|
||||
Retain = 1 << 1,
|
||||
Copy = 1 << 2,
|
||||
ReadOnly = 1 << 3,
|
||||
ReadWrite = 1 << 4,
|
||||
Getter = 1 << 5,
|
||||
Setter = 1 << 6,
|
||||
NonAtomic = 1 << 7,
|
||||
|
||||
WritabilityMask = ReadOnly | ReadWrite,
|
||||
SetterSemanticsMask = Assign | Retain | Copy,
|
||||
};
|
||||
|
||||
bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
|
||||
int &flags,
|
||||
int attr)
|
||||
@@ -714,7 +699,17 @@ bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
|
||||
|
||||
bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast)
|
||||
{
|
||||
int propAttrs = None;
|
||||
semantic()->check(ast->simple_declaration, _scope);
|
||||
SimpleDeclarationAST *simpleDecl = ast->simple_declaration->asSimpleDeclaration();
|
||||
|
||||
if (!simpleDecl) {
|
||||
translationUnit()->warning(ast->simple_declaration->firstToken(),
|
||||
"invalid type for property declaration");
|
||||
return false;
|
||||
}
|
||||
|
||||
int propAttrs = ObjCPropertyDeclaration::None;
|
||||
Name *getterName = 0, *setterName = 0;
|
||||
|
||||
for (ObjCPropertyAttributeListAST *iter= ast->property_attribute_list; iter; iter = iter->next) {
|
||||
ObjCPropertyAttributeAST *attrAst = iter->value;
|
||||
@@ -723,45 +718,57 @@ bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast)
|
||||
|
||||
Identifier *attrId = identifier(attrAst->attribute_identifier_token);
|
||||
if (attrId == control()->objcGetterId()) {
|
||||
if (checkPropertyAttribute(attrAst, propAttrs, Getter)) {
|
||||
// TODO: find method declaration for getter
|
||||
if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Getter)) {
|
||||
getterName = semantic()->check(attrAst->method_selector, _scope);
|
||||
}
|
||||
} else if (attrId == control()->objcSetterId()) {
|
||||
if (checkPropertyAttribute(attrAst, propAttrs, Setter)) {
|
||||
// TODO: find method declaration for setter
|
||||
if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Setter)) {
|
||||
setterName = semantic()->check(attrAst->method_selector, _scope);
|
||||
}
|
||||
} else if (attrId == control()->objcReadwriteId()) {
|
||||
checkPropertyAttribute(attrAst, propAttrs, ReadWrite);
|
||||
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadWrite);
|
||||
} else if (attrId == control()->objcReadonlyId()) {
|
||||
checkPropertyAttribute(attrAst, propAttrs, ReadOnly);
|
||||
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadOnly);
|
||||
} else if (attrId == control()->objcAssignId()) {
|
||||
checkPropertyAttribute(attrAst, propAttrs, Assign);
|
||||
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Assign);
|
||||
} else if (attrId == control()->objcRetainId()) {
|
||||
checkPropertyAttribute(attrAst, propAttrs, Retain);
|
||||
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Retain);
|
||||
} else if (attrId == control()->objcCopyId()) {
|
||||
checkPropertyAttribute(attrAst, propAttrs, Copy);
|
||||
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Copy);
|
||||
} else if (attrId == control()->objcNonatomicId()) {
|
||||
checkPropertyAttribute(attrAst, propAttrs, NonAtomic);
|
||||
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::NonAtomic);
|
||||
}
|
||||
}
|
||||
|
||||
if (propAttrs & ReadOnly && propAttrs & ReadWrite)
|
||||
if (propAttrs & ObjCPropertyDeclaration::ReadOnly &&
|
||||
propAttrs & ObjCPropertyDeclaration::ReadWrite)
|
||||
// Should this be an error instead of only a warning?
|
||||
translationUnit()->warning(ast->property_token,
|
||||
"property can have at most one attribute \"readonly\" or \"readwrite\" specified");
|
||||
int setterSemAttrs = propAttrs & SetterSemanticsMask;
|
||||
int setterSemAttrs = propAttrs & ObjCPropertyDeclaration::SetterSemanticsMask;
|
||||
if (setterSemAttrs
|
||||
&& setterSemAttrs != Assign
|
||||
&& setterSemAttrs != Retain
|
||||
&& setterSemAttrs != Copy) {
|
||||
&& setterSemAttrs != ObjCPropertyDeclaration::Assign
|
||||
&& setterSemAttrs != ObjCPropertyDeclaration::Retain
|
||||
&& setterSemAttrs != ObjCPropertyDeclaration::Copy) {
|
||||
// Should this be an error instead of only a warning?
|
||||
translationUnit()->warning(ast->property_token,
|
||||
"property can have at most one attribute \"assign\", \"retain\", or \"copy\" specified");
|
||||
}
|
||||
|
||||
// TODO: Check if the next line is correct (EV)
|
||||
semantic()->check(ast->simple_declaration, _scope);
|
||||
List<ObjCPropertyDeclaration *> **lastSymbols = &ast->symbols;
|
||||
for (List<Declaration*> *iter = simpleDecl->symbols; iter; iter = iter->next) {
|
||||
ObjCPropertyDeclaration *propDecl = control()->newObjCPropertyDeclaration(ast->firstToken(),
|
||||
iter->value->name());
|
||||
propDecl->setType(iter->value->type());
|
||||
propDecl->setAttributes(propAttrs);
|
||||
propDecl->setGetterName(getterName);
|
||||
propDecl->setSetterName(setterName);
|
||||
_scope->enterSymbol(propDecl);
|
||||
|
||||
*lastSymbols = new (translationUnit()->memoryPool()) List<ObjCPropertyDeclaration *>();
|
||||
(*lastSymbols)->value = propDecl;
|
||||
lastSymbols = &(*lastSymbols)->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -129,6 +129,7 @@ public:
|
||||
delete_array_entries(objcForwardClassDeclarations);
|
||||
delete_array_entries(objcForwardProtocolDeclarations);
|
||||
delete_array_entries(objcMethods);
|
||||
delete_array_entries(objcPropertyDeclarations);
|
||||
}
|
||||
|
||||
NameId *findOrInsertNameId(Identifier *id)
|
||||
@@ -393,6 +394,13 @@ public:
|
||||
return method;
|
||||
}
|
||||
|
||||
ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, Name *name)
|
||||
{
|
||||
ObjCPropertyDeclaration *decl = new ObjCPropertyDeclaration(translationUnit, sourceLocation, name);
|
||||
objcPropertyDeclarations.push_back(decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
Enum *newEnum(unsigned sourceLocation, Name *name)
|
||||
{
|
||||
Enum *e = new Enum(translationUnit,
|
||||
@@ -577,6 +585,7 @@ public:
|
||||
std::vector<ObjCForwardClassDeclaration *> objcForwardClassDeclarations;
|
||||
std::vector<ObjCForwardProtocolDeclaration *> objcForwardProtocolDeclarations;
|
||||
std::vector<ObjCMethod *> objcMethods;
|
||||
std::vector<ObjCPropertyDeclaration *> objcPropertyDeclarations;
|
||||
|
||||
// ObjC context keywords:
|
||||
Identifier *objcGetterId;
|
||||
@@ -787,6 +796,9 @@ ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(unsig
|
||||
ObjCMethod *Control::newObjCMethod(unsigned sourceLocation, Name *name)
|
||||
{ return d->newObjCMethod(sourceLocation, name); }
|
||||
|
||||
ObjCPropertyDeclaration *Control::newObjCPropertyDeclaration(unsigned sourceLocation, Name *name)
|
||||
{ return d->newObjCPropertyDeclaration(sourceLocation, name); }
|
||||
|
||||
Identifier *Control::objcGetterId() const
|
||||
{ return d->objcGetterId; }
|
||||
|
||||
|
@@ -169,6 +169,9 @@ public:
|
||||
/// Creates a new Objective-C method symbol.
|
||||
ObjCMethod *newObjCMethod(unsigned sourceLocation, Name *name = 0);
|
||||
|
||||
/// Creates a new Objective-C @property declaration symbol.
|
||||
ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, Name *name);
|
||||
|
||||
// Objective-C specific context keywords.
|
||||
Identifier *objcGetterId() const;
|
||||
Identifier *objcSetterId() const;
|
||||
|
@@ -488,4 +488,5 @@ bool Symbol::isObjCForwardProtocolDeclaration() const
|
||||
bool Symbol::isObjCMethod() const
|
||||
{ return asObjCMethod() != 0; }
|
||||
|
||||
|
||||
bool Symbol::isObjCPropertyDeclaration() const
|
||||
{ return asObjCPropertyDeclaration() != 0; }
|
||||
|
@@ -228,6 +228,9 @@ public:
|
||||
/// Returns true if this Symbol is an Objective-C method declaration.
|
||||
bool isObjCMethod() const;
|
||||
|
||||
/// Returns true if this Symbol is an Objective-C @property declaration.
|
||||
bool isObjCPropertyDeclaration() const;
|
||||
|
||||
virtual const ScopedSymbol *asScopedSymbol() const { return 0; }
|
||||
virtual const Enum *asEnum() const { return 0; }
|
||||
virtual const Function *asFunction() const { return 0; }
|
||||
@@ -247,6 +250,7 @@ public:
|
||||
virtual const ObjCProtocol *asObjCProtocol() const { return 0; }
|
||||
virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return 0; }
|
||||
virtual const ObjCMethod *asObjCMethod() const { return 0; }
|
||||
virtual const ObjCPropertyDeclaration *asObjCPropertyDeclaration() const { return 0; }
|
||||
|
||||
virtual ScopedSymbol *asScopedSymbol() { return 0; }
|
||||
virtual Enum *asEnum() { return 0; }
|
||||
@@ -267,6 +271,7 @@ public:
|
||||
virtual ObjCProtocol *asObjCProtocol() { return 0; }
|
||||
virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return 0; }
|
||||
virtual ObjCMethod *asObjCMethod() { return 0; }
|
||||
virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration() { return 0; }
|
||||
|
||||
/// Returns this Symbol's type.
|
||||
virtual FullySpecifiedType type() const = 0;
|
||||
|
@@ -88,6 +88,7 @@ public:
|
||||
virtual bool visit(ObjCProtocol *) { return true; }
|
||||
virtual bool visit(ObjCForwardProtocolDeclaration *) { return true; }
|
||||
virtual bool visit(ObjCMethod *) { return true; }
|
||||
virtual bool visit(ObjCPropertyDeclaration *) { return true; }
|
||||
};
|
||||
|
||||
} // end of namespace CPlusPlus
|
||||
|
@@ -820,4 +820,23 @@ void ObjCMethod::visitSymbol0(SymbolVisitor *visitor)
|
||||
}
|
||||
}
|
||||
|
||||
ObjCPropertyDeclaration::ObjCPropertyDeclaration(TranslationUnit *translationUnit,
|
||||
unsigned sourceLocation,
|
||||
Name *name):
|
||||
Symbol(translationUnit, sourceLocation, name),
|
||||
_propertyAttributes(None),
|
||||
_getterName(0),
|
||||
_setterName(0)
|
||||
{}
|
||||
|
||||
ObjCPropertyDeclaration::~ObjCPropertyDeclaration()
|
||||
{}
|
||||
|
||||
FullySpecifiedType ObjCPropertyDeclaration::type() const
|
||||
{ return _type; }
|
||||
|
||||
void ObjCPropertyDeclaration::visitSymbol0(SymbolVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
}
|
||||
|
@@ -729,6 +729,75 @@ private:
|
||||
Scope *_arguments;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT ObjCPropertyDeclaration: public Symbol
|
||||
{
|
||||
public:
|
||||
enum PropertyAttributes {
|
||||
None = 0,
|
||||
Assign = 1 << 0,
|
||||
Retain = 1 << 1,
|
||||
Copy = 1 << 2,
|
||||
ReadOnly = 1 << 3,
|
||||
ReadWrite = 1 << 4,
|
||||
Getter = 1 << 5,
|
||||
Setter = 1 << 6,
|
||||
NonAtomic = 1 << 7,
|
||||
|
||||
WritabilityMask = ReadOnly | ReadWrite,
|
||||
SetterSemanticsMask = Assign | Retain | Copy,
|
||||
};
|
||||
|
||||
public:
|
||||
ObjCPropertyDeclaration(TranslationUnit *translationUnit,
|
||||
unsigned sourceLocation,
|
||||
Name *name);
|
||||
virtual ~ObjCPropertyDeclaration();
|
||||
|
||||
bool hasAttribute(int attribute) const
|
||||
{ return _propertyAttributes & attribute; }
|
||||
|
||||
void setAttributes(int attributes)
|
||||
{ _propertyAttributes = attributes; }
|
||||
|
||||
bool hasGetter() const
|
||||
{ return hasAttribute(Getter); }
|
||||
|
||||
bool hasSetter() const
|
||||
{ return hasAttribute(Setter); }
|
||||
|
||||
Name *getterName() const
|
||||
{ return _getterName; }
|
||||
|
||||
void setGetterName(Name *getterName)
|
||||
{ _getterName = getterName; }
|
||||
|
||||
Name *setterName() const
|
||||
{ return _setterName; }
|
||||
|
||||
void setSetterName(Name *setterName)
|
||||
{ _setterName = setterName; }
|
||||
|
||||
void setType(const FullySpecifiedType &type)
|
||||
{ _type = type; }
|
||||
|
||||
// Symbol's interface
|
||||
virtual FullySpecifiedType type() const;
|
||||
|
||||
virtual const ObjCPropertyDeclaration *asOObjCPropertyDeclaration() const
|
||||
{ return this; }
|
||||
|
||||
virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration()
|
||||
{ return this; }
|
||||
|
||||
protected:
|
||||
virtual void visitSymbol0(SymbolVisitor *visitor);
|
||||
|
||||
private:
|
||||
FullySpecifiedType _type;
|
||||
int _propertyAttributes;
|
||||
Name *_getterName, *_setterName;
|
||||
};
|
||||
|
||||
} // end of namespace CPlusPlus
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user