Slight refactoring.
- Factored out CppLanguage::ParseTypeExpression() into one that could be used in CLanguageFamily, with some hooks to help differentiate what's allowed in C vs C++. Makes the type parsing available for C files as well, and consequently allows typecasting to work for those.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2013, Rene Gollent, [email protected].
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -22,3 +23,13 @@ CLanguage::Name() const
|
|||||||
{
|
{
|
||||||
return "C";
|
return "C";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CLanguage::IsModifierValid(char modifier) const
|
||||||
|
{
|
||||||
|
if (modifier == '*')
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ public:
|
|||||||
virtual ~CLanguage();
|
virtual ~CLanguage();
|
||||||
|
|
||||||
virtual const char* Name() const;
|
virtual const char* Name() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool IsModifierValid(char modifier) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2013, Rene Gollent, [email protected].
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CLanguageFamily.h"
|
#include "CLanguageFamily.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "TeamTypeInformation.h"
|
||||||
|
#include "Type.h"
|
||||||
|
#include "TypeLookupConstraints.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CLanguageFamily::CLanguageFamily()
|
CLanguageFamily::CLanguageFamily()
|
||||||
{
|
{
|
||||||
@@ -22,3 +30,131 @@ CLanguageFamily::GetSyntaxHighlighter() const
|
|||||||
// TODO:...
|
// TODO:...
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CLanguageFamily::ParseTypeExpression(const BString& expression,
|
||||||
|
TeamTypeInformation* info, Type*& _resultType) const
|
||||||
|
{
|
||||||
|
status_t result = B_OK;
|
||||||
|
Type* baseType = NULL;
|
||||||
|
|
||||||
|
BString parsedName = expression;
|
||||||
|
BString baseTypeName;
|
||||||
|
BString arraySpecifier;
|
||||||
|
parsedName.RemoveAll(" ");
|
||||||
|
|
||||||
|
int32 modifierIndex = -1;
|
||||||
|
modifierIndex = parsedName.FindFirst('*');
|
||||||
|
if (modifierIndex == -1)
|
||||||
|
modifierIndex = parsedName.FindFirst('&');
|
||||||
|
if (modifierIndex == -1)
|
||||||
|
modifierIndex = parsedName.FindFirst('[');
|
||||||
|
|
||||||
|
if (modifierIndex >= 0)
|
||||||
|
parsedName.MoveInto(baseTypeName, 0, modifierIndex);
|
||||||
|
else
|
||||||
|
baseTypeName = parsedName;
|
||||||
|
|
||||||
|
modifierIndex = parsedName.FindFirst('[');
|
||||||
|
if (modifierIndex >= 0) {
|
||||||
|
parsedName.MoveInto(arraySpecifier, modifierIndex,
|
||||||
|
parsedName.Length() - modifierIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
|
||||||
|
baseType);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
BReference<Type> typeRef;
|
||||||
|
typeRef.SetTo(baseType, true);
|
||||||
|
|
||||||
|
if (!parsedName.IsEmpty()) {
|
||||||
|
AddressType* derivedType = NULL;
|
||||||
|
// walk the list of modifiers trying to add each.
|
||||||
|
for (int32 i = 0; i < parsedName.Length(); i++) {
|
||||||
|
if (!IsModifierValid(parsedName[i]))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
address_type_kind typeKind;
|
||||||
|
switch (parsedName[i]) {
|
||||||
|
case '*':
|
||||||
|
{
|
||||||
|
typeKind = DERIVED_TYPE_POINTER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '&':
|
||||||
|
{
|
||||||
|
typeKind = DERIVED_TYPE_REFERENCE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (derivedType == NULL) {
|
||||||
|
result = baseType->CreateDerivedAddressType(typeKind,
|
||||||
|
derivedType);
|
||||||
|
} else {
|
||||||
|
result = derivedType->CreateDerivedAddressType(typeKind,
|
||||||
|
derivedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
typeRef.SetTo(derivedType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_resultType = derivedType;
|
||||||
|
} else
|
||||||
|
_resultType = baseType;
|
||||||
|
|
||||||
|
|
||||||
|
if (!arraySpecifier.IsEmpty()) {
|
||||||
|
ArrayType* arrayType = NULL;
|
||||||
|
|
||||||
|
int32 startIndex = 1;
|
||||||
|
do {
|
||||||
|
int32 size = strtoul(arraySpecifier.String() + startIndex,
|
||||||
|
NULL, 10);
|
||||||
|
if (size < 0)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (arrayType == NULL) {
|
||||||
|
result = _resultType->CreateDerivedArrayType(0, size, true,
|
||||||
|
arrayType);
|
||||||
|
} else {
|
||||||
|
result = arrayType->CreateDerivedArrayType(0, size, true,
|
||||||
|
arrayType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
typeRef.SetTo(arrayType, true);
|
||||||
|
|
||||||
|
startIndex = arraySpecifier.FindFirst('[', startIndex + 1);
|
||||||
|
|
||||||
|
} while (startIndex >= 0);
|
||||||
|
|
||||||
|
// since a C/C++ array is essentially pointer math,
|
||||||
|
// the resulting array has to be wrapped in a pointer to
|
||||||
|
// ensure the element addresses wind up being against the
|
||||||
|
// correct address.
|
||||||
|
AddressType* addressType = NULL;
|
||||||
|
result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER,
|
||||||
|
addressType);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
_resultType = addressType;
|
||||||
|
}
|
||||||
|
|
||||||
|
typeRef.Detach();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ public:
|
|||||||
virtual ~CLanguageFamily();
|
virtual ~CLanguageFamily();
|
||||||
|
|
||||||
virtual SyntaxHighlighter* GetSyntaxHighlighter() const;
|
virtual SyntaxHighlighter* GetSyntaxHighlighter() const;
|
||||||
|
|
||||||
|
virtual status_t ParseTypeExpression(const BString& expression,
|
||||||
|
TeamTypeInformation* lookup,
|
||||||
|
Type*& _resultType) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool IsModifierValid(char modifier) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,6 @@
|
|||||||
|
|
||||||
#include "CppLanguage.h"
|
#include "CppLanguage.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "TeamTypeInformation.h"
|
|
||||||
#include "Type.h"
|
|
||||||
#include "TypeLookupConstraints.h"
|
|
||||||
|
|
||||||
|
|
||||||
CppLanguage::CppLanguage()
|
CppLanguage::CppLanguage()
|
||||||
{
|
{
|
||||||
@@ -31,127 +25,11 @@ CppLanguage::Name() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
bool
|
||||||
CppLanguage::ParseTypeExpression(const BString &expression,
|
CppLanguage::IsModifierValid(char modifier) const
|
||||||
TeamTypeInformation* info,
|
|
||||||
Type*& _resultType) const
|
|
||||||
{
|
{
|
||||||
status_t result = B_OK;
|
if (modifier == '*' || modifier == '&')
|
||||||
Type* baseType = NULL;
|
return true;
|
||||||
|
|
||||||
BString parsedName = expression;
|
return false;
|
||||||
BString baseTypeName;
|
|
||||||
BString arraySpecifier;
|
|
||||||
parsedName.RemoveAll(" ");
|
|
||||||
|
|
||||||
int32 modifierIndex = -1;
|
|
||||||
modifierIndex = parsedName.FindFirst('*');
|
|
||||||
if (modifierIndex == -1)
|
|
||||||
modifierIndex = parsedName.FindFirst('&');
|
|
||||||
if (modifierIndex == -1)
|
|
||||||
modifierIndex = parsedName.FindFirst('[');
|
|
||||||
|
|
||||||
if (modifierIndex >= 0)
|
|
||||||
parsedName.MoveInto(baseTypeName, 0, modifierIndex);
|
|
||||||
else
|
|
||||||
baseTypeName = parsedName;
|
|
||||||
|
|
||||||
modifierIndex = parsedName.FindFirst('[');
|
|
||||||
if (modifierIndex >= 0) {
|
|
||||||
parsedName.MoveInto(arraySpecifier, modifierIndex,
|
|
||||||
parsedName.Length() - modifierIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
|
|
||||||
baseType);
|
|
||||||
if (result != B_OK)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
BReference<Type> typeRef;
|
|
||||||
typeRef.SetTo(baseType, true);
|
|
||||||
|
|
||||||
if (!parsedName.IsEmpty()) {
|
|
||||||
AddressType* derivedType = NULL;
|
|
||||||
// walk the list of modifiers trying to add each.
|
|
||||||
for (int32 i = 0; i < parsedName.Length(); i++) {
|
|
||||||
address_type_kind typeKind;
|
|
||||||
switch (parsedName[i]) {
|
|
||||||
case '*':
|
|
||||||
{
|
|
||||||
typeKind = DERIVED_TYPE_POINTER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '&':
|
|
||||||
{
|
|
||||||
typeKind = DERIVED_TYPE_REFERENCE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (derivedType == NULL) {
|
|
||||||
result = baseType->CreateDerivedAddressType(typeKind,
|
|
||||||
derivedType);
|
|
||||||
} else {
|
|
||||||
result = derivedType->CreateDerivedAddressType(typeKind,
|
|
||||||
derivedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != B_OK)
|
|
||||||
return result;
|
|
||||||
typeRef.SetTo(derivedType, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
_resultType = derivedType;
|
|
||||||
} else
|
|
||||||
_resultType = baseType;
|
|
||||||
|
|
||||||
|
|
||||||
if (!arraySpecifier.IsEmpty()) {
|
|
||||||
ArrayType* arrayType = NULL;
|
|
||||||
|
|
||||||
int32 startIndex = 1;
|
|
||||||
do {
|
|
||||||
int32 size = strtoul(arraySpecifier.String() + startIndex,
|
|
||||||
NULL, 10);
|
|
||||||
if (size < 0)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
if (arrayType == NULL) {
|
|
||||||
result = _resultType->CreateDerivedArrayType(0, size, true,
|
|
||||||
arrayType);
|
|
||||||
} else {
|
|
||||||
result = arrayType->CreateDerivedArrayType(0, size, true,
|
|
||||||
arrayType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != B_OK)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
typeRef.SetTo(arrayType, true);
|
|
||||||
|
|
||||||
startIndex = arraySpecifier.FindFirst('[', startIndex + 1);
|
|
||||||
|
|
||||||
} while (startIndex >= 0);
|
|
||||||
|
|
||||||
// since a C/C++ array is essentially pointer math,
|
|
||||||
// the resulting array has to be wrapped in a pointer to
|
|
||||||
// ensure the element addresses wind up being against the
|
|
||||||
// correct address.
|
|
||||||
AddressType* addressType = NULL;
|
|
||||||
result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER,
|
|
||||||
addressType);
|
|
||||||
if (result != B_OK)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
_resultType = addressType;
|
|
||||||
}
|
|
||||||
|
|
||||||
typeRef.Detach();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ public:
|
|||||||
|
|
||||||
virtual const char* Name() const;
|
virtual const char* Name() const;
|
||||||
|
|
||||||
virtual status_t ParseTypeExpression(const BString &expression,
|
protected:
|
||||||
TeamTypeInformation* lookup,
|
virtual bool IsModifierValid(char modifier) const;
|
||||||
Type*& _resultType) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user