Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 23 additions & 36 deletions server/src/compiler_analyzer/analyzer.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
// https://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html

import {
AccessModifier,
funcHeadDestructor,
isFunctionHeadReturnValue,
isMemberMethodInPostOp,
NodeArgList,
NodeAssign,
NodeCase,
NodeCast,
NodeClass,
NodeCondition,
NodeDoWhile,
NodeEnum,
NodeExpr,
NodeExprPostOp,
NodeExprPostOp1,
Expand All @@ -24,31 +20,22 @@ import {
NodeFor,
NodeFunc,
NodeFuncCall,
NodeFuncDef,
NodeIf,
NodeInitList,
NodeInterface,
NodeIntfMethod,
NodeLambda,
NodeLiteral,
NodeMixin,
NodeName,
NodeNamespace,
NodeParamList,
NodeReturn,
NodeScope,
NodeScript,
NodeStatBlock,
NodeStatement,
NodeSwitch,
NodeTry,
NodeType,
NodeTypeDef,
NodeVar,
NodeVarAccess,
NodeVirtualProp,
NodeWhile,
ParsedEnumMember,
ParsedRange
} from "../compiler_parser/nodes";
import {
Expand All @@ -63,29 +50,23 @@ import {diagnostic} from "../code/diagnostic";
import {LocationInfo, NumberLiterals, TokenKind} from "../compiler_tokenizer/tokens";
import {
AnalyzedScope,
copySymbolsInScope,
createAnonymousIdentifier,
createSymbolScope,
createSymbolScopeAndInsert,
findGlobalScope,
findScopeShallowly,
findScopeShallowlyOrInsert,
findScopeWithParentByNodes,
isSymbolConstructorInScope, SymbolScope
} from "./symbolScope";
import {checkFunctionMatch} from "./checkFunction";
import {ParserToken} from "../compiler_parser/parserToken";
import {canTypeConvert, checkTypeMatch, isAllowedToAccessMember} from "./checkType";
import {
getIdentifierInType,
getLocationBetween,
getNextTokenIfExist,
getNodeLocation
} from "../compiler_parser/nodesUtils";
import {
builtinBoolType,
builtinSetterValueToken,
builtinThisToken,
resolvedBuiltinBool,
resolvedBuiltinDouble,
resolvedBuiltinFloat,
Expand All @@ -101,12 +82,10 @@ import {
isResolvedAutoType,
stringifyResolvedType,
stringifyResolvedTypes,
TemplateTranslation,
tryInsertSymbolObject
TemplateTranslation
} from "./symbolUtils";
import {Mutable} from "../utils/utilities";
import {getGlobalSettings} from "../code/settings";
import {createVirtualToken} from "../compiler_tokenizer/tokenUtils";
import assert = require("node:assert");
import {ResolvedType} from "./resolvedType";

Expand Down Expand Up @@ -352,7 +331,7 @@ function analyzeScope(parentScope: SymbolScope, nodeScope: NodeScope): SymbolSco
let found: SymbolScope | undefined = undefined;
for (; ;) {
found = findScopeShallowly(scopeIterator, nextScope.text);
if (found?.ownerNode?.nodeName === NodeName.Func) found = undefined;
if (found?.linkedNode?.nodeName === NodeName.Func) found = undefined;
if (found !== undefined) break;
if (i == 0 && scopeIterator.parentScope !== undefined) {
// If it is not a global scope, search further up the hierarchy.
Expand Down Expand Up @@ -391,36 +370,44 @@ function analyzeStatement(scope: SymbolScope, statement: NodeStatement) {
case NodeName.If:
analyzeIf(scope, statement);
break;
case NodeName.For:
analyzeFor(scope, statement);
case NodeName.For: {
const childScope = createSymbolScopeAndInsert(statement, scope, createAnonymousIdentifier());
analyzeFor(childScope, statement);
break;
case NodeName.While:
analyzeWhile(scope, statement);
}
case NodeName.While: {
const childScope = createSymbolScopeAndInsert(statement, scope, createAnonymousIdentifier());
analyzeWhile(childScope, statement);
break;
}
case NodeName.Return:
analyzeReturn(scope, statement);
break;
case NodeName.StatBlock: {
const childScope = createSymbolScopeAndInsert(undefined, scope, createAnonymousIdentifier());
const childScope = createSymbolScopeAndInsert(statement, scope, createAnonymousIdentifier());
analyzeStatBlock(childScope, statement);
break;
}
case NodeName.Break:
break;
case NodeName.Continue:
break;
case NodeName.DoWhile:
analyzeDoWhile(scope, statement);
case NodeName.DoWhile: {
const childScope = createSymbolScopeAndInsert(statement, scope, createAnonymousIdentifier());
analyzeDoWhile(childScope, statement);
break;
}
case NodeName.Switch:
analyzeSwitch(scope, statement);
break;
case NodeName.ExprStat:
analyzeExprStat(scope, statement);
break;
case NodeName.Try:
analyzeTry(scope, statement);
case NodeName.Try: {
const childScope = createSymbolScopeAndInsert(statement, scope, createAnonymousIdentifier());
analyzeTry(childScope, statement);
break;
}
default:
break;
}
Expand Down Expand Up @@ -498,17 +485,17 @@ function analyzeReturn(scope: SymbolScope, nodeReturn: NodeReturn) {
const returnType = nodeReturn.assign !== undefined ? analyzeAssign(scope, nodeReturn.assign) : undefined;

const functionScope = findScopeWithParentByNodes(scope, [NodeName.Func, NodeName.VirtualProp, NodeName.Lambda]);
if (functionScope === undefined || functionScope.ownerNode === undefined) return;
if (functionScope === undefined || functionScope.linkedNode === undefined) return;

// TODO: Support for lambda

if (functionScope.ownerNode.nodeName === NodeName.Func) {
if (functionScope.linkedNode.nodeName === NodeName.Func) {
let functionReturn = functionScope.parentScope?.symbolMap.get(functionScope.key);
if (functionReturn === undefined || functionReturn instanceof SymbolFunction === false) return;

// Select suitable overload if there are multiple overloads
while (functionReturn.nextOverload !== undefined) {
if (functionReturn.sourceNode === functionScope.ownerNode) break;
if (functionReturn.sourceNode === functionScope.linkedNode) break;
functionReturn = functionReturn.nextOverload;
}

Expand All @@ -519,7 +506,7 @@ function analyzeReturn(scope: SymbolScope, nodeReturn: NodeReturn) {
} else {
checkTypeMatch(returnType, functionReturn.returnType, nodeReturn.nodeRange);
}
} else if (functionScope.ownerNode.nodeName === NodeName.VirtualProp) {
} else if (functionScope.linkedNode.nodeName === NodeName.VirtualProp) {
const key = functionScope.key;
const isGetter = key.startsWith('get_');
if (isGetter === false) {
Expand Down
4 changes: 2 additions & 2 deletions server/src/compiler_analyzer/checkType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ function canConstructImplicitly(

// Search for the constructor of the given type from the scope to which the given type belongs.
const constructorScope = findScopeShallowly(destScope, destIdentifier);
if (constructorScope === undefined || constructorScope.ownerNode?.nodeName !== NodeName.Class) return false;
if (constructorScope === undefined || constructorScope.linkedNode?.nodeName !== NodeName.Class) return false;

// Search for the constructor of the given type from the scope of the type itself.
const constructor = findSymbolShallowly(constructorScope, destIdentifier);
Expand Down Expand Up @@ -221,7 +221,7 @@ export function isAllowedToAccessMember(checkingScope: SymbolScope, declaredSymb
if (declaredSymbol.accessRestriction === AccessModifier.Private) {
return isScopeChildOrGrandchild(checkingScope, declaredScope);
} else if (declaredSymbol.accessRestriction === AccessModifier.Protected) {
if (declaredScope.ownerNode === undefined) return false;
if (declaredScope.linkedNode === undefined) return false;

const checkingOuterScope = findScopeWithParentByNodes(checkingScope, [NodeName.Class, NodeName.Interface]);
if (checkingOuterScope === undefined || checkingOuterScope.parentScope === undefined) return false;
Expand Down
22 changes: 2 additions & 20 deletions server/src/compiler_analyzer/symbolObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,16 @@ import {
NodeEnum,
NodeFunc,
NodeFuncDef,
NodeIf,
NodeInterface,
NodeIntfMethod,
NodeLambda,
NodeName,
NodeVirtualProp
NodeName
} from "../compiler_parser/nodes";
import {ParserToken} from "../compiler_parser/parserToken";
import {ComplementHints} from "./symbolComplement";
import {TemplateTranslation} from "./symbolUtils";
import assert = require("node:assert");
import {Mutable} from "../utils/utilities";
import {ResolvedType} from "./resolvedType";
import {SymbolScope} from "./symbolScope";
import {TokenKind} from "../compiler_tokenizer/tokens";
import {numberTypeSet} from "../compiler_tokenizer/tokenReservedWords";
import assert = require("node:assert");

/**
* The node that serves as the origin of a type declaration.
Expand Down Expand Up @@ -187,18 +181,6 @@ export type SymbolObject = SymbolType | SymbolFunction | SymbolVariable;

// (IF | FOR | WHILE | RETURN | STATBLOCK | BREAK | CONTINUE | DOWHILE | SWITCH | EXPRSTAT | TRY)

/**
* Nodes that can have a scope containing symbols.
*/
export type SymbolOwnerNode =
NodeEnum
| NodeClass
| NodeVirtualProp
| NodeInterface
| NodeFunc
| NodeIf
| NodeLambda;

/**
* Information about a symbol that references a symbol declared elsewhere.
*/
Expand Down
Loading