Skip to content

Commit

Permalink
Work-in-progress #34: Major completion overhaul. Not ready for produc…
Browse files Browse the repository at this point in the history
…tion use, top-level completion has regressed.
  • Loading branch information
EliotVU committed Jan 26, 2023
1 parent 5dfe017 commit a49ea04
Show file tree
Hide file tree
Showing 13 changed files with 934 additions and 218 deletions.
7 changes: 6 additions & 1 deletion grammars/UCParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ options {
} while (token.type !== UCParser.NEWLINE && token.type !== UCParser.EOF)
this._input.seek(i);
}

isNewLine(i = this._input.index): boolean {
const token = this._input.get(i);
return token.type === UCParser.NEWLINE;
}
}

// Class modifier keywords have been commented out, because we are not using them for parsing.
Expand Down Expand Up @@ -997,7 +1002,7 @@ defaultStatement
// -- the UC compiler just skips any character till it hits a newline character.
| SEMICOLON

// | . { this.skipLine(); }
// | ~(BITWISE_OR | SEMICOLON)
;

defaultExpression
Expand Down
6 changes: 6 additions & 0 deletions grammars/examples/Classes/AssignTypeTest.uc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ var name nameVar;
var native int nativeVar;
var transient int transientVar;

var bool boolVar;
var byte byteVar;
var float floatVar;
var int intVar;
var Class objectVar;
Expand Down Expand Up @@ -77,6 +79,7 @@ function int AssignTest() {

// FIXME: Type error
getName(enum'EEnum', enumVar);
boolVar = byteVar;
}

function name getName(Object obj, byte index);
Expand All @@ -85,6 +88,9 @@ defaultproperties
{
enumVar=E_NONE

boolVar=1
boolVar=true

// TODO: Not yet indexed
vectorVar=(x=0)
vectorVar={(
Expand Down
6 changes: 5 additions & 1 deletion server/src/UC/Parser/ErrorStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { DefaultErrorStrategy, Parser, RecognitionException } from 'antlr4ts';
import { DefaultErrorStrategy, Parser, RecognitionException, Token } from 'antlr4ts';

import { UCParser } from '../antlr/generated/UCParser';

export class UCErrorStrategy extends DefaultErrorStrategy {
protected singleTokenDeletion(recognizer: Parser): Token | undefined {
return undefined;
}

reportError(recognizer: Parser, e: RecognitionException) {
if (!recognizer.context) {
return super.reportError(recognizer, e);
Expand Down
3 changes: 3 additions & 0 deletions server/src/UC/Symbols/FieldSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export enum ModifierFlags {

// TODO: Track this modifier for various fields
Deprecated = 1 << 21,

// A private method can however be re-defined!
NonOverridable = Private | Intrinsic,
}

export abstract class UCFieldSymbol extends UCObjectSymbol {
Expand Down
17 changes: 16 additions & 1 deletion server/src/UC/Symbols/MethodSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,22 @@ export class UCMethodSymbol extends UCStructSymbol {
return resolvedType.getCompletionSymbols<C>(document, context, kinds);
}
}
return super.getCompletionSymbols<C>(document, context, kinds);

const symbols: ISymbol[] = [];
for (let child = this.children; child; child = child.next) {
if (typeof kinds !== 'undefined' && ((1 << child.kind) & kinds) === 0) {
continue;
}
if (child.acceptCompletion(document, this)) {
symbols.push(child);
}
}

const outerSymbols = this.outer.getCompletionSymbols<C>(document, context, kinds);
if (outerSymbols) {
return outerSymbols.concat(symbols as C[]);
}
return symbols as C[];
}

override findSuperSymbol<T extends UCFieldSymbol>(id: Name, kind?: UCSymbolKind) {
Expand Down
3 changes: 2 additions & 1 deletion server/src/UC/Symbols/ScriptStructSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ export class UCScriptStructSymbol extends UCStructSymbol {
}

override acceptCompletion(_document: UCDocument, context: UCObjectSymbol): boolean {
return isProperty(context) || isFunction(context);
return true;
// return isProperty(context) || isFunction(context);
}

override index(document: UCDocument, _context: UCStructSymbol) {
Expand Down
52 changes: 43 additions & 9 deletions server/src/UC/Symbols/TypeSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,52 @@ import { intersectsWith, intersectsWithRange } from '../helpers';
import { indexReference } from '../indexer';
import { Name } from '../name';
import {
NAME_ARRAY, NAME_BOOL, NAME_BUTTON, NAME_BYTE, NAME_DELEGATE, NAME_FLOAT, NAME_INT, NAME_MAP,
NAME_NAME, NAME_NONE, NAME_OBJECT, NAME_POINTER, NAME_RANGE, NAME_ROTATOR, NAME_STRING,
NAME_TYPE, NAME_VECTOR
NAME_ARRAY,
NAME_BOOL,
NAME_BUTTON,
NAME_BYTE,
NAME_DELEGATE,
NAME_FLOAT,
NAME_INT,
NAME_MAP,
NAME_NAME,
NAME_NONE,
NAME_OBJECT,
NAME_POINTER,
NAME_RANGE,
NAME_ROTATOR,
NAME_STRING,
NAME_TYPE,
NAME_VECTOR,
} from '../names';
import { IStatement } from '../statements';
import { SymbolWalker } from '../symbolWalker';
import {
DEFAULT_IDENTIFIER, DEFAULT_RANGE, Identifier, IntrinsicArray, ISymbol, IWithIndex,
IWithInnerSymbols, IWithReference, ModifierFlags, ObjectsTable, SymbolReference,
UCArchetypeSymbol, UCBaseOperatorSymbol, UCClassSymbol, UCConstSymbol, UCEnumMemberSymbol,
UCEnumSymbol, UCEventSymbol, UCFieldSymbol, UCMethodSymbol, UCParamSymbol, UCPropertySymbol,
UCScriptStructSymbol, UCStateSymbol, UCStructSymbol
DEFAULT_IDENTIFIER,
DEFAULT_RANGE,
Identifier,
IntrinsicArray,
ISymbol,
IWithIndex,
IWithInnerSymbols,
IWithReference,
ModifierFlags,
ObjectsTable,
SymbolReference,
UCArchetypeSymbol,
UCBaseOperatorSymbol,
UCClassSymbol,
UCConstSymbol,
UCEnumMemberSymbol,
UCEnumSymbol,
UCEventSymbol,
UCFieldSymbol,
UCMethodSymbol,
UCParamSymbol,
UCPropertySymbol,
UCScriptStructSymbol,
UCStateSymbol,
UCStructSymbol,
} from './';
import { ContextInfo, INode } from './ISymbol';
import { UCDelegateSymbol } from './MethodSymbol';
Expand Down Expand Up @@ -717,7 +751,7 @@ export function isMethodSymbol(symbol: ISymbol): symbol is UCMethodSymbol {
return symbol.kind === UCSymbolKind.Function;
}

export function isDelegateSymbol(symbol: ISymbol): symbol is UCMethodSymbol {
export function isDelegateSymbol(symbol: ISymbol): symbol is UCDelegateSymbol {
return symbol.kind === UCSymbolKind.Delegate;
}

Expand Down
54 changes: 54 additions & 0 deletions server/src/UC/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,60 @@ export class UCDocument {
this.scope.addSymbol(symbol);
}

public parse(text: string): DocumentParseData {
console.log('parsing document ' + this.fileName);

const inputStream = UCInputStream.fromString(text);
const lexer = new UCLexer(inputStream);
lexer.removeErrorListeners();
const tokens = new UCTokenStream(lexer);

if (config.generation === UCGeneration.UC3) {
const startPreprocressing = performance.now();
const macroParser = createPreprocessor(this, lexer);
lexer.reset();
if (macroParser) {
try {
const macroTree = preprocessDocument(this, macroParser);
if (macroTree) {
tokens.initMacroTree(macroTree);
}
} catch (err) {
console.error(err);
} finally {
console.info(this.fileName + ': preprocessing time ' + (performance.now() - startPreprocressing));
}
}
}

tokens.fill();

let context: ProgramContext | undefined;
const parser = new UCParser(tokens);
try {
parser.interpreter.setPredictionMode(PredictionMode.SLL);
parser.errorHandler = ERROR_STRATEGY;
parser.removeErrorListeners();
context = parser.program();
} catch (err) {
console.debug('PredictionMode SLL has failed, rolling back to LL.');
try {
parser.reset();
parser.interpreter.setPredictionMode(PredictionMode.LL);
parser.errorHandler = ERROR_STRATEGY;
parser.removeErrorListeners();
context = parser.program();
} catch (err) {
console.error(
`An error was thrown while parsing document: "${this.uri}"`,
err
);
}
}
tokens.release(tokens.mark());
return { context, parser };
}

public build(text: string = this.readText()): DocumentParseData {
console.log('building document ' + this.fileName);

Expand Down
Loading

0 comments on commit a49ea04

Please sign in to comment.