Changeset View
Changeset View
Standalone View
Standalone View
duchain/builders/declarationbuilder.cpp
Context not available. | |||||
250 | } | 250 | } | ||
---|---|---|---|---|---|
251 | } | 251 | } | ||
252 | 252 | | |||
253 | /** | ||||
254 | * Write lock need to be taken before calling this method | ||||
255 | */ | ||||
256 | void DeclarationBuilder::visitMethodDeclarationInjectContext(go::MethodDeclarationAst* node, QualifiedIdentifier const& typeIdentifier) { | ||||
257 | auto typeDeclaration = go::getTypeDeclaration(typeIdentifier, currentContext()); | ||||
258 | auto toBeInjectedContext = typeDeclaration ? typeDeclaration->internalContext() : nullptr; | ||||
259 | if(!typeDeclaration || !typeDeclaration->internalContext()) | ||||
260 | { | ||||
261 | openContext(node->methodName, node->methodName, DUContext::ContextType::Class, typeIdentifier); | ||||
262 | if(typeDeclaration) | ||||
263 | { | ||||
264 | typeDeclaration->setInternalContext(currentContext()); | ||||
265 | } | ||||
266 | toBeInjectedContext = currentContext(); | ||||
267 | closeContext(); | ||||
268 | } | ||||
269 | | ||||
270 | injectContext(toBeInjectedContext); | ||||
271 | } | ||||
272 | | ||||
253 | void DeclarationBuilder::visitMethodDeclaration(go::MethodDeclarationAst* node) | 273 | void DeclarationBuilder::visitMethodDeclaration(go::MethodDeclarationAst* node) | ||
254 | { | 274 | { | ||
275 | auto typeIdentifier = identifierForNode(go::getMethodRecvTypeIdentifier(node->methodRecv)); | ||||
255 | 276 | | |||
256 | go::GoFunctionDeclaration* functionDeclaration = nullptr; | 277 | DUChainWriteLocker writeLock; | ||
257 | QualifiedIdentifier typeIdentifier; | 278 | visitMethodDeclarationInjectContext(node, typeIdentifier); | ||
258 | auto containerType = go::getMethodRecvTypeIdentifier(node->methodRecv); | | |||
259 | 279 | | |||
260 | { | 280 | auto range = RangeInRevision(currentContext()->range().start, currentContext()->range().start); | ||
261 | DUChainWriteLocker lock; | 281 | auto functionDeclaration = openDeclaration<go::GoFunctionDeclaration>(identifierForNode(node->methodName).last(), range); | ||
262 | typeIdentifier = identifierForNode(containerType); | 282 | functionDeclaration->setAutoDeclaration(true); | ||
263 | auto typeDeclaration = go::getTypeDeclaration(typeIdentifier, currentContext()); | 283 | closeDeclaration(); | ||
264 | auto toBeInjectedContext = typeDeclaration ? typeDeclaration->internalContext() : nullptr; | | |||
265 | if(!typeDeclaration || !typeDeclaration->internalContext()) | | |||
266 | { | | |||
267 | openContext(node->methodName, node->methodName, DUContext::ContextType::Class, typeIdentifier); | | |||
268 | if(typeDeclaration) | | |||
269 | { | | |||
270 | typeDeclaration->setInternalContext(currentContext()); | | |||
271 | } | | |||
272 | toBeInjectedContext = currentContext(); | | |||
273 | closeContext(); | | |||
274 | } | | |||
275 | 284 | | |||
276 | injectContext(toBeInjectedContext); | 285 | closeInjectedContext(); | ||
286 | writeLock.unlock(); | ||||
277 | 287 | | |||
278 | auto range = RangeInRevision(currentContext()->range().start, currentContext()->range().start); | 288 | DUChainReadLocker readLock; | ||
279 | functionDeclaration = openDeclaration<go::GoFunctionDeclaration>(identifierForNode(node->methodName).last(), range); | 289 | auto identifier = functionDeclaration->qualifiedIdentifier(); | ||
280 | functionDeclaration->setAutoDeclaration(true); | 290 | readLock.unlock(); | ||
281 | closeDeclaration(); | | |||
282 | 291 | | |||
283 | closeInjectedContext(); | 292 | openContext(node, editorFindRange(node, 0), DUContext::ContextType::Class, typeIdentifier); | ||
284 | } | 293 | writeLock.lock(); | ||
285 | 294 | | |||
286 | QualifiedIdentifier identifier; | | |||
287 | { | | |||
288 | DUChainReadLocker lock; | | |||
289 | identifier = functionDeclaration->qualifiedIdentifier(); | | |||
290 | } | | |||
291 | 295 | | |||
292 | openContext(node, editorFindRange(node, 0), DUContext::ContextType::Class, typeIdentifier); | | |||
293 | DUChainWriteLocker lock; | | |||
294 | auto functionDefinition = buildMethod(node->signature, node->body, node->methodName, functionDeclaration, m_session->commentBeforeToken(node->startToken-1), identifier); | 296 | auto functionDefinition = buildMethod(node->signature, node->body, node->methodName, functionDeclaration, m_session->commentBeforeToken(node->startToken-1), identifier); | ||
295 | functionDeclaration->setType<go::GoFunctionType>(functionDefinition->type<go::GoFunctionType>()); | 297 | functionDeclaration->setType<go::GoFunctionType>(functionDefinition->type<go::GoFunctionType>()); | ||
296 | functionDeclaration->setKind(Declaration::Instance); | 298 | functionDeclaration->setKind(Declaration::Instance); | ||
297 | lock.unlock(); | 299 | auto internalCtx = functionDefinition->internalContext(); | ||
298 | 300 | if(node->methodRecv->type && internalCtx) | |||
299 | if(node->methodRecv->type && functionDefinition->internalContext()) | | |||
300 | { | 301 | { | ||
301 | //declare method receiver variable('this' or 'self' analog in Go) | 302 | //declare method receiver variable('this' or 'self' analog in Go) | ||
302 | openContext(functionDefinition->internalContext()); | 303 | openContext(internalCtx); | ||
303 | buildTypeName(node->methodRecv->type); | 304 | buildTypeName(node->methodRecv->type); | ||
304 | if(node->methodRecv->star!= -1) | 305 | if(node->methodRecv->star!= -1) | ||
305 | { | 306 | { | ||
Context not available. | |||||
307 | ptype->setBaseType(lastType()); | 308 | ptype->setBaseType(lastType()); | ||
308 | injectType(PointerType::Ptr(ptype)); | 309 | injectType(PointerType::Ptr(ptype)); | ||
309 | } | 310 | } | ||
310 | DUChainWriteLocker n; | | |||
311 | functionDefinition->setDeclaration(functionDeclaration); | 311 | functionDefinition->setDeclaration(functionDeclaration); | ||
312 | auto methodReceiverName = node->methodRecv->nameOrType; | 312 | auto methodReceiverName = node->methodRecv->nameOrType; | ||
313 | Declaration* thisVariable = openDeclaration<Declaration>(identifierForNode(methodReceiverName).last(), | 313 | Declaration* thisVariable = openDeclaration<Declaration>(identifierForNode(methodReceiverName).last(), | ||
Context not available. | |||||
317 | closeContext(); | 317 | closeContext(); | ||
318 | } | 318 | } | ||
319 | closeContext(); | 319 | closeContext(); | ||
320 | writeLock.unlock(); | ||||
320 | } | 321 | } | ||
321 | 322 | | |||
322 | void DeclarationBuilder::visitTypeSpec(go::TypeSpecAst* node) | 323 | void DeclarationBuilder::visitTypeSpec(go::TypeSpecAst* node) | ||
Context not available. |